From 16a573e1c402fab34442b5aad78434d601c24b26 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Thu, 16 May 2024 16:51:57 -0600 Subject: [PATCH 01/22] expose regression params in opt --- Libs/Optimize/OptimizeParameters.cpp | 16 ++++++++++++++++ Libs/Optimize/OptimizeParameters.h | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/Libs/Optimize/OptimizeParameters.cpp b/Libs/Optimize/OptimizeParameters.cpp index d7f87860027..b45a97f4c66 100644 --- a/Libs/Optimize/OptimizeParameters.cpp +++ b/Libs/Optimize/OptimizeParameters.cpp @@ -45,6 +45,8 @@ const std::string checkpointing_interval = "checkpointing_interval"; const std::string save_init_splits = "save_init_splits"; const std::string keep_checkpoints = "keep_checkpoints"; const std::string use_disentangled_ssm = "use_disentangled_ssm"; +const std::string use_linear_regression = "use_linear_regression"; +const std::string use_mixed_effects_model = "use_mixed_effects_model"; const std::string field_attributes = "field_attributes"; const std::string field_attribute_weights = "field_attribute_weights"; const std::string use_geodesics_to_landmarks = "use_geodesics_to_landmarks"; @@ -93,6 +95,8 @@ OptimizeParameters::OptimizeParameters(ProjectHandle project) { Keys::geodesics_to_landmarks_weight, Keys::keep_checkpoints, Keys::use_disentangled_ssm, + Keys::use_linear_regression, + Keys::use_mixed_effects_model, Keys::particle_format, Keys::geodesic_remesh_percent, Keys::shared_boundary, @@ -201,6 +205,18 @@ bool OptimizeParameters::get_use_disentangled_ssm() { return params_.get(Keys::u //--------------------------------------------------------------------------- void OptimizeParameters::set_use_disentangled_ssm(bool value) { params_.set(Keys::use_disentangled_ssm, value); } +//--------------------------------------------------------------------------- +bool OptimizeParameters::get_use_linear_regression() { return params_.get(Keys::use_linear_regression, false); } + +//--------------------------------------------------------------------------- +void OptimizeParameters::set_use_linear_regression(bool value) { params_.set(Keys::use_linear_regression, value); } + +//--------------------------------------------------------------------------- +bool OptimizeParameters::get_use_mixed_effects_model() { return params_.get(Keys::use_mixed_effects_model, false); } + +//--------------------------------------------------------------------------- +void OptimizeParameters::set_use_mixed_effects_model(bool value) { params_.set(Keys::use_mixed_effects_model, value); } + //--------------------------------------------------------------------------- bool OptimizeParameters::get_use_procrustes_scaling() { return params_.get(Keys::procrustes_scaling, false); } diff --git a/Libs/Optimize/OptimizeParameters.h b/Libs/Optimize/OptimizeParameters.h index 6e37f063b75..fb28b3abd0f 100644 --- a/Libs/Optimize/OptimizeParameters.h +++ b/Libs/Optimize/OptimizeParameters.h @@ -60,6 +60,12 @@ class OptimizeParameters { bool get_use_disentangled_ssm(); void set_use_disentangled_ssm(bool value); + bool get_use_linear_regression(); + void set_use_linear_regression(bool value); + + bool get_use_mixed_effects_model(); + void set_use_mixed_effects_model(bool value); + bool get_use_procrustes(); void set_use_procrustes(bool value); From d452bfcb340fb6f3cc751674b9c8dd1988a77079 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Thu, 16 May 2024 18:41:53 -0600 Subject: [PATCH 02/22] support explanatory variable in SW project --- Libs/Project/ProjectReader.cpp | 5 +++++ Libs/Project/Subject.cpp | 6 ++++++ Libs/Project/Subject.h | 6 ++++++ 3 files changed, 17 insertions(+) diff --git a/Libs/Project/ProjectReader.cpp b/Libs/Project/ProjectReader.cpp index d7b4142cd84..936bf3fb1c2 100644 --- a/Libs/Project/ProjectReader.cpp +++ b/Libs/Project/ProjectReader.cpp @@ -68,6 +68,11 @@ void ProjectReader::load_subjects(StringMapList list) { if (contains(item, "excluded")) { subject->set_excluded(Variant(item["excluded"])); } + + if (contains(item, "explanatory_variable")) { + subject->set_explanatory_variable(Variant(item["explanatory_variable"])); + } + if (name.empty()) { if (!subject->get_original_filenames().empty()) { name = StringUtils::getBaseFilenameWithoutExtension(subject->get_original_filenames()[0]); diff --git a/Libs/Project/Subject.cpp b/Libs/Project/Subject.cpp index 43b1bda2049..57c1eb5d50f 100644 --- a/Libs/Project/Subject.cpp +++ b/Libs/Project/Subject.cpp @@ -100,6 +100,12 @@ void Subject::set_fixed(bool fixed) { fixed_ = fixed; } //--------------------------------------------------------------------------- bool Subject::is_excluded() { return excluded_; } +//--------------------------------------------------------------------------- +void Subject::set_explanatory_variable(double val) { explanatory_variable_ = val; } + +//--------------------------------------------------------------------------- +double Subject::get_explanatory_variable() { return explanatory_variable_; } + //--------------------------------------------------------------------------- void Subject::set_excluded(bool excluded) { excluded_ = excluded; } diff --git a/Libs/Project/Subject.h b/Libs/Project/Subject.h index 3b3f176634a..16c32973656 100644 --- a/Libs/Project/Subject.h +++ b/Libs/Project/Subject.h @@ -107,6 +107,11 @@ class Subject { //! Set if this subject is excluded or not void set_excluded(bool excluded); + //! Get the explanatory variable defined for the subject, used for Linear Regression and Mixed Effects Model for optimization + double get_explanatory_variable(); + //! Set the explanatory variable defined for the subject, used for Linear Regression and Mixed Effects Model for optimization + void set_explanatory_variable(double val); + //! Get the notes std::string get_notes(); //! Set the notes @@ -118,6 +123,7 @@ class Subject { std::string display_name_; bool fixed_ = false; bool excluded_ = false; + double explanatory_variable_ = 0.0; StringList original_filenames_; StringList groomed_filenames_; StringList local_particle_filenames_; From d67e7076ca5e6ace39ffd2a0b8bc466a10183057 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Mon, 20 May 2024 11:33:27 -0600 Subject: [PATCH 03/22] expose and link linear regression opt params --- Libs/Optimize/Optimize.cpp | 6 ++++++ Libs/Optimize/Optimize.h | 9 +++++++-- Libs/Optimize/OptimizeParameters.cpp | 26 ++++++++++++++++++++++---- Libs/Optimize/OptimizeParameters.h | 4 ++-- 4 files changed, 37 insertions(+), 8 deletions(-) diff --git a/Libs/Optimize/Optimize.cpp b/Libs/Optimize/Optimize.cpp index fcadbb32fa4..dbcec64210d 100644 --- a/Libs/Optimize/Optimize.cpp +++ b/Libs/Optimize/Optimize.cpp @@ -1667,6 +1667,12 @@ void Optimize::SetTimePtsPerSubject(int time_pts_per_subject) { this->m_timepts_ //--------------------------------------------------------------------------- int Optimize::GetTimePtsPerSubject() { return this->m_timepts_per_subject; } +//--------------------------------------------------------------------------- +void Optimize::SetExplanatoryVariables(std::vector val) { this->m_explanatory_variables = val; } + +//--------------------------------------------------------------------------- +std::vector Optimize::GetExplanatoryVariables() { return this->m_explanatory_variables; } + //--------------------------------------------------------------------------- void Optimize::SetOptimizationIterations(int optimization_iterations) { this->m_optimization_iterations = optimization_iterations; diff --git a/Libs/Optimize/Optimize.h b/Libs/Optimize/Optimize.h index 3f86a2f059a..2744bd58425 100644 --- a/Libs/Optimize/Optimize.h +++ b/Libs/Optimize/Optimize.h @@ -158,10 +158,14 @@ class Optimize { m_mesh_ffc_mode = mesh_ffc_mode; m_sampler->SetMeshFFCMode(mesh_ffc_mode); } - //! Set the number of time points per subject (TODO: details) + //! Set the number of time points per subject used for Linear Regression or Mixed Effects Model optimization void SetTimePtsPerSubject(int time_pts_per_subject); - //! Get the number of time points per subject (TODO: details) + //! Get the number of time points per subject used for Linear Regression or Mixed Effects Model optimization int GetTimePtsPerSubject(); + //! Set Explanatory Variable for | used for Linear Regression or Mixed Effects Model optimization + void SetExplanatoryVariables(std::vector vals); + //! Get the number of time points per subject used for Linear Regression or Mixed Effects Model optimization + std::vector GetExplanatoryVariables(); //! Set the number of optimization iterations void SetOptimizationIterations(int optimization_iterations); //! Set the number of optimization iterations already completed (TODO: details) @@ -388,6 +392,7 @@ class Optimize { bool m_mesh_ffc_mode = 0; unsigned int m_timepts_per_subject = 1; + std::vector m_explanatory_variables; int m_optimization_iterations = 2000; int m_optimization_iterations_completed = 0; int m_iterations_per_split = 1000; diff --git a/Libs/Optimize/OptimizeParameters.cpp b/Libs/Optimize/OptimizeParameters.cpp index b45a97f4c66..efc46536467 100644 --- a/Libs/Optimize/OptimizeParameters.cpp +++ b/Libs/Optimize/OptimizeParameters.cpp @@ -46,7 +46,7 @@ const std::string save_init_splits = "save_init_splits"; const std::string keep_checkpoints = "keep_checkpoints"; const std::string use_disentangled_ssm = "use_disentangled_ssm"; const std::string use_linear_regression = "use_linear_regression"; -const std::string use_mixed_effects_model = "use_mixed_effects_model"; +const std::string time_points_per_subject = "time_points_per_subject"; const std::string field_attributes = "field_attributes"; const std::string field_attribute_weights = "field_attribute_weights"; const std::string use_geodesics_to_landmarks = "use_geodesics_to_landmarks"; @@ -96,7 +96,7 @@ OptimizeParameters::OptimizeParameters(ProjectHandle project) { Keys::keep_checkpoints, Keys::use_disentangled_ssm, Keys::use_linear_regression, - Keys::use_mixed_effects_model, + Keys::time_points_per_subject, Keys::particle_format, Keys::geodesic_remesh_percent, Keys::shared_boundary, @@ -212,10 +212,10 @@ bool OptimizeParameters::get_use_linear_regression() { return params_.get(Keys:: void OptimizeParameters::set_use_linear_regression(bool value) { params_.set(Keys::use_linear_regression, value); } //--------------------------------------------------------------------------- -bool OptimizeParameters::get_use_mixed_effects_model() { return params_.get(Keys::use_mixed_effects_model, false); } +int OptimizeParameters::get_time_points_per_subject() { return params_.get(Keys::time_points_per_subject, 1); } //--------------------------------------------------------------------------- -void OptimizeParameters::set_use_mixed_effects_model(bool value) { params_.set(Keys::use_mixed_effects_model, value); } +void OptimizeParameters::set_time_points_per_subject(int value) { params_.set(Keys::time_points_per_subject, value); } //--------------------------------------------------------------------------- bool OptimizeParameters::get_use_procrustes_scaling() { return params_.get(Keys::procrustes_scaling, false); } @@ -449,6 +449,9 @@ bool OptimizeParameters::set_up_optimize(Optimize* optimize) { optimize->SetMeshFFCMode(get_mesh_ffc_mode()); optimize->SetUseDisentangledSpatiotemporalSSM(get_use_disentangled_ssm()); optimize->set_particle_format(get_particle_format()); + optimize->SetTimePtsPerSubject(get_time_points_per_subject()); + optimize->SetUseRegression(get_use_linear_regression()); + optimize->SetUseMixedEffects(get_time_points_per_subject() > 1 ? true : false); optimize->SetSharedBoundaryEnabled(get_shared_boundary()); optimize->SetSharedBoundaryWeight(get_shared_boundary_weight()); @@ -644,6 +647,21 @@ bool OptimizeParameters::set_up_optimize(Optimize* optimize) { } } + // get explanatory variables for subjects if used for regression + if (get_use_linear_regression()) + { + std::vector exp_vars; + for (const auto& s : subjects) { + exp_vars.push_back(s->get_explanatory_variable()); + } + dynamic_cast( + optimize->GetSampler()->GetEnsembleRegressionEntropyFunction()->GetShapeMatrix()) + ->SetExplanatory(exp_vars); + dynamic_cast( + optimize->GetSampler()->GetEnsembleMixedEffectsEntropyFunction()->GetShapeMatrix()) + ->SetExplanatory(exp_vars); + } + std::vector filenames; int count = 0; domain_count = 0; diff --git a/Libs/Optimize/OptimizeParameters.h b/Libs/Optimize/OptimizeParameters.h index fb28b3abd0f..58d014f4fd9 100644 --- a/Libs/Optimize/OptimizeParameters.h +++ b/Libs/Optimize/OptimizeParameters.h @@ -63,8 +63,8 @@ class OptimizeParameters { bool get_use_linear_regression(); void set_use_linear_regression(bool value); - bool get_use_mixed_effects_model(); - void set_use_mixed_effects_model(bool value); + int get_time_points_per_subject(); + void set_time_points_per_subject(int value); bool get_use_procrustes(); void set_use_procrustes(bool value); From 17602e7e8e3d8232971be3750a34a2c949ca7491 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Thu, 16 May 2024 18:41:53 -0600 Subject: [PATCH 04/22] support explanatory variable in SW project --- Libs/Project/ProjectReader.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/Libs/Project/ProjectReader.cpp b/Libs/Project/ProjectReader.cpp index 936bf3fb1c2..9029174296a 100644 --- a/Libs/Project/ProjectReader.cpp +++ b/Libs/Project/ProjectReader.cpp @@ -68,7 +68,6 @@ void ProjectReader::load_subjects(StringMapList list) { if (contains(item, "excluded")) { subject->set_excluded(Variant(item["excluded"])); } - if (contains(item, "explanatory_variable")) { subject->set_explanatory_variable(Variant(item["explanatory_variable"])); } From 91d6c4b37f46a280c202da680db50c13c34a7996 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Sat, 1 Jun 2024 15:35:02 -0600 Subject: [PATCH 05/22] add ui elements for use regression feature --- Studio/Optimize/OptimizeTool.ui | 64 +++++++++++++++++++++++++++++++-- 1 file changed, 62 insertions(+), 2 deletions(-) diff --git a/Studio/Optimize/OptimizeTool.ui b/Studio/Optimize/OptimizeTool.ui index 2f1bc5d173c..81866106d94 100644 --- a/Studio/Optimize/OptimizeTool.ui +++ b/Studio/Optimize/OptimizeTool.ui @@ -302,6 +302,13 @@ QWidget#optimize_panel { + + + + Use Linear Regression + + + @@ -857,8 +864,59 @@ QWidget#optimize_panel { - - + + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + Qt::Horizontal + + + + 40 + 20 + + + + + + + + + 100 @@ -1223,6 +1281,8 @@ QWidget#optimize_panel { use_landmarks narrow_band use_disentangled_ssm + use_linear_regression + From 40ff752238adeee698e4275a85e8e22759db0c8c Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Sat, 1 Jun 2024 15:40:54 -0600 Subject: [PATCH 06/22] link linear regression ui to optimizetool --- Studio/Optimize/OptimizeTool.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Studio/Optimize/OptimizeTool.cpp b/Studio/Optimize/OptimizeTool.cpp index c5225f36399..b0c20eb315e 100644 --- a/Studio/Optimize/OptimizeTool.cpp +++ b/Studio/Optimize/OptimizeTool.cpp @@ -63,7 +63,10 @@ OptimizeTool::OptimizeTool(Preferences& prefs, Telemetry& telemetry) : preferenc "It has no effect on the optimization"); ui_->shared_boundary->setToolTip("Use shared boundary optimization"); ui_->shared_boundary_weight->setToolTip("Weight of shared boundary optimization"); - ui_->use_disentangled_ssm->setToolTip("Use disentangled Optimization technique to build spatiotemporal SSM."); + ui_->use_disentangled_ssm->setToolTip("Use the disentangled optimization technique to build spatiotemporal SSM."); + ui_->use_linear_regression->setToolTip("Use the linear regression optimization technique, where correspondence particle optimization is performed by regressing shape against an explanatory variable. Ensure that the explanatory variable is specified in the data tab of the project file."); + + // hidden for 6.5 release ui_->disentangled_label->hide(); @@ -286,6 +289,8 @@ void OptimizeTool::load_params() { ui_->use_geodesics_from_landmarks->setChecked(params.get_use_geodesics_to_landmarks()); ui_->geodesics_to_landmarks_weight->setText(QString::number(params.get_geodesic_to_landmarks_weight())); ui_->use_disentangled_ssm->setChecked(params.get_use_disentangled_ssm()); + ui_->use_linear_regression->setChecked(params.get_use_linear_regression()); + ui_->procrustes->setChecked(params.get_use_procrustes()); ui_->procrustes_scaling->setChecked(params.get_use_procrustes_scaling()); @@ -334,6 +339,7 @@ void OptimizeTool::store_params() { params.set_use_geodesics_to_landmarks(ui_->use_geodesics_from_landmarks->isChecked()); params.set_geodesic_to_landmarks_weight(ui_->geodesics_to_landmarks_weight->text().toDouble()); params.set_use_disentangled_ssm(ui_->use_disentangled_ssm->isChecked()); + params.set_use_linear_regression(ui_->use_linear_regression->isChecked()); params.set_use_procrustes(ui_->procrustes->isChecked()); params.set_use_procrustes_scaling(ui_->procrustes_scaling->isChecked()); From 2ef29a2eb458634f8a7d34613b8d6503c0d6ae72 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Tue, 4 Jun 2024 14:06:56 -0600 Subject: [PATCH 07/22] more studio support --- Studio/Optimize/OptimizeTool.cpp | 13 ++++++++++--- Studio/Optimize/OptimizeTool.ui | 18 ++++++++++++++++++ 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/Studio/Optimize/OptimizeTool.cpp b/Studio/Optimize/OptimizeTool.cpp index b0c20eb315e..705c0771c3e 100644 --- a/Studio/Optimize/OptimizeTool.cpp +++ b/Studio/Optimize/OptimizeTool.cpp @@ -33,6 +33,7 @@ OptimizeTool::OptimizeTool(Preferences& prefs, Telemetry& telemetry) : preferenc connect(ui_->use_normals, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); connect(ui_->procrustes, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); connect(ui_->multiscale, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); + connect(ui_->use_linear_regression, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); connect(ui_->use_geodesics_from_landmarks, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); connect(ui_->use_geodesic_distance, &QCheckBox::toggled, this, &OptimizeTool::update_ui_elements); @@ -65,7 +66,7 @@ OptimizeTool::OptimizeTool(Preferences& prefs, Telemetry& telemetry) : preferenc ui_->shared_boundary_weight->setToolTip("Weight of shared boundary optimization"); ui_->use_disentangled_ssm->setToolTip("Use the disentangled optimization technique to build spatiotemporal SSM."); ui_->use_linear_regression->setToolTip("Use the linear regression optimization technique, where correspondence particle optimization is performed by regressing shape against an explanatory variable. Ensure that the explanatory variable is specified in the data tab of the project file."); - + ui_->time_points_per_subject->setToolTip("Number of timepoints/explanatory variables defined for each subject in the data tab. Note: More than 1 timepoint uses a mixed effects model; 1 timepoint uses linear regression. "); // hidden for 6.5 release @@ -74,6 +75,8 @@ OptimizeTool::OptimizeTool(Preferences& prefs, Telemetry& telemetry) : preferenc QIntValidator* above_zero = new QIntValidator(1, std::numeric_limits::max(), this); QIntValidator* zero_and_up = new QIntValidator(0, std::numeric_limits::max(), this); + QIntValidator* one_and_up = new QIntValidator(1, std::numeric_limits::max(), this); + QDoubleValidator* double_validator = new QDoubleValidator(0, std::numeric_limits::max(), 1000, this); @@ -89,6 +92,7 @@ OptimizeTool::OptimizeTool(Preferences& prefs, Telemetry& telemetry) : preferenc ui_->multiscale_particles->setValidator(above_zero); ui_->narrow_band->setValidator(double_validator); ui_->geodesics_to_landmarks_weight->setValidator(double_validator); + ui_->time_points_per_subject->setValidator(one_and_up); ui_->shared_boundary_weight->setValidator(double_validator); line_edits_.push_back(ui_->number_of_particles); @@ -103,7 +107,7 @@ OptimizeTool::OptimizeTool(Preferences& prefs, Telemetry& telemetry) : preferenc line_edits_.push_back(ui_->multiscale_particles); line_edits_.push_back(ui_->geodesics_to_landmarks_weight); line_edits_.push_back(ui_->narrow_band); - line_edits_.push_back(ui_->shared_boundary_weight); + for (QLineEdit* line_edit : line_edits_) { connect(line_edit, &QLineEdit::textChanged, this, &OptimizeTool::update_run_button); @@ -289,8 +293,9 @@ void OptimizeTool::load_params() { ui_->use_geodesics_from_landmarks->setChecked(params.get_use_geodesics_to_landmarks()); ui_->geodesics_to_landmarks_weight->setText(QString::number(params.get_geodesic_to_landmarks_weight())); ui_->use_disentangled_ssm->setChecked(params.get_use_disentangled_ssm()); - ui_->use_linear_regression->setChecked(params.get_use_linear_regression()); + ui_->use_linear_regression->setChecked(params.get_use_linear_regression()); + ui_->time_points_per_subject->setText(QString::number(params.get_time_points_per_subject())); ui_->procrustes->setChecked(params.get_use_procrustes()); ui_->procrustes_scaling->setChecked(params.get_use_procrustes_scaling()); @@ -340,6 +345,7 @@ void OptimizeTool::store_params() { params.set_geodesic_to_landmarks_weight(ui_->geodesics_to_landmarks_weight->text().toDouble()); params.set_use_disentangled_ssm(ui_->use_disentangled_ssm->isChecked()); params.set_use_linear_regression(ui_->use_linear_regression->isChecked()); + params.set_time_points_per_subject(ui_->time_points_per_subject->text().toDouble()); params.set_use_procrustes(ui_->procrustes->isChecked()); params.set_use_procrustes_scaling(ui_->procrustes_scaling->isChecked()); @@ -388,6 +394,7 @@ void OptimizeTool::update_ui_elements() { ui_->procrustes_rotation_translation->setEnabled(ui_->procrustes->isChecked()); ui_->procrustes_interval->setEnabled(ui_->procrustes->isChecked()); ui_->multiscale_particles->setEnabled(ui_->multiscale->isChecked()); + ui_->time_points_per_subject->setEnabled(ui_->use_linear_regression->isChecked()); ui_->geodesics_to_landmarks_weight->setEnabled(ui_->use_geodesics_from_landmarks->isChecked()); ui_->geodesic_remesh_percent->setEnabled(ui_->use_geodesic_distance->isChecked()); diff --git a/Studio/Optimize/OptimizeTool.ui b/Studio/Optimize/OptimizeTool.ui index 81866106d94..92fcf61bd68 100644 --- a/Studio/Optimize/OptimizeTool.ui +++ b/Studio/Optimize/OptimizeTool.ui @@ -435,6 +435,13 @@ QWidget#optimize_panel { + + + + Timepoints defined per subject + + + @@ -558,6 +565,16 @@ QWidget#optimize_panel { + + + + 1 + + + Qt::AlignCenter + + + @@ -1282,6 +1299,7 @@ QWidget#optimize_panel { narrow_band use_disentangled_ssm use_linear_regression + time_points_per_subject From 69fcb3c6d44759ecf67ea7a321f373e865d930ce Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Thu, 16 May 2024 18:41:53 -0600 Subject: [PATCH 08/22] support explanatory variable in SW project --- Studio/Resources/.nfs000000041c1dd02f0000039f | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) create mode 100644 Studio/Resources/.nfs000000041c1dd02f0000039f diff --git a/Studio/Resources/.nfs000000041c1dd02f0000039f b/Studio/Resources/.nfs000000041c1dd02f0000039f new file mode 100644 index 00000000000..528a903a883 --- /dev/null +++ b/Studio/Resources/.nfs000000041c1dd02f0000039f @@ -0,0 +1,60 @@ + + + Images/shapes-icon.png + Images/acorn.png + Images/circle.png + Images/hammer.png + Images/bug.png + Images/pencil.png + Images/palette.png + Images/red_dots.png + Images/wand.png + Images/injection.png + Images/hammer2.png + Images/wand2.png + Images/star.png + Images/star2.png + Images/snowflake.png + Images/grey_ball.png + Images/run.png + Images/blocks.png + Images/blocks2.png + Images/blue_ball.png + Images/purple_ball.png + Images/dots.png + Images/wrench.png + Images/wrench2.png + Images/gear2.png + Images/add.png + Images/remove.png + Images/select.png + Images/unselect.png + Images/data.png + Images/chart.png + Images/deep_ssm.png + Images/gear.png + Images/tools.png + Images/shapeworks-logo.png + Images/DownArrow.png + Images/DownArrowWhite.png + Images/RightArrow.png + Images/RightArrowWhite.png + Images/AutoView.png + Images/AutoViewOff.png + Images/IsosurfaceVisible.png + Images/IsosurfaceVisibleOff.png + Images/Visible.png + Images/VisibleGray.png + Images/VisibleOff.png + Images/spinner.png + Images/log_normal.png + Images/log_warning.png + Images/log_error.png + Images/Brush.png + Images/flag_on.png + Images/flag_off.png + Images/planes_on.png + Images/planes_off.png + Images/down_arrow.png + + From 5de96b6e27bd61eeec74165b2dca9d4ea14079c1 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Thu, 13 Jun 2024 10:49:24 -0600 Subject: [PATCH 09/22] more studio changes --- Libs/Optimize/OptimizeParameters.cpp | 5 +++++ Libs/Optimize/OptimizeParameters.h | 1 + Studio/Analysis/AnalysisTool.cpp | 14 ++++++++++++-- Studio/Data/Session.cpp | 2 ++ Studio/Interface/ShapeWorksStudioApp.cpp | 8 ++++++++ Studio/Optimize/OptimizeTool.h | 6 ++++++ 6 files changed, 34 insertions(+), 2 deletions(-) diff --git a/Libs/Optimize/OptimizeParameters.cpp b/Libs/Optimize/OptimizeParameters.cpp index efc46536467..ae6e97a883d 100644 --- a/Libs/Optimize/OptimizeParameters.cpp +++ b/Libs/Optimize/OptimizeParameters.cpp @@ -55,6 +55,7 @@ const std::string particle_format = "particle_format"; const std::string geodesic_remesh_percent = "geodesic_remesh_percent"; const std::string shared_boundary = "shared_boundary"; const std::string shared_boundary_weight = "shared_boundary_weight"; +const std::string output_prefix = "output_prefix"; } // namespace Keys //--------------------------------------------------------------------------- @@ -99,6 +100,7 @@ OptimizeParameters::OptimizeParameters(ProjectHandle project) { Keys::time_points_per_subject, Keys::particle_format, Keys::geodesic_remesh_percent, + Keys::output_prefix, Keys::shared_boundary, Keys::shared_boundary_weight}; @@ -887,6 +889,9 @@ void OptimizeParameters::set_geodesic_remesh_percent(double value) { params_.set(Keys::geodesic_remesh_percent, value); } +//--------------------------------------------------------------------------- +void OptimizeParameters::set_output_prefix(std::string value) { params_.set(Keys::output_prefix, value); } + //--------------------------------------------------------------------------- bool OptimizeParameters::get_shared_boundary() { return params_.get(Keys::shared_boundary, false); } diff --git a/Libs/Optimize/OptimizeParameters.h b/Libs/Optimize/OptimizeParameters.h index 58d014f4fd9..99727771e60 100644 --- a/Libs/Optimize/OptimizeParameters.h +++ b/Libs/Optimize/OptimizeParameters.h @@ -143,6 +143,7 @@ class OptimizeParameters { double get_shared_boundary_weight(); void set_shared_boundary_weight(double value); + void set_output_prefix(std::string value); private: std::string get_output_prefix(); diff --git a/Studio/Analysis/AnalysisTool.cpp b/Studio/Analysis/AnalysisTool.cpp index 0a4d9b668da..6119d9cccb7 100644 --- a/Studio/Analysis/AnalysisTool.cpp +++ b/Studio/Analysis/AnalysisTool.cpp @@ -138,7 +138,7 @@ AnalysisTool::AnalysisTool(Preferences& prefs) : preferences_(prefs) { ui_->metrics_open_button->setChecked(false); /// TODO nothing there yet (regression tab) - ui_->tabWidget->removeTab(3); + // ui_->tabWidget->removeTab(3); for (auto button : {ui_->distance_transform_radio_button, ui_->mesh_warping_radio_button, ui_->legacy_radio_button}) { connect(button, &QRadioButton::clicked, this, &AnalysisTool::reconstruction_method_changed); @@ -378,7 +378,7 @@ void AnalysisTool::handle_analysis_options() { ui_->mcaLevelBetweenButton->setEnabled(true); ui_->vanillaPCAButton->setChecked(true); } - } else { + } else if (ui_->tabWidget->currentWidget() == ui_->regression_tab){ // regression mode ui_->sampleSpinBox->setEnabled(false); ui_->medianButton->setEnabled(false); @@ -386,6 +386,14 @@ void AnalysisTool::handle_analysis_options() { ui_->pcaAnimateCheckBox->setEnabled(false); ui_->pcaModeSpinBox->setEnabled(false); pca_animate_timer_.stop(); + + } else { + ui_->sampleSpinBox->setEnabled(false); + ui_->medianButton->setEnabled(false); + ui_->pcaSlider->setEnabled(false); + ui_->pcaAnimateCheckBox->setEnabled(false); + ui_->pcaModeSpinBox->setEnabled(false); + pca_animate_timer_.stop(); } update_difference_particles(); @@ -861,6 +869,8 @@ void AnalysisTool::store_settings() { params.set("network_pvalue_of_interest", ui_->network_pvalue_of_interest->text().toStdString()); params.set("network_pvalue_threshold", ui_->network_pvalue_threshold->text().toStdString()); + params.set("regression_slope", session->) + session_->get_project()->set_parameters(Parameters::ANALYSIS_PARAMS, params); } diff --git a/Studio/Data/Session.cpp b/Studio/Data/Session.cpp index 8513b99a1d6..c79528a74b8 100644 --- a/Studio/Data/Session.cpp +++ b/Studio/Data/Session.cpp @@ -837,6 +837,8 @@ void Session::new_plane_point(PickResult result) { //--------------------------------------------------------------------------- QString Session::get_filename() { return filename_; } +QString Session::get_parent_dir() + //--------------------------------------------------------------------------- int Session::get_num_shapes() { return shapes_.size(); } diff --git a/Studio/Interface/ShapeWorksStudioApp.cpp b/Studio/Interface/ShapeWorksStudioApp.cpp index bb0128c0a35..7f58d3f812f 100644 --- a/Studio/Interface/ShapeWorksStudioApp.cpp +++ b/Studio/Interface/ShapeWorksStudioApp.cpp @@ -1528,6 +1528,14 @@ void ShapeWorksStudioApp::open_project(QString filename) { groom_tool_->load_params(); optimize_tool_->load_params(); + + if (optimize_tool_->get_regression_analysis_status()) + { + // Verify if slope and intercept files exist + auto particles_dir = session_->get_filename().dir().absolutePath().toStdString(); + auto slope_filename = session_->get_filename().toStdString() + } + analysis_tool_->store_settings(); update_from_preferences(); update_tool_mode(); diff --git a/Studio/Optimize/OptimizeTool.h b/Studio/Optimize/OptimizeTool.h index e62b58a896b..f88e3226261 100644 --- a/Studio/Optimize/OptimizeTool.h +++ b/Studio/Optimize/OptimizeTool.h @@ -37,6 +37,10 @@ Q_OBJECT; //! Load params from project void load_params(); //! Store params to project + + //! Get flag if regression needs to enabled for analysis in Studio + inline bool get_regression_analysis_status() { return regression_analysis_status; } + void store_params(); //! Enable action buttons @@ -94,5 +98,7 @@ public Q_SLOTS: QElapsedTimer elapsed_timer_; Ui_OptimizeTool* ui_; + + bool regression_analysis_status_; }; } From fd0e1bafef06e1d00d157639fbd1d82c12ea94cc Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Wed, 9 Oct 2024 12:28:42 -0600 Subject: [PATCH 10/22] rebase changes --- Libs/Particles/ParticleShapeStatistics.cpp | 2 ++ Studio/Analysis/AnalysisTool.cpp | 2 +- Studio/Data/Session.cpp | 2 +- Studio/Interface/ShapeWorksStudioApp.cpp | 4 ++-- Studio/Optimize/OptimizeTool.h | 2 +- Studio/Optimize/OptimizeTool.ui | 10 ++++++++++ 6 files changed, 17 insertions(+), 5 deletions(-) diff --git a/Libs/Particles/ParticleShapeStatistics.cpp b/Libs/Particles/ParticleShapeStatistics.cpp index 288eae4a44c..aa6d8c008b8 100644 --- a/Libs/Particles/ParticleShapeStatistics.cpp +++ b/Libs/Particles/ParticleShapeStatistics.cpp @@ -694,4 +694,6 @@ Eigen::MatrixXd ParticleShapeStatistics::get_group1_matrix() const { return grou //--------------------------------------------------------------------------- Eigen::MatrixXd ParticleShapeStatistics::get_group2_matrix() const { return group2_matrix_; } + + } // namespace shapeworks diff --git a/Studio/Analysis/AnalysisTool.cpp b/Studio/Analysis/AnalysisTool.cpp index 6119d9cccb7..5896cf71878 100644 --- a/Studio/Analysis/AnalysisTool.cpp +++ b/Studio/Analysis/AnalysisTool.cpp @@ -869,7 +869,7 @@ void AnalysisTool::store_settings() { params.set("network_pvalue_of_interest", ui_->network_pvalue_of_interest->text().toStdString()); params.set("network_pvalue_threshold", ui_->network_pvalue_threshold->text().toStdString()); - params.set("regression_slope", session->) + // params.set("regression_slope", session->) session_->get_project()->set_parameters(Parameters::ANALYSIS_PARAMS, params); } diff --git a/Studio/Data/Session.cpp b/Studio/Data/Session.cpp index c79528a74b8..36b3d6ba2b5 100644 --- a/Studio/Data/Session.cpp +++ b/Studio/Data/Session.cpp @@ -837,7 +837,7 @@ void Session::new_plane_point(PickResult result) { //--------------------------------------------------------------------------- QString Session::get_filename() { return filename_; } -QString Session::get_parent_dir() +// QString Session::get_parent_dir() //--------------------------------------------------------------------------- int Session::get_num_shapes() { return shapes_.size(); } diff --git a/Studio/Interface/ShapeWorksStudioApp.cpp b/Studio/Interface/ShapeWorksStudioApp.cpp index 7f58d3f812f..b312dea14ee 100644 --- a/Studio/Interface/ShapeWorksStudioApp.cpp +++ b/Studio/Interface/ShapeWorksStudioApp.cpp @@ -1532,8 +1532,8 @@ void ShapeWorksStudioApp::open_project(QString filename) { if (optimize_tool_->get_regression_analysis_status()) { // Verify if slope and intercept files exist - auto particles_dir = session_->get_filename().dir().absolutePath().toStdString(); - auto slope_filename = session_->get_filename().toStdString() + // auto particles_dir = session_->get_filename().dir().absolutePath().toStdString(); + // auto slope_filename = session_->get_filename().toStdString(); } analysis_tool_->store_settings(); update_from_preferences(); diff --git a/Studio/Optimize/OptimizeTool.h b/Studio/Optimize/OptimizeTool.h index f88e3226261..cab850aa3f2 100644 --- a/Studio/Optimize/OptimizeTool.h +++ b/Studio/Optimize/OptimizeTool.h @@ -39,7 +39,7 @@ Q_OBJECT; //! Store params to project //! Get flag if regression needs to enabled for analysis in Studio - inline bool get_regression_analysis_status() { return regression_analysis_status; } + inline bool get_regression_analysis_status() { return regression_analysis_status_; } void store_params(); diff --git a/Studio/Optimize/OptimizeTool.ui b/Studio/Optimize/OptimizeTool.ui index 92fcf61bd68..f741c6c05e6 100644 --- a/Studio/Optimize/OptimizeTool.ui +++ b/Studio/Optimize/OptimizeTool.ui @@ -881,6 +881,16 @@ QWidget#optimize_panel { + + + + 100 + + + Qt::AlignCenter + + + From e2be77d7e263dc7c3e5b554113f05cac2d9ab02f Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Tue, 31 Dec 2024 12:22:59 -0700 Subject: [PATCH 11/22] new changes --- Libs/Particles/ParticleShapeStatistics.h | 10 ++- Libs/Project/Subject.h | 2 +- Studio/Analysis/AnalysisTool.cpp | 84 ++++++++++++++++++++++-- Studio/Analysis/AnalysisTool.h | 9 +++ Studio/Analysis/AnalysisTool.ui | 63 ++++++++++++++++++ Studio/Data/Session.cpp | 15 +++++ Studio/Data/Session.h | 2 + 7 files changed, 178 insertions(+), 7 deletions(-) diff --git a/Libs/Particles/ParticleShapeStatistics.h b/Libs/Particles/ParticleShapeStatistics.h index 28b0972676b..e8b5746759f 100644 --- a/Libs/Particles/ParticleShapeStatistics.h +++ b/Libs/Particles/ParticleShapeStatistics.h @@ -135,6 +135,9 @@ class ParticleShapeStatistics { //! Set the meshes for each sample (used for some evaluation metrics) void set_meshes(const std::vector& meshes) { meshes_ = meshes; } + // import estimated parameters for regression + inline bool import_regression_parameters(Eigen::VectorXd slope, Eigen::VectorXd intercept) { slope_ = slope; intercept_ = intercept; }; + private: unsigned int num_samples_group1_; unsigned int num_samples_group2_; @@ -147,9 +150,14 @@ class ParticleShapeStatistics { std::vector eigenvalues_; Eigen::VectorXd mean_; Eigen::VectorXd mean1_; - Eigen::VectorXd mean2_; + Eigen::VectorXd mean2_;x Eigen::MatrixXd points_minus_mean_; Eigen::MatrixXd shapes_; + + // for regression tasks + Eigen::VectorXd slope_; + Eigen::VectorXd intercept_; + bool regression_enabled_; std::vector percent_variance_by_mode_; Eigen::MatrixXd principals_; diff --git a/Libs/Project/Subject.h b/Libs/Project/Subject.h index 16c32973656..585cd075901 100644 --- a/Libs/Project/Subject.h +++ b/Libs/Project/Subject.h @@ -123,7 +123,7 @@ class Subject { std::string display_name_; bool fixed_ = false; bool excluded_ = false; - double explanatory_variable_ = 0.0; + double explanatory_variable_ = std::numeric_limits::lowest(); StringList original_filenames_; StringList groomed_filenames_; StringList local_particle_filenames_; diff --git a/Studio/Analysis/AnalysisTool.cpp b/Studio/Analysis/AnalysisTool.cpp index 5896cf71878..156bc309281 100644 --- a/Studio/Analysis/AnalysisTool.cpp +++ b/Studio/Analysis/AnalysisTool.cpp @@ -269,6 +269,11 @@ void AnalysisTool::on_reconstructionButton_clicked() { //--------------------------------------------------------------------------- int AnalysisTool::get_pca_mode() { return ui_->pcaModeSpinBox->value() - 1; } +//--------------------------------------------------------------------------- +bool AnalysisTool::get_regression_analysis_status() { + return ui_->enableRegressionCheckBox->isChecked(); +} + //--------------------------------------------------------------------------- double AnalysisTool::get_group_ratio() { double group_slider_value = ui_->group_slider->value(); @@ -505,6 +510,35 @@ void AnalysisTool::network_analysis_clicked() { app_->get_py_worker()->run_job(network_analysis_job_); } +Eigen::VectorXd load_regression_parameters(std::string filepath) { + std::ifstream infile(slope_file_path); + if (!infile.good()) { + throw std::runtime_error("Unable to open regression parameter file: \"" + + filepath + "\" for reading"); + } + try { + std::vector temp_values; + double value; + while (infile >> value) { + temp_values.push_back(value); + } + if (temp_values.empty()) { + std::cerr << "Error: No data found in file " << slope_file_path + << std::endl; + return Eigen::VectorXd(); + } + Eigen::VectorXd param_vector(temp_values.size()); + for (std::size_t i = 0; i < temp_values.size(); ++i) { + param_vector[i] = temp_values[i]; + } + return param_vector; + + } catch (json::exception& e) { + throw std::runtime_error("Unabled to parse regression parameter file " + + filepath + " : " + e.what()); + } +} + //----------------------------------------------------------------------------- bool AnalysisTool::compute_stats() { if (stats_ready_) { @@ -627,6 +661,20 @@ bool AnalysisTool::compute_stats() { compute_shape_evaluations(); } + can_run_regression_ = check_explanatory_variable_limits(); + if (can_run_regression_) { + auto slope = load_regression_parameters( + session_->get_regression_param_file("slope")); + auto intercept = load_regression_parameters( + session_->get_regression_param_file("intercept")); + stats_.import_regression_parameters(slope, intercept); + } + else { + ui_->regression_groupbox->setVisible(false); + ui_->explanatoryVariableSlider->setVisible(false); + ui_->enableRegressionCheckBox->setVisible(false); + } + stats_ready_ = true; /// Set this to true to export long format sample data (e.g. for import into R) @@ -667,6 +715,19 @@ bool AnalysisTool::compute_stats() { return true; } +bool check_explanatory_variable_limits() { + auto subjects = session_->get_project()->get_subjects(); + explanatory_variable_limits_.resize(2); + explanatory_variable_limits_[0] = std::numeric_limits::max(); + explanatory_variable_limits_[1] = std::numeric_limits::lowest(); + for (auto sub : subjects) { + double exp_val = sub->get_explanatory_variable(); + if (exp_val == std::numeric_limits::lowest()) return false; + explanatory_variable_limits_[0] = std::min(explanatory_variable_limits_[0], exp_val); + explanatory_variable_limits_[1] = std::max(explanatory_variable_limits_[1], exp_val); + } + return true; +} //----------------------------------------------------------------------------- Particles AnalysisTool::get_mean_shape_points() { if (!compute_stats()) { @@ -729,8 +790,8 @@ Particles AnalysisTool::get_shape_points(int mode, double value) { ui_->explained_variance->setText(""); ui_->cumulative_explained_variance->setText(""); } - - temp_shape_ = stats_.get_mean() + (e * (value * lambda)); + auto mean = !regression_enabled_ ? stats_.get_mean() : stats_.get_regression_mean(ui_->get_explanatory_variable_value()); + temp_shape_ = mean + (e * (value * lambda)); auto positions = temp_shape_; @@ -829,11 +890,17 @@ ShapeHandle AnalysisTool::get_current_shape() { int pca_mode = get_pca_mode(); double pca_value = get_pca_value(); auto mca_level = get_mca_level(); - if (mca_level == AnalysisTool::McaMode::Vanilla) { - return get_mode_shape(pca_mode, pca_value); + bool regression_analysis_enabled = get_regression_analysis_status(); + if (!regression_analysis_enabled) { + if (mca_level == AnalysisTool::McaMode::Vanilla) { + return get_mode_shape(pca_mode, pca_value); + } else { + return get_mca_mode_shape(pca_mode, pca_value, mca_level); + } } else { - return get_mca_mode_shape(pca_mode, pca_value, mca_level); + } + } //--------------------------------------------------------------------------- @@ -1095,6 +1162,13 @@ double AnalysisTool::get_pca_value() { return value; } + +double AnalysisTool::get_explanatory_variable_value() { + int slider_value = ui_->explanatoryVariableSlider->value(); + return t_min + (static_cast(slider_value) / 100.0) * (t_max - t_min); + +} + //--------------------------------------------------------------------------- void AnalysisTool::pca_labels_changed(QString value, QString eigen, QString lambda) { set_labels(QString("pca"), value); diff --git a/Studio/Analysis/AnalysisTool.h b/Studio/Analysis/AnalysisTool.h index d6198e972ab..81e22509bb5 100644 --- a/Studio/Analysis/AnalysisTool.h +++ b/Studio/Analysis/AnalysisTool.h @@ -80,6 +80,10 @@ class AnalysisTool : public QWidget { bool pca_animate(); McaMode get_mca_level() const; + bool get_regression_analysis_status(); + + bool check_explanatory_variable_limits(); + int get_sample_number(); bool compute_stats(); @@ -236,6 +240,8 @@ class AnalysisTool : public QWidget { void update_difference_particles(); Eigen::VectorXd get_mean_shape_particles(); + + Eigen::VectorXd load_regression_parameters(std::string filepath); ShapeHandle create_shape_from_points(Particles points); @@ -275,6 +281,9 @@ class AnalysisTool : public QWidget { std::string feature_map_; + std::vector explanatory_variable_limits_; + bool can_run_regression_; + std::vector current_group_names_; std::vector current_group_values_; diff --git a/Studio/Analysis/AnalysisTool.ui b/Studio/Analysis/AnalysisTool.ui index da73800f756..a2316e5b907 100644 --- a/Studio/Analysis/AnalysisTool.ui +++ b/Studio/Analysis/AnalysisTool.ui @@ -1546,6 +1546,69 @@ QWidget#particles_panel { + + + + Regression Analysis + + + + 0 + + + 0 + + + 0 + + + 0 + + + + + Enable regression analysis if explanatory variables are provided + + + Enable Regression Analysis + + + + + + + Exp.Var. + + + + + + + false + + + Explanatory variable slider + + + -20 + + + 20 + + + Qt::Horizontal + + + QSlider::TicksBelow + + + 1 + + + + + + diff --git a/Studio/Data/Session.cpp b/Studio/Data/Session.cpp index 36b3d6ba2b5..2feedec085e 100644 --- a/Studio/Data/Session.cpp +++ b/Studio/Data/Session.cpp @@ -1418,4 +1418,19 @@ void Session::recompute_surfaces() { } Q_EMIT update_display(); } + +std::string get_regression_param_file(std::string param_name) { + QFileInfo fileInfo(filename_); + QString baseName = fileInfo.completeBaseName(); + + QDir projectDir = fileInfo.absoluteDir(); + QString particlesDir = baseName + "_particles"; + QString paramFilePath = projectDir.filePath(particlesDir); + paramFilePath = QDir(paramFilePath).filePath(param_name); + + if (!QFile::exists(paramFilePath)) { + return ""; + } + return paramFilePath.toStdString(); +} } // namespace shapeworks diff --git a/Studio/Data/Session.h b/Studio/Data/Session.h index a7d9f7a3f79..a445ec8b55e 100644 --- a/Studio/Data/Session.h +++ b/Studio/Data/Session.h @@ -339,6 +339,8 @@ class Session : public QObject, public QEnableSharedFromThis { void new_plane_point(PickResult result); + std::string get_regression_param_file(std::string param_name = "slope"); + QWidget* parent_{nullptr}; Preferences& preferences_; From 92a8570d3948a5cbb656d33888477f6d23da85b3 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Tue, 31 Dec 2024 12:28:00 -0700 Subject: [PATCH 12/22] typos fix --- Libs/Particles/ParticleShapeStatistics.h | 2 +- Studio/Analysis/AnalysisTool.cpp | 2 +- Studio/Resources/.nfs000000041c1dd02f0000039f | 60 ------------------- 3 files changed, 2 insertions(+), 62 deletions(-) delete mode 100644 Studio/Resources/.nfs000000041c1dd02f0000039f diff --git a/Libs/Particles/ParticleShapeStatistics.h b/Libs/Particles/ParticleShapeStatistics.h index e8b5746759f..0606b778593 100644 --- a/Libs/Particles/ParticleShapeStatistics.h +++ b/Libs/Particles/ParticleShapeStatistics.h @@ -150,7 +150,7 @@ class ParticleShapeStatistics { std::vector eigenvalues_; Eigen::VectorXd mean_; Eigen::VectorXd mean1_; - Eigen::VectorXd mean2_;x + Eigen::VectorXd mean2_; Eigen::MatrixXd points_minus_mean_; Eigen::MatrixXd shapes_; diff --git a/Studio/Analysis/AnalysisTool.cpp b/Studio/Analysis/AnalysisTool.cpp index 156bc309281..202e6a2cc6f 100644 --- a/Studio/Analysis/AnalysisTool.cpp +++ b/Studio/Analysis/AnalysisTool.cpp @@ -138,7 +138,7 @@ AnalysisTool::AnalysisTool(Preferences& prefs) : preferences_(prefs) { ui_->metrics_open_button->setChecked(false); /// TODO nothing there yet (regression tab) - // ui_->tabWidget->removeTab(3); + ui_->tabWidget->removeTab(3); for (auto button : {ui_->distance_transform_radio_button, ui_->mesh_warping_radio_button, ui_->legacy_radio_button}) { connect(button, &QRadioButton::clicked, this, &AnalysisTool::reconstruction_method_changed); diff --git a/Studio/Resources/.nfs000000041c1dd02f0000039f b/Studio/Resources/.nfs000000041c1dd02f0000039f deleted file mode 100644 index 528a903a883..00000000000 --- a/Studio/Resources/.nfs000000041c1dd02f0000039f +++ /dev/null @@ -1,60 +0,0 @@ - - - Images/shapes-icon.png - Images/acorn.png - Images/circle.png - Images/hammer.png - Images/bug.png - Images/pencil.png - Images/palette.png - Images/red_dots.png - Images/wand.png - Images/injection.png - Images/hammer2.png - Images/wand2.png - Images/star.png - Images/star2.png - Images/snowflake.png - Images/grey_ball.png - Images/run.png - Images/blocks.png - Images/blocks2.png - Images/blue_ball.png - Images/purple_ball.png - Images/dots.png - Images/wrench.png - Images/wrench2.png - Images/gear2.png - Images/add.png - Images/remove.png - Images/select.png - Images/unselect.png - Images/data.png - Images/chart.png - Images/deep_ssm.png - Images/gear.png - Images/tools.png - Images/shapeworks-logo.png - Images/DownArrow.png - Images/DownArrowWhite.png - Images/RightArrow.png - Images/RightArrowWhite.png - Images/AutoView.png - Images/AutoViewOff.png - Images/IsosurfaceVisible.png - Images/IsosurfaceVisibleOff.png - Images/Visible.png - Images/VisibleGray.png - Images/VisibleOff.png - Images/spinner.png - Images/log_normal.png - Images/log_warning.png - Images/log_error.png - Images/Brush.png - Images/flag_on.png - Images/flag_off.png - Images/planes_on.png - Images/planes_off.png - Images/down_arrow.png - - From 04c25ea6ac93822a62505e95f6bf0240ce4e2937 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Tue, 31 Dec 2024 12:48:13 -0700 Subject: [PATCH 13/22] edit logic --- Studio/Analysis/AnalysisTool.cpp | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/Studio/Analysis/AnalysisTool.cpp b/Studio/Analysis/AnalysisTool.cpp index 202e6a2cc6f..83fb73b1c93 100644 --- a/Studio/Analysis/AnalysisTool.cpp +++ b/Studio/Analysis/AnalysisTool.cpp @@ -890,17 +890,11 @@ ShapeHandle AnalysisTool::get_current_shape() { int pca_mode = get_pca_mode(); double pca_value = get_pca_value(); auto mca_level = get_mca_level(); - bool regression_analysis_enabled = get_regression_analysis_status(); - if (!regression_analysis_enabled) { - if (mca_level == AnalysisTool::McaMode::Vanilla) { + if (mca_level == AnalysisTool::McaMode::Vanilla) { return get_mode_shape(pca_mode, pca_value); } else { return get_mca_mode_shape(pca_mode, pca_value, mca_level); } - } else { - - } - } //--------------------------------------------------------------------------- From 6eb9637565ee51ddafeb2cebe96193037190602f Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Fri, 3 Jan 2025 16:05:12 -0700 Subject: [PATCH 14/22] add comupte regression mean logic --- Libs/Particles/ParticleShapeStatistics.cpp | 21 +++++++++++++++++++++ Libs/Particles/ParticleShapeStatistics.h | 6 ++++-- Studio/Analysis/AnalysisTool.cpp | 15 +++++++++------ Studio/Analysis/AnalysisTool.h | 4 +++- 4 files changed, 37 insertions(+), 9 deletions(-) diff --git a/Libs/Particles/ParticleShapeStatistics.cpp b/Libs/Particles/ParticleShapeStatistics.cpp index aa6d8c008b8..60effe45a84 100644 --- a/Libs/Particles/ParticleShapeStatistics.cpp +++ b/Libs/Particles/ParticleShapeStatistics.cpp @@ -492,6 +492,27 @@ ParticleShapeStatistics::ParticleShapeStatistics(std::shared_ptr projec groups.push_back(1); } import_points(points, groups); + // TODO: importing regression params doesn't make sense here. take a look again later. +} + + Eigen::VectorXd ParticleShapeStatistics::compute_regression_mean(const std::vector& explanatory_variables) const +{ + // Map explanatory variables to an Eigen vector + Eigen::VectorXd t = Eigen::Map(explanatory_variables.data(), explanatory_variables.size()); + + // Ensure slope and intercept are initialized + if (slope_.size() == 0 || intercept_.size() == 0) { + throw std::runtime_error("Slope and Intercept not initialized yet!"); + } + + // Handle scalar and vector cases for t + if (t.size() == 1) { + return slope_ + intercept_ * t[0]; // Scalar broadcasting + } else if (t.size() == slope_.size()) { + return slope_ + intercept_.cwiseProduct(t); // Element-wise multiplication + } else { + throw std::invalid_argument("Size mismatch: t must be either scalar or match dimensions of slope and intercept."); + } } //--------------------------------------------------------------------------- diff --git a/Libs/Particles/ParticleShapeStatistics.h b/Libs/Particles/ParticleShapeStatistics.h index 0606b778593..1960b851212 100644 --- a/Libs/Particles/ParticleShapeStatistics.h +++ b/Libs/Particles/ParticleShapeStatistics.h @@ -87,7 +87,9 @@ class ParticleShapeStatistics { const Eigen::VectorXd& get_mean_rel_pos() { return mean_rel_pose_; } //! Returns the mean shape. - const Eigen::VectorXd& get_mean() const { return mean_; } + const Eigen::VectorXd get_mean() const { return mean_; } + + Eigen::VectorXd compute_regression_mean(const std::vector& explanatory_variables) const; const Eigen::VectorXd& get_group1_mean() const { return mean1_; } const Eigen::VectorXd& get_group2_mean() const { return mean2_; } @@ -136,7 +138,7 @@ class ParticleShapeStatistics { void set_meshes(const std::vector& meshes) { meshes_ = meshes; } // import estimated parameters for regression - inline bool import_regression_parameters(Eigen::VectorXd slope, Eigen::VectorXd intercept) { slope_ = slope; intercept_ = intercept; }; + inline bool import_regression_parameters(Eigen::VectorXd& slope, Eigen::VectorXd& intercept) { slope_ = slope; intercept_ = intercept; return true;}; private: unsigned int num_samples_group1_; diff --git a/Studio/Analysis/AnalysisTool.cpp b/Studio/Analysis/AnalysisTool.cpp index 83fb73b1c93..a15cd7f5817 100644 --- a/Studio/Analysis/AnalysisTool.cpp +++ b/Studio/Analysis/AnalysisTool.cpp @@ -664,10 +664,13 @@ bool AnalysisTool::compute_stats() { can_run_regression_ = check_explanatory_variable_limits(); if (can_run_regression_) { auto slope = load_regression_parameters( - session_->get_regression_param_file("slope")); + session_->get_regression_param_file("slope")); // dM vector auto intercept = load_regression_parameters( - session_->get_regression_param_file("intercept")); - stats_.import_regression_parameters(slope, intercept); + session_->get_regression_param_file("intercept")); // dM vector + stats_.import_regression_parameters(slope, intercept); // set slope and intercept in stats object + ui_->regression_groupbox->setVisible(true); + ui_->explanatoryVariableSlider->setVisible(true); + ui_->enableRegressionCheckBox->setVisible(true); } else { ui_->regression_groupbox->setVisible(false); @@ -790,7 +793,7 @@ Particles AnalysisTool::get_shape_points(int mode, double value) { ui_->explained_variance->setText(""); ui_->cumulative_explained_variance->setText(""); } - auto mean = !regression_enabled_ ? stats_.get_mean() : stats_.get_regression_mean(ui_->get_explanatory_variable_value()); + auto mean = !regression_enabled_ ? stats_.get_mean() : stats_.compute_regression_mean(ui_->get_explanatory_variable_value()); temp_shape_ = mean + (e * (value * lambda)); auto positions = temp_shape_; @@ -1157,9 +1160,9 @@ double AnalysisTool::get_pca_value() { } -double AnalysisTool::get_explanatory_variable_value() { +std::vector AnalysisTool::get_explanatory_variable_value() { int slider_value = ui_->explanatoryVariableSlider->value(); - return t_min + (static_cast(slider_value) / 100.0) * (t_max - t_min); + return {t_min + (static_cast(slider_value) / 100.0) * (t_max - t_min)}; } diff --git a/Studio/Analysis/AnalysisTool.h b/Studio/Analysis/AnalysisTool.h index 81e22509bb5..a2d853d7fa6 100644 --- a/Studio/Analysis/AnalysisTool.h +++ b/Studio/Analysis/AnalysisTool.h @@ -77,6 +77,8 @@ class AnalysisTool : public QWidget { double get_pca_value(); + std::vector get_explanatory_variable_value(); + bool pca_animate(); McaMode get_mca_level() const; @@ -282,7 +284,7 @@ class AnalysisTool : public QWidget { std::string feature_map_; std::vector explanatory_variable_limits_; - bool can_run_regression_; + bool can_run_regression_; // decide if necessary variables are present to run regression in analysis std::vector current_group_names_; std::vector current_group_values_; From d364a4425ddf99fcd68231fc597e433b0d52fd2e Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Fri, 3 Jan 2025 16:07:46 -0700 Subject: [PATCH 15/22] typo fixes --- Libs/Particles/ParticleShapeStatistics.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Libs/Particles/ParticleShapeStatistics.h b/Libs/Particles/ParticleShapeStatistics.h index 1960b851212..ee3e9e6f8b8 100644 --- a/Libs/Particles/ParticleShapeStatistics.h +++ b/Libs/Particles/ParticleShapeStatistics.h @@ -87,9 +87,9 @@ class ParticleShapeStatistics { const Eigen::VectorXd& get_mean_rel_pos() { return mean_rel_pose_; } //! Returns the mean shape. - const Eigen::VectorXd get_mean() const { return mean_; } + const Eigen::VectorXd& get_mean() const { return mean_; } - Eigen::VectorXd compute_regression_mean(const std::vector& explanatory_variables) const; + Eigen::VectorXd compute_regression_mean(const std::vector& explanatory_variables) const; const Eigen::VectorXd& get_group1_mean() const { return mean1_; } const Eigen::VectorXd& get_group2_mean() const { return mean2_; } @@ -138,7 +138,7 @@ class ParticleShapeStatistics { void set_meshes(const std::vector& meshes) { meshes_ = meshes; } // import estimated parameters for regression - inline bool import_regression_parameters(Eigen::VectorXd& slope, Eigen::VectorXd& intercept) { slope_ = slope; intercept_ = intercept; return true;}; + inline bool import_regression_parameters(Eigen::VectorXd slope, Eigen::VectorXd intercept) { slope_ = slope; intercept_ = intercept; return true;}; private: unsigned int num_samples_group1_; From 1783f7710d6d55b7593cefeb02e5e3748a728417 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Fri, 3 Jan 2025 16:10:41 -0700 Subject: [PATCH 16/22] typo fixes --- Libs/Particles/ParticleShapeStatistics.cpp | 32 ++++++++++------------ 1 file changed, 14 insertions(+), 18 deletions(-) diff --git a/Libs/Particles/ParticleShapeStatistics.cpp b/Libs/Particles/ParticleShapeStatistics.cpp index 60effe45a84..979c70a3949 100644 --- a/Libs/Particles/ParticleShapeStatistics.cpp +++ b/Libs/Particles/ParticleShapeStatistics.cpp @@ -495,24 +495,20 @@ ParticleShapeStatistics::ParticleShapeStatistics(std::shared_ptr projec // TODO: importing regression params doesn't make sense here. take a look again later. } - Eigen::VectorXd ParticleShapeStatistics::compute_regression_mean(const std::vector& explanatory_variables) const -{ - // Map explanatory variables to an Eigen vector - Eigen::VectorXd t = Eigen::Map(explanatory_variables.data(), explanatory_variables.size()); - - // Ensure slope and intercept are initialized - if (slope_.size() == 0 || intercept_.size() == 0) { - throw std::runtime_error("Slope and Intercept not initialized yet!"); - } - - // Handle scalar and vector cases for t - if (t.size() == 1) { - return slope_ + intercept_ * t[0]; // Scalar broadcasting - } else if (t.size() == slope_.size()) { - return slope_ + intercept_.cwiseProduct(t); // Element-wise multiplication - } else { - throw std::invalid_argument("Size mismatch: t must be either scalar or match dimensions of slope and intercept."); - } +Eigen::VectorXd ParticleShapeStatistics::compute_regression_mean( + const std::vector& explanatory_variables) const { + Eigen::VectorXd t = Eigen::Map( + explanatory_variables.data(), explanatory_variables.size()); + + // Ensure slope and intercept are initialized + if (slope_.size() == 0 || intercept_.size() == 0) { + throw std::runtime_error("Slope and Intercept not initialized yet!"); + } + + if (t.size() == 1) + return slope_ + intercept_ * t[0]; + else + return slope_ + intercept_.cwiseProduct(t); } //--------------------------------------------------------------------------- From 332ad71129660165d4bf5929d05eddf3daeaf2c9 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Mon, 6 Jan 2025 18:13:11 -0700 Subject: [PATCH 17/22] previous regression tab logic --- Studio/Analysis/AnalysisTool.cpp | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/Studio/Analysis/AnalysisTool.cpp b/Studio/Analysis/AnalysisTool.cpp index a15cd7f5817..befb5510899 100644 --- a/Studio/Analysis/AnalysisTool.cpp +++ b/Studio/Analysis/AnalysisTool.cpp @@ -383,7 +383,7 @@ void AnalysisTool::handle_analysis_options() { ui_->mcaLevelBetweenButton->setEnabled(true); ui_->vanillaPCAButton->setChecked(true); } - } else if (ui_->tabWidget->currentWidget() == ui_->regression_tab){ + } else { // regression mode ui_->sampleSpinBox->setEnabled(false); ui_->medianButton->setEnabled(false); @@ -392,13 +392,6 @@ void AnalysisTool::handle_analysis_options() { ui_->pcaModeSpinBox->setEnabled(false); pca_animate_timer_.stop(); - } else { - ui_->sampleSpinBox->setEnabled(false); - ui_->medianButton->setEnabled(false); - ui_->pcaSlider->setEnabled(false); - ui_->pcaAnimateCheckBox->setEnabled(false); - ui_->pcaModeSpinBox->setEnabled(false); - pca_animate_timer_.stop(); } update_difference_particles(); From abd8fcf96713e0619aa9f09221d1188084632cc3 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Mon, 6 Jan 2025 18:16:06 -0700 Subject: [PATCH 18/22] previous regression tab logic --- Studio/Optimize/OptimizeTool.h | 3 --- 1 file changed, 3 deletions(-) diff --git a/Studio/Optimize/OptimizeTool.h b/Studio/Optimize/OptimizeTool.h index cab850aa3f2..30da28d10c2 100644 --- a/Studio/Optimize/OptimizeTool.h +++ b/Studio/Optimize/OptimizeTool.h @@ -38,8 +38,6 @@ Q_OBJECT; void load_params(); //! Store params to project - //! Get flag if regression needs to enabled for analysis in Studio - inline bool get_regression_analysis_status() { return regression_analysis_status_; } void store_params(); @@ -99,6 +97,5 @@ public Q_SLOTS: Ui_OptimizeTool* ui_; - bool regression_analysis_status_; }; } From ede45bd5fdd921e38a71918f7a070c1150466e1a Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Wed, 8 Jan 2025 11:58:17 -0700 Subject: [PATCH 19/22] more changes --- Libs/Particles/ParticleShapeStatistics.cpp | 1 + Libs/Particles/ParticleShapeStatistics.h | 1 - Studio/Analysis/AnalysisTool.cpp | 7 ++++--- Studio/Interface/ShapeWorksStudioApp.cpp | 8 -------- 4 files changed, 5 insertions(+), 12 deletions(-) diff --git a/Libs/Particles/ParticleShapeStatistics.cpp b/Libs/Particles/ParticleShapeStatistics.cpp index 979c70a3949..d35312248f0 100644 --- a/Libs/Particles/ParticleShapeStatistics.cpp +++ b/Libs/Particles/ParticleShapeStatistics.cpp @@ -497,6 +497,7 @@ ParticleShapeStatistics::ParticleShapeStatistics(std::shared_ptr projec Eigen::VectorXd ParticleShapeStatistics::compute_regression_mean( const std::vector& explanatory_variables) const { + std::cout << "Computing mean for regression" << std::endl; Eigen::VectorXd t = Eigen::Map( explanatory_variables.data(), explanatory_variables.size()); diff --git a/Libs/Particles/ParticleShapeStatistics.h b/Libs/Particles/ParticleShapeStatistics.h index ee3e9e6f8b8..2a1602b8060 100644 --- a/Libs/Particles/ParticleShapeStatistics.h +++ b/Libs/Particles/ParticleShapeStatistics.h @@ -159,7 +159,6 @@ class ParticleShapeStatistics { // for regression tasks Eigen::VectorXd slope_; Eigen::VectorXd intercept_; - bool regression_enabled_; std::vector percent_variance_by_mode_; Eigen::MatrixXd principals_; diff --git a/Studio/Analysis/AnalysisTool.cpp b/Studio/Analysis/AnalysisTool.cpp index befb5510899..e3bc097e2d1 100644 --- a/Studio/Analysis/AnalysisTool.cpp +++ b/Studio/Analysis/AnalysisTool.cpp @@ -713,7 +713,7 @@ bool AnalysisTool::compute_stats() { bool check_explanatory_variable_limits() { auto subjects = session_->get_project()->get_subjects(); - explanatory_variable_limits_.resize(2); + explanatory_variable_limits_.resize(2, 0.0); explanatory_variable_limits_[0] = std::numeric_limits::max(); explanatory_variable_limits_[1] = std::numeric_limits::lowest(); for (auto sub : subjects) { @@ -786,7 +786,7 @@ Particles AnalysisTool::get_shape_points(int mode, double value) { ui_->explained_variance->setText(""); ui_->cumulative_explained_variance->setText(""); } - auto mean = !regression_enabled_ ? stats_.get_mean() : stats_.compute_regression_mean(ui_->get_explanatory_variable_value()); + auto mean = !get_regression_analysis_status() ? stats_.get_mean() : stats_.compute_regression_mean(ui_->get_explanatory_variable_value()); temp_shape_ = mean + (e * (value * lambda)); auto positions = temp_shape_; @@ -1155,7 +1155,8 @@ double AnalysisTool::get_pca_value() { std::vector AnalysisTool::get_explanatory_variable_value() { int slider_value = ui_->explanatoryVariableSlider->value(); - return {t_min + (static_cast(slider_value) / 100.0) * (t_max - t_min)}; + // return {t_min + (static_cast(slider_value) / 100.0) * (t_max - t_min)}; + return {explanatory_variable_limits_[0] + (static_cast(slider_value) / 100.0) * (explanatory_variable_limits_[1] - explanatory_variable_limits_[0])}; } diff --git a/Studio/Interface/ShapeWorksStudioApp.cpp b/Studio/Interface/ShapeWorksStudioApp.cpp index b312dea14ee..bb0128c0a35 100644 --- a/Studio/Interface/ShapeWorksStudioApp.cpp +++ b/Studio/Interface/ShapeWorksStudioApp.cpp @@ -1528,14 +1528,6 @@ void ShapeWorksStudioApp::open_project(QString filename) { groom_tool_->load_params(); optimize_tool_->load_params(); - - if (optimize_tool_->get_regression_analysis_status()) - { - // Verify if slope and intercept files exist - // auto particles_dir = session_->get_filename().dir().absolutePath().toStdString(); - // auto slope_filename = session_->get_filename().toStdString(); - } - analysis_tool_->store_settings(); update_from_preferences(); update_tool_mode(); From d13ae70bc61561c55cf1fad10e2be184024e3c64 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Wed, 8 Jan 2025 12:01:48 -0700 Subject: [PATCH 20/22] code clean --- Libs/Particles/ParticleShapeStatistics.cpp | 1 + Studio/Analysis/AnalysisTool.cpp | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/Libs/Particles/ParticleShapeStatistics.cpp b/Libs/Particles/ParticleShapeStatistics.cpp index d35312248f0..f415567e3ca 100644 --- a/Libs/Particles/ParticleShapeStatistics.cpp +++ b/Libs/Particles/ParticleShapeStatistics.cpp @@ -495,6 +495,7 @@ ParticleShapeStatistics::ParticleShapeStatistics(std::shared_ptr projec // TODO: importing regression params doesn't make sense here. take a look again later. } +//--------------------------------------------------------------------------- Eigen::VectorXd ParticleShapeStatistics::compute_regression_mean( const std::vector& explanatory_variables) const { std::cout << "Computing mean for regression" << std::endl; diff --git a/Studio/Analysis/AnalysisTool.cpp b/Studio/Analysis/AnalysisTool.cpp index e3bc097e2d1..8db6755fa81 100644 --- a/Studio/Analysis/AnalysisTool.cpp +++ b/Studio/Analysis/AnalysisTool.cpp @@ -391,7 +391,6 @@ void AnalysisTool::handle_analysis_options() { ui_->pcaAnimateCheckBox->setEnabled(false); ui_->pcaModeSpinBox->setEnabled(false); pca_animate_timer_.stop(); - } update_difference_particles(); @@ -503,6 +502,7 @@ void AnalysisTool::network_analysis_clicked() { app_->get_py_worker()->run_job(network_analysis_job_); } +//--------------------------------------------------------------------------- Eigen::VectorXd load_regression_parameters(std::string filepath) { std::ifstream infile(slope_file_path); if (!infile.good()) { @@ -711,6 +711,7 @@ bool AnalysisTool::compute_stats() { return true; } +//--------------------------------------------------------------------------- bool check_explanatory_variable_limits() { auto subjects = session_->get_project()->get_subjects(); explanatory_variable_limits_.resize(2, 0.0); From 9e211ca08460d3a19175a147a9abfb7538c6eb85 Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Wed, 8 Jan 2025 12:05:50 -0700 Subject: [PATCH 21/22] code clean --- Studio/Analysis/AnalysisTool.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Studio/Analysis/AnalysisTool.cpp b/Studio/Analysis/AnalysisTool.cpp index 8db6755fa81..66406fe729b 100644 --- a/Studio/Analysis/AnalysisTool.cpp +++ b/Studio/Analysis/AnalysisTool.cpp @@ -655,6 +655,7 @@ bool AnalysisTool::compute_stats() { } can_run_regression_ = check_explanatory_variable_limits(); + std::cout << "can run regression set to " << can_run_regression_ << std::endl; if (can_run_regression_) { auto slope = load_regression_parameters( session_->get_regression_param_file("slope")); // dM vector @@ -888,10 +889,10 @@ ShapeHandle AnalysisTool::get_current_shape() { double pca_value = get_pca_value(); auto mca_level = get_mca_level(); if (mca_level == AnalysisTool::McaMode::Vanilla) { - return get_mode_shape(pca_mode, pca_value); - } else { - return get_mca_mode_shape(pca_mode, pca_value, mca_level); - } + return get_mode_shape(pca_mode, pca_value); + } else { + return get_mca_mode_shape(pca_mode, pca_value, mca_level); + } } //--------------------------------------------------------------------------- From fb5698bb2be9fdc2afc476c878ad73f44fad3d4f Mon Sep 17 00:00:00 2001 From: nawazishkhan1-nk Date: Wed, 8 Jan 2025 12:42:30 -0700 Subject: [PATCH 22/22] edits --- Studio/Analysis/AnalysisTool.cpp | 10 +++++++++- Studio/Analysis/AnalysisTool.h | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/Studio/Analysis/AnalysisTool.cpp b/Studio/Analysis/AnalysisTool.cpp index 66406fe729b..e3a3127bfd4 100644 --- a/Studio/Analysis/AnalysisTool.cpp +++ b/Studio/Analysis/AnalysisTool.cpp @@ -788,7 +788,7 @@ Particles AnalysisTool::get_shape_points(int mode, double value) { ui_->explained_variance->setText(""); ui_->cumulative_explained_variance->setText(""); } - auto mean = !get_regression_analysis_status() ? stats_.get_mean() : stats_.compute_regression_mean(ui_->get_explanatory_variable_value()); + auto mean = !get_regression_analysis_status() ? stats_.get_mean() : stats_.compute_regression_mean(get_explanatory_variable_value()); temp_shape_ = mean + (e * (value * lambda)); auto positions = temp_shape_; @@ -1054,6 +1054,13 @@ void AnalysisTool::on_pcaSlider_valueChanged() { Q_EMIT pca_update(); } +//--------------------------------------------------------------------------- +void AnalysisTool::on_explanatoryVariableSlider_valueChanged() { + // this will make the slider handle redraw making the UI appear more responsive + QCoreApplication::processEvents(); + Q_EMIT pca_update(); +} + //--------------------------------------------------------------------------- void AnalysisTool::on_group_slider_valueChanged() { // this will make the slider handle redraw making the UI appear more responsive @@ -1180,6 +1187,7 @@ void AnalysisTool::update_slider() { void AnalysisTool::reset_stats() { stats_ready_ = false; evals_ready_ = false; + can_run_regression_ = false; ui_->tabWidget->setCurrentWidget(ui_->mean_tab); ui_->allSamplesRadio->setChecked(true); diff --git a/Studio/Analysis/AnalysisTool.h b/Studio/Analysis/AnalysisTool.h index a2d853d7fa6..ae35bb53479 100644 --- a/Studio/Analysis/AnalysisTool.h +++ b/Studio/Analysis/AnalysisTool.h @@ -141,6 +141,7 @@ class AnalysisTool : public QWidget { // PCA void on_pcaSlider_valueChanged(); + void on_explanatoryVariableSlider_valueChanged(); void on_group_slider_valueChanged(); void on_pcaModeSpinBox_valueChanged(int i);