From 7f542c7940a3ddd8be3b27fe07f606e903ffd559 Mon Sep 17 00:00:00 2001 From: Xun Li Date: Sun, 6 Nov 2022 12:04:48 -0700 Subject: [PATCH] Fix bonferroni cutoff sigmap & conditonal cluster map (#2406) * if use custom inference, use num_cats (which could be less than) instead of def_cats.size() * fix conditional cluster map allow one dimension * Update version.h * Update install_name.py * fix conditional cluster map with time-enabled variable --- BuildTools/macosx/code_sign.py | 4 ++ BuildTools/macosx/install_name.py | 6 ++ Explore/AbstractClusterMap.cpp | 4 +- Explore/ConditionalClusterMapView.cpp | 91 ++++++++++++++++----------- Explore/GetisOrdMapNewView.cpp | 10 ++- Explore/LisaCoordinator.cpp | 18 ++++-- Explore/LisaMapNewView.cpp | 14 +++-- Explore/LocalGearyMapNewView.cpp | 8 ++- GenUtils.cpp | 11 ++++ GenUtils.h | 1 + version.h | 4 +- 11 files changed, 117 insertions(+), 54 deletions(-) diff --git a/BuildTools/macosx/code_sign.py b/BuildTools/macosx/code_sign.py index 6d8b39ee4..fd2a4f51d 100755 --- a/BuildTools/macosx/code_sign.py +++ b/BuildTools/macosx/code_sign.py @@ -12,6 +12,10 @@ def ProcessDependency(dylib_path, cid): if dylib_path == '@rpath/libgeos.3.11.0.dylib': dylib_path = '/opt/homebrew/opt/geos/lib/libgeos.3.11.0.dylib' + if dylib_path == '@loader_path/libicuuc.71.dylib': + dylib_path = '/opt/homebrew/opt/icu4c/lib/libicuuc.71.dylib' + if dylib_path == '@loader_path/libicudata.71.dylib': + dylib_path = '/opt/homebrew/opt/icu4c/lib/libicudata.71.dylib' print("Process:", dylib_path) #cmd = "codesign -f -s - " diff --git a/BuildTools/macosx/install_name.py b/BuildTools/macosx/install_name.py index 4abe6715f..5694f4159 100644 --- a/BuildTools/macosx/install_name.py +++ b/BuildTools/macosx/install_name.py @@ -17,12 +17,18 @@ def ProcessDependency(dir_path, dylib_name): # workaround for gdal 3.3.3 that @rpath/libgeos.3.10.2.dylib was used instead of dir path copyitem = item + if item == '@rpath/libgeos.3.10.2.dylib': + copyitem = '/usr/local/opt/geos/lib/libgeos.dylib' if item == '@rpath/libgeos.3.11.0.dylib': copyitem = '/usr/local/opt/geos/lib/libgeos.dylib' if item == '@loader_path/libicuuc.70.dylib': copyitem = '/usr/local/opt/icu4c/lib/libicuuc.70.dylib' + if item == '@loader_path/libicuuc.71.dylib': + copyitem = '/usr/local/opt/icu4c/lib/libicuuc.71.dylib' if item == '@loader_path/libicudata.70.dylib': copyitem = '/usr/local/opt/icu4c/lib/libicudata.70.dylib' + if item == '@loader_path/libicudata.71.dylib': + copyitem = '/usr/local/opt/icu4c/lib/libicudata.71.dylib' if item.startswith('/usr/lib') == False and item.startswith('/System') == False and (codesign_only or item.startswith('@executable_path/')==False): print("Process:", item) diff --git a/Explore/AbstractClusterMap.cpp b/Explore/AbstractClusterMap.cpp index f604a2c8a..cadc9be15 100644 --- a/Explore/AbstractClusterMap.cpp +++ b/Explore/AbstractClusterMap.cpp @@ -337,8 +337,8 @@ void AbstractMapCanvas::CreateAndUpdateCategories() } else if (cluster[i] == 6) { cat_data.AppendIdToCategory(t, undefined_cat, i); } else { - //cat_data.AppendIdToCategory(t, (sigCat[i]-s_f)+1, i); - for ( int c = def_cats.size()-1; c >= 0; c-- ) { + // if use custom inference, use num_cats instead of def_cats.size() + for ( int c = num_cats - 1; c >= 0; c-- ) { if ( p[i] <= def_cutoffs[c] ) { cat_data.AppendIdToCategory(t, level_cat_dict[c], i); break; diff --git a/Explore/ConditionalClusterMapView.cpp b/Explore/ConditionalClusterMapView.cpp index b0b422bd2..f7c4d23cc 100644 --- a/Explore/ConditionalClusterMapView.cpp +++ b/Explore/ConditionalClusterMapView.cpp @@ -1080,11 +1080,12 @@ void ConditionalLISAClusterMapCanvas::CreateAndUpdateCategories() cat_var_sorted.resize(num_time_vals); cat_var_undef.resize(num_time_vals); int lisa_time = lisa_coord->num_time_vals; - int lisa_t = 0; + int lisa_t = project->GetTimeState()->GetCurrTime(); for (int t=0; tGetClusterIndicators(lisa_t); for (int i=0; inum_time_vals; int num_obs = lisa_coord->num_obs; cat_data.CreateEmptyCategories(num_time_vals, num_obs); - lisa_t = 0; for (int t=0; tGetHasIsolates(lisa_t)) num_cats++; if (lisa_coord->GetHasUndefined(lisa_t)) @@ -1298,18 +1299,23 @@ void ConditionalGClusterMapCanvas::CreateAndUpdateCategories() // we do not allow smoothing with multiple time variables. cat_var_sorted.resize(num_time_vals); cat_var_undef.resize(num_time_vals); + int lisa_time = g_coord->num_time_vals; + int lisa_t = project->GetTimeState()->GetCurrTime(); for (int t=0; t cluster; - g_coord->FillClusterCats(t, is_gi, is_perm, cluster); + g_coord->FillClusterCats(lisa_t, is_gi, is_perm, cluster); for (int i=0; idata_undef[0][t][i]; + cat_var_undef[t][i] = g_coord->data_undef[0][lisa_t][i]; } } @@ -1341,10 +1347,11 @@ void ConditionalGClusterMapCanvas::CreateAndUpdateCategories() int isolates_cat = -1; int num_cats = 0; double stop_sig = 0; - - if (g_coord->GetHasIsolates(t)) + if (lisa_t < num_time -1) + lisa_t = t; + if (g_coord->GetHasIsolates(lisa_t)) num_cats++; - if (g_coord->GetHasUndefined(t)) + if (g_coord->GetHasUndefined(lisa_t)) num_cats++; num_cats += 3; @@ -1362,14 +1369,14 @@ void ConditionalGClusterMapCanvas::CreateAndUpdateCategories() cat_data.SetCategoryLabel(t, 2, _("Low")); cat_data.SetCategoryColor(t, 2, wxColour(0, 0, 255)); - if (g_coord->GetHasIsolates(t) && - g_coord->GetHasUndefined(t)) + if (g_coord->GetHasIsolates(lisa_t) && + g_coord->GetHasUndefined(lisa_t)) { isolates_cat = 3; undefined_cat = 4; - } else if (g_coord->GetHasUndefined(t)) { + } else if (g_coord->GetHasUndefined(lisa_t)) { undefined_cat = 3; - } else if (g_coord->GetHasIsolates(t)) { + } else if (g_coord->GetHasIsolates(lisa_t)) { isolates_cat = 3; } @@ -1383,7 +1390,7 @@ void ConditionalGClusterMapCanvas::CreateAndUpdateCategories() } vector cluster; - g_coord->FillClusterCats(t, is_gi, is_perm, cluster); + g_coord->FillClusterCats(lisa_t, is_gi, is_perm, cluster); for (int i=0, iend=g_coord->num_obs; inum_time_vals; + int lisa_t = project->GetTimeState()->GetCurrTime(); + for (int t=0; tcluster_vecs[t][i]; + cat_var_sorted[t][i].first = local_geary_coord->cluster_vecs[lisa_t][i]; cat_var_sorted[t][i].second = i; - cat_var_undef[t][i] = local_geary_coord->undef_data[0][t][i]; + cat_var_undef[t][i] = local_geary_coord->undef_data[0][lisa_t][i]; } } @@ -1551,10 +1563,11 @@ void ConditionalLocalGearyClusterMapCanvas::CreateAndUpdateCategories() int isolates_cat = -1; int num_cats = 0; double stop_sig = 0; + if (lisa_t < num_time -1) lisa_t = t; - if (local_geary_coord->GetHasIsolates(t)) + if (local_geary_coord->GetHasIsolates(lisa_t)) num_cats++; - if (local_geary_coord->GetHasUndefined(t)) + if (local_geary_coord->GetHasUndefined(lisa_t)) num_cats++; num_cats += 5; @@ -1578,13 +1591,13 @@ void ConditionalLocalGearyClusterMapCanvas::CreateAndUpdateCategories() cat_data.SetCategoryColor(t, 3, wxColour(253,219,199)); cat_data.SetCategoryLabel(t, 4, _("Negative")); cat_data.SetCategoryColor(t, 4, wxColour(103,173,199)); - if (local_geary_coord->GetHasIsolates(t) && - local_geary_coord->GetHasUndefined(t)) { + if (local_geary_coord->GetHasIsolates(lisa_t) && + local_geary_coord->GetHasUndefined(lisa_t)) { isolates_cat = 5; undefined_cat = 6; - } else if (local_geary_coord->GetHasUndefined(t)) { + } else if (local_geary_coord->GetHasUndefined(lisa_t)) { undefined_cat = 5; - } else if (local_geary_coord->GetHasIsolates(t)) { + } else if (local_geary_coord->GetHasIsolates(lisa_t)) { isolates_cat = 5; } @@ -1598,9 +1611,9 @@ void ConditionalLocalGearyClusterMapCanvas::CreateAndUpdateCategories() } double cuttoff = local_geary_coord->significance_cutoff; - double* p = local_geary_coord->sig_local_geary_vecs[t]; - int* cluster = local_geary_coord->cluster_vecs[t]; - int* sigCat = local_geary_coord->sig_cat_vecs[t]; + double* p = local_geary_coord->sig_local_geary_vecs[lisa_t]; + int* cluster = local_geary_coord->cluster_vecs[lisa_t]; + int* sigCat = local_geary_coord->sig_cat_vecs[lisa_t]; for (int i=0, iend=local_geary_coord->num_obs; i cuttoff && cluster[i] != 5 && cluster[i] != 6) { @@ -1725,15 +1738,20 @@ void ConditionalLocalJoinCountClusterMapCanvas::CreateAndUpdateCategories() cat_var_sorted.resize(num_time_vals); cat_var_undef.resize(num_time_vals); + int lisa_time = local_jc_coord->num_time_vals; + int lisa_t = project->GetTimeState()->GetCurrTime(); + for (int t=0; tlocal_jc_vecs[t][i]; + cat_var_sorted[t][i].first = local_jc_coord->local_jc_vecs[lisa_t][i]; cat_var_sorted[t][i].second = i; - cat_var_undef[t][i] = local_jc_coord->undef_tms[t][i]; + cat_var_undef[t][i] = local_jc_coord->undef_tms[lisa_t][i]; } } @@ -1765,10 +1783,11 @@ void ConditionalLocalJoinCountClusterMapCanvas::CreateAndUpdateCategories() int isolates_cat = -1; int num_cats = 0; double stop_sig = 0; - - if (local_jc_coord->GetHasIsolates(t)) + if (lisa_t < num_time -1) + lisa_t = t; + if (local_jc_coord->GetHasIsolates(lisa_t)) num_cats++; - if (local_jc_coord->GetHasUndefined(t)) + if (local_jc_coord->GetHasUndefined(lisa_t)) num_cats++; num_cats += 5; @@ -1790,13 +1809,13 @@ void ConditionalLocalJoinCountClusterMapCanvas::CreateAndUpdateCategories() cat_data.SetCategoryColor(t, 2, wxColour(0, 255, 0)); cat_data.SetCategoryLabel(t, 3, _("Colocation Cluster")); cat_data.SetCategoryColor(t, 3, wxColour(255,0,0)); - if (local_jc_coord->GetHasIsolates(t) && - local_jc_coord->GetHasUndefined(t)) { + if (local_jc_coord->GetHasIsolates(lisa_t) && + local_jc_coord->GetHasUndefined(lisa_t)) { isolates_cat = 4; undefined_cat = 5; - } else if (local_jc_coord->GetHasUndefined(t)) { + } else if (local_jc_coord->GetHasUndefined(lisa_t)) { undefined_cat = 4; - } else if (local_jc_coord->GetHasIsolates(t)) { + } else if (local_jc_coord->GetHasIsolates(lisa_t)) { isolates_cat = 4; } @@ -1810,9 +1829,9 @@ void ConditionalLocalJoinCountClusterMapCanvas::CreateAndUpdateCategories() } double cuttoff = local_jc_coord->significance_cutoff; - double* p = local_jc_coord->sig_local_jc_vecs[t]; + double* p = local_jc_coord->sig_local_jc_vecs[lisa_t]; std::vector cluster; - local_jc_coord->FillClusterCats(t,cluster); + local_jc_coord->FillClusterCats(lisa_t, cluster); for (int i=0, iend=local_jc_coord->num_obs; i cuttoff && cluster[i] != 4 && cluster[i] != 5) { diff --git a/Explore/GetisOrdMapNewView.cpp b/Explore/GetisOrdMapNewView.cpp index 373b4cf72..5f6070784 100644 --- a/Explore/GetisOrdMapNewView.cpp +++ b/Explore/GetisOrdMapNewView.cpp @@ -1059,8 +1059,14 @@ void GetisOrdMapFrame::OnSelectCoresAndNeighbors(wxCommandEvent& event) void GetisOrdMapFrame::OnShowAsConditionalMap(wxCommandEvent& event) { - VariableSettingsDlg dlg(project, VariableSettingsDlg::bivariate, - false, false, + int style = VariableSettingsDlg::ALLOW_STRING_IN_FIRST | VariableSettingsDlg::ALLOW_STRING_IN_SECOND | + VariableSettingsDlg::ALLOW_EMPTY_IN_FIRST | + VariableSettingsDlg::ALLOW_EMPTY_IN_SECOND; + + + VariableSettingsDlg dlg(project, + VariableSettingsDlg::bivariate, + style, _("Conditional G Cluster Map Variables"), _("Horizontal Cells"), _("Vertical Cells")); diff --git a/Explore/LisaCoordinator.cpp b/Explore/LisaCoordinator.cpp index 7c1a1d8a7..8ca6d5cd5 100644 --- a/Explore/LisaCoordinator.cpp +++ b/Explore/LisaCoordinator.cpp @@ -486,6 +486,9 @@ void LisaCoordinator::Calc() Gal_vecs[t] = gw; Gal_vecs_orig[t] = weights; + double reference_val = using_median + ? GenUtils::Median(data1, num_obs, undefs) : 0; + for (int i=0; i 0) { if (data1) { - if (data1[i] > 0 && Wdata < 0) cluster[i] = 4; - else if (data1[i] < 0 && Wdata > 0) cluster[i] = 3; - else if (data1[i] < 0 && Wdata < 0) cluster[i] = 2; - else cluster[i] = 1; //data1[i] > 0 && Wdata > 0 + if (data1[i] > reference_val && Wdata < reference_val) { + cluster[i] = 4; + } else if (data1[i] < reference_val && Wdata > reference_val) { + cluster[i] = 3; + } else if (data1[i] < reference_val && Wdata < reference_val) { + cluster[i] = 2; + } else { + cluster[i] = 1; //data1[i] > 0 && Wdata > 0 + } } } } diff --git a/Explore/LisaMapNewView.cpp b/Explore/LisaMapNewView.cpp index 91d3d52ea..afd1d44f8 100644 --- a/Explore/LisaMapNewView.cpp +++ b/Explore/LisaMapNewView.cpp @@ -338,12 +338,16 @@ void LisaMapFrame::OnSaveResult(wxCommandEvent& event) void LisaMapFrame::OnShowAsConditionalMap(wxCommandEvent& event) { - VariableSettingsDlg dlg(project, VariableSettingsDlg::bivariate, - false, false, + int style = VariableSettingsDlg::ALLOW_STRING_IN_FIRST | VariableSettingsDlg::ALLOW_STRING_IN_SECOND | + VariableSettingsDlg::ALLOW_EMPTY_IN_FIRST | + VariableSettingsDlg::ALLOW_EMPTY_IN_SECOND; + + VariableSettingsDlg dlg(project, + VariableSettingsDlg::bivariate, + style, _("Conditional LISA Map Variables"), - _("Horizontal Cells"), _("Vertical Cells"), - "", "", false, false, false, // default - true, true, false, false); + _("Horizontal Cells"), + _("Vertical Cells")); if (dlg.ShowModal() != wxID_OK) { return; diff --git a/Explore/LocalGearyMapNewView.cpp b/Explore/LocalGearyMapNewView.cpp index 0541897d0..1ce0bfcab 100644 --- a/Explore/LocalGearyMapNewView.cpp +++ b/Explore/LocalGearyMapNewView.cpp @@ -1127,9 +1127,13 @@ void LocalGearyMapFrame::OnSelectCoresAndNeighbors(wxCommandEvent& event) void LocalGearyMapFrame::OnShowAsConditionalMap(wxCommandEvent& event) { wxLogMessage("In LocalGearyMapFrame::OnShowAsConditionalMap"); + int style = VariableSettingsDlg::ALLOW_STRING_IN_FIRST | VariableSettingsDlg::ALLOW_STRING_IN_SECOND | + VariableSettingsDlg::ALLOW_EMPTY_IN_FIRST | + VariableSettingsDlg::ALLOW_EMPTY_IN_SECOND; - VariableSettingsDlg dlg(project, VariableSettingsDlg::bivariate, - false, false, + VariableSettingsDlg dlg(project, + VariableSettingsDlg::bivariate, + style, _("Conditional Local Geary Map Variables"), _("Horizontal Cells"), _("Vertical Cells")); diff --git a/GenUtils.cpp b/GenUtils.cpp index d649f2214..7027e4123 100644 --- a/GenUtils.cpp +++ b/GenUtils.cpp @@ -1331,6 +1331,17 @@ double GenUtils::Median(std::vector& data) return 0.5 * (data[n/2 -1] + data[n/2]); } +double GenUtils::Median(double* data, int n, const std::vector& undefs) +{ + std::vector valid_data; + for (int i = 0; i < n; ++i) { + if (!undefs[i]) { + valid_data.push_back(data[i]); + } + } + return Median(valid_data); +} + void GenUtils::DeviationFromMean(int nObs, double* data) { if (nObs == 0) return; diff --git a/GenUtils.h b/GenUtils.h index 8be4821e8..9f5580d5e 100644 --- a/GenUtils.h +++ b/GenUtils.h @@ -377,6 +377,7 @@ namespace GenUtils { double Sum(vector& data); double Median(std::vector& data); + double Median(double* data, int n, const std::vector& undefs); double SumOfSquares(vector& data); double SumOfSquaresMedian(vector& data); diff --git a/version.h b/version.h index 058eae2db..251595714 100644 --- a/version.h +++ b/version.h @@ -2,10 +2,10 @@ namespace Gda { const int version_major = 1; const int version_minor = 20; const int version_build = 0; - const int version_subbuild = 22; + const int version_subbuild = 24; const int version_year = 2022; const int version_month = 10; - const int version_day = 15; + const int version_day = 30; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release }