From 5109e6bbe0cd41d08fd15c4c2a14c6cf4ac601bb Mon Sep 17 00:00:00 2001 From: Xun Li Date: Sun, 8 Jan 2023 21:10:55 -0700 Subject: [PATCH] Fix conditional cluster map & issues with Bonferroni (#2407) --- Algorithms/tsne.cpp | 17 +- Algorithms/tsne.h | 4 +- BuildTools/macosx/GNUmakefile | 6 +- .../macosx/GeoDa.m1.xcodeproj/project.pbxproj | 2 +- BuildTools/macosx/code_sign.py | 23 +- BuildTools/macosx/install.sh | 2 +- BuildTools/macosx/install_name.py | 20 +- DialogTools/nbrMatchDlg.cpp | 16 +- DialogTools/nbrMatchDlg.h | 141 ++++----- DialogTools/quantileLisaDlg.cpp | 4 +- DialogTools/tSNEDlg.cpp | 2 +- Explore/AbstractClusterMap.cpp | 146 ++++----- Explore/AbstractClusterMap.h | 3 + Explore/AbstractCoordinator.cpp | 12 +- Explore/AbstractCoordinator.h | 7 + Explore/ConditionalClusterMapView.cpp | 134 ++++----- Explore/GStatCoordinator.cpp | 11 +- Explore/GStatCoordinator.h | 5 + Explore/GetisOrdMapNewView.cpp | 204 ++++++------- Explore/GetisOrdMapNewView.h | 3 + Explore/LisaCoordinator.cpp | 35 +-- Explore/LocalGearyCoordinator.cpp | 34 ++- Explore/LocalGearyCoordinator.h | 11 + Explore/LocalGearyMapNewView.cpp | 284 ++++++++---------- Explore/LocalGearyMapNewView.h | 3 + Explore/MLJCCoordinator.cpp | 9 +- Explore/MLJCCoordinator.h | 7 +- Explore/MLJCMapNewView.cpp | 235 ++++++--------- Explore/MLJCMapNewView.h | 13 +- Explore/PCPNewView.cpp | 104 ++++--- Explore/PCPNewView.h | 5 +- version.h | 4 +- 32 files changed, 720 insertions(+), 786 deletions(-) diff --git a/Algorithms/tsne.cpp b/Algorithms/tsne.cpp index 970dc0f4d..857960ae5 100755 --- a/Algorithms/tsne.cpp +++ b/Algorithms/tsne.cpp @@ -38,7 +38,7 @@ TSNE::TSNE(double* X, int N, int D, double* Y, int no_dims, double perplexity, double theta , int num_threads, int max_iter, int n_iter_early_exag, - int random_state, bool skip_random_init, int verbose, + unsigned int random_state, bool skip_random_init, int verbose, double early_exaggeration, double learning_rate, double *final_error) : X(X), N(N), D(D), Y(Y), no_dims(no_dims), perplexity(perplexity) , theta(theta), @@ -95,6 +95,14 @@ void TSNE::run(boost::lockfree::queue& tsne_queue, #endif #endif + if (skip_random_init != true) { + if(random_state >= 0) { + srand((unsigned int) random_state); + } else { + srand((unsigned int) time(NULL)); + } + } + /* ====================== Step 1 @@ -178,13 +186,6 @@ void TSNE::run(boost::lockfree::queue& tsne_queue, stop_lying_iter = 0; // Immediately stop lying. Passed Y is close to the true solution. } else { - if (skip_random_init != true) { - if(random_state >= 0) { - srand((unsigned int) random_state); - } else { - srand(time(NULL)); - } - } for (int i = 0; i < N * no_dims; i++) { Y[i] = randn(); } diff --git a/Algorithms/tsne.h b/Algorithms/tsne.h index 84176c5f8..2f681b123 100755 --- a/Algorithms/tsne.h +++ b/Algorithms/tsne.h @@ -27,7 +27,7 @@ class TSNE int no_dims = 2, double perplexity = 30, double theta = .5, int num_threads = 1, int max_iter = 1000, int n_iter_early_exag = 250, - int random_state = 0, bool init_from_Y = false, int verbose = 0, + unsigned int random_state = 0, bool init_from_Y = false, int verbose = 0, double early_exaggeration = 12, double learning_rate = 200, double *final_error = NULL); @@ -57,7 +57,7 @@ class TSNE int num_threads; int max_iter; int n_iter_early_exag; - int random_state; + unsigned int random_state; bool skip_random_init; int verbose; double early_exaggeration; diff --git a/BuildTools/macosx/GNUmakefile b/BuildTools/macosx/GNUmakefile index 3e194bc1d..695cb28d7 100644 --- a/BuildTools/macosx/GNUmakefile +++ b/BuildTools/macosx/GNUmakefile @@ -95,12 +95,12 @@ build-geoda-mac: cp /usr/local/opt/gdal/share/gdal/* build/GeoDa.app/Contents/Resources/gdaldata cp libraries/lib/libwx_osx_cocoau-3.1.4.0.0.dylib build/GeoDa.app/Contents/Frameworks/libwx_osx_cocoau-3.1.dylib cp libraries/lib/libwx_osx_cocoau_gl-3.1.4.0.0.dylib build/GeoDa.app/Contents/Frameworks/libwx_osx_cocoau_gl-3.1.dylib - cp /usr/local/opt/gdal/lib/libgdal.31.dylib build/GeoDa.app/Contents/Frameworks + cp /usr/local/opt/gdal/lib/libgdal.32.dylib build/GeoDa.app/Contents/Frameworks install_name_tool -id "GeoDa" build/GeoDa.app/Contents/MacOS/GeoDa install_name_tool -change "$(GEODA_HOME)/libraries/lib/libwx_osx_cocoau_gl-3.1.dylib" "@executable_path/../Frameworks/libwx_osx_cocoau_gl-3.1.dylib" build/GeoDa.app/Contents/MacOS/GeoDa install_name_tool -change "$(GEODA_HOME)/libraries/lib/libwx_osx_cocoau-3.1.dylib" "@executable_path/../Frameworks/libwx_osx_cocoau-3.1.dylib" build/GeoDa.app/Contents/MacOS/GeoDa - install_name_tool -change "/usr/local/opt/gdal/lib/libgdal.31.dylib" "@executable_path/../Frameworks/libgdal.31.dylib" build/GeoDa.app/Contents/MacOS/GeoDa - install_name_tool -change "/opt/homebrew/opt/gdal/lib/libgdal.31.dylib" "@executable_path/../Frameworks/libgdal.31.dylib" build/GeoDa.app/Contents/MacOS/GeoDa + install_name_tool -change "/usr/local/opt/gdal/lib/libgdal.32.dylib" "@executable_path/../Frameworks/libgdal.32.dylib" build/GeoDa.app/Contents/MacOS/GeoDa + install_name_tool -change "/opt/homebrew/opt/gdal/lib/libgdal.32.dylib" "@executable_path/../Frameworks/libgdal.32.dylib" build/GeoDa.app/Contents/MacOS/GeoDa python3 install_name.py $(GEODA_HOME)/build/GeoDa.app/Contents/Frameworks "Developer ID Application: Geodapress LLC (26M5NG43GP)" install_name_tool -change "@executable_path/../Frameworks/libwx_osx_cocoau-3.1.4.0.0.dylib" "@executable_path/../Frameworks/libwx_osx_cocoau-3.1.dylib" build/GeoDa.app/Contents/Frameworks/libwx_osx_cocoau_gl-3.1.dylib codesign -f --timestamp -o runtime -s "Developer ID Application: Geodapress LLC (26M5NG43GP)" build/GeoDa.app/Contents/Frameworks/libwx_osx_cocoau_gl-3.1.dylib diff --git a/BuildTools/macosx/GeoDa.m1.xcodeproj/project.pbxproj b/BuildTools/macosx/GeoDa.m1.xcodeproj/project.pbxproj index fa159cbd3..e12be510b 100644 --- a/BuildTools/macosx/GeoDa.m1.xcodeproj/project.pbxproj +++ b/BuildTools/macosx/GeoDa.m1.xcodeproj/project.pbxproj @@ -1897,7 +1897,7 @@ ); runOnlyForDeploymentPostprocessing = 0; shellPath = /bin/sh; - shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n#python3 install_name.py $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks\nif [ \"${CONFIGURATION}\" = \"Debug\" ]; then\n codesign -f -s \"Apple Development: xunli@uchicago.edu (AN5USPSZF6)\" /opt/homebrew/opt/gdal/lib/libgdal.31.dylib\n codesign -f -s \"Apple Development: xunli@uchicago.edu (AN5USPSZF6)\" /opt/homebrew/Cellar/openssl@1.1/1.1.1o/lib/libcrypto.1.1.dylib\n codesign -f -s \"Apple Development: xunli@uchicago.edu (AN5USPSZF6)\" /Users/xun/github/geoda/BuildTools/macosx/libraries/lib/libwx_osx_cocoau-3.1.4.0.0.dylib\n codesign -f -s \"Apple Development: xunli@uchicago.edu (AN5USPSZF6)\" /Users/xun/github/geoda/BuildTools/macosx/libraries/lib/libwx_osx_cocoau_gl-3.1.4.0.0.dylib\n #install_name_tool -change \"@rpath/libgeos.3.10.1.dylib\" \"/opt/homebrew/opt/geos/lib/libgeos.3.10.1.dylib\" /opt/homebrew/Cellar/geos/3.10.1/lib/libgeos_c.1.16.0.dylib\n #codesign -f -s \"Apple Development: xunli@uchicago.edu (AN5USPSZF6)\" /opt/homebrew/Cellar/geos/3.10.1/lib/libgeos_c.1.16.0.dylib\nelse\n mkdir $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks\n cp /Users/xun/github/geoda/BuildTools/macosx/libraries/lib/libwx_osx_cocoau-3.1.4.0.0.dylib $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/libwx_osx_cocoau-3.1.dylib\n cp /Users/xun/github/geoda/BuildTools/macosx/libraries/lib/libwx_osx_cocoau_gl-3.1.4.0.0.dylib $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/libwx_osx_cocoau_gl-3.1.dylib\n cp /usr/local/opt/gdal/lib/libgdal.29.dylib $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/libgdal.29.dylib\n install_name_tool -id \"GeoDa\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/GeoDa\n install_name_tool -change \"/Users/xun/github/geoda/BuildTools/macosx/libraries/lib/libwx_osx_cocoau_gl-3.1.dylib\" \"@executable_path/../Frameworks/libwx_osx_cocoau_gl-3.1.dylib\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/GeoDa\n install_name_tool -change \"/Users/xun/github/geoda/BuildTools/macosx/libraries/lib/libwx_osx_cocoau-3.1.dylib\" \"@executable_path/../Frameworks/libwx_osx_cocoau-3.1.dylib\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/GeoDa\n install_name_tool -change \"/usr/local/opt/gdal/lib/libgdal.29.dylib\" \"@executable_path/../Frameworks/libgdal.29.dylib\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/GeoDa\n install_name_tool -change \"/opt/homebrew/opt/gdal/lib/libgdal.29.dylib\" \"@executable_path/../Frameworks/libgdal.29.dylib\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/GeoDa\n python3 install_name.py $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks \"0046C0AE0D6933F7CD8A67875F820AF13CD63439\"\n codesign -f --timestamp -o runtime -s \"0046C0AE0D6933F7CD8A67875F820AF13CD63439\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/GeoDa\n codesign -f --timestamp -o runtime -s \"0046C0AE0D6933F7CD8A67875F820AF13CD63439\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app\nfi\n"; + shellScript = "# Type a script or drag a script file from your workspace to insert its path.\n#python3 install_name.py $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks\nif [ \"${CONFIGURATION}\" = \"Debug\" ]; then\n codesign -f -s \"Apple Development: xunli@uchicago.edu (AN5USPSZF6)\" /opt/homebrew/opt/gdal/lib/libgdal.32.dylib\n codesign -f -s \"Apple Development: xunli@uchicago.edu (AN5USPSZF6)\" /opt/homebrew/Cellar/openssl@1.1/1.1.1o/lib/libcrypto.1.1.dylib\n codesign -f -s \"Apple Development: xunli@uchicago.edu (AN5USPSZF6)\" /Users/xun/github/geoda/BuildTools/macosx/libraries/lib/libwx_osx_cocoau-3.1.4.0.0.dylib\n codesign -f -s \"Apple Development: xunli@uchicago.edu (AN5USPSZF6)\" /Users/xun/github/geoda/BuildTools/macosx/libraries/lib/libwx_osx_cocoau_gl-3.1.4.0.0.dylib\n #install_name_tool -change \"@rpath/libgeos.3.10.1.dylib\" \"/opt/homebrew/opt/geos/lib/libgeos.3.10.1.dylib\" /opt/homebrew/Cellar/geos/3.10.1/lib/libgeos_c.1.16.0.dylib\n #codesign -f -s \"Apple Development: xunli@uchicago.edu (AN5USPSZF6)\" /opt/homebrew/Cellar/geos/3.10.1/lib/libgeos_c.1.16.0.dylib\nelse\n mkdir $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks\n cp /Users/xun/github/geoda/BuildTools/macosx/libraries/lib/libwx_osx_cocoau-3.1.4.0.0.dylib $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/libwx_osx_cocoau-3.1.dylib\n cp /Users/xun/github/geoda/BuildTools/macosx/libraries/lib/libwx_osx_cocoau_gl-3.1.4.0.0.dylib $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/libwx_osx_cocoau_gl-3.1.dylib\n cp /usr/local/opt/gdal/lib/libgdal.29.dylib $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks/libgdal.29.dylib\n install_name_tool -id \"GeoDa\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/GeoDa\n install_name_tool -change \"/Users/xun/github/geoda/BuildTools/macosx/libraries/lib/libwx_osx_cocoau_gl-3.1.dylib\" \"@executable_path/../Frameworks/libwx_osx_cocoau_gl-3.1.dylib\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/GeoDa\n install_name_tool -change \"/Users/xun/github/geoda/BuildTools/macosx/libraries/lib/libwx_osx_cocoau-3.1.dylib\" \"@executable_path/../Frameworks/libwx_osx_cocoau-3.1.dylib\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/GeoDa\n install_name_tool -change \"/usr/local/opt/gdal/lib/libgdal.29.dylib\" \"@executable_path/../Frameworks/libgdal.29.dylib\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/GeoDa\n install_name_tool -change \"/opt/homebrew/opt/gdal/lib/libgdal.29.dylib\" \"@executable_path/../Frameworks/libgdal.29.dylib\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/GeoDa\n python3 install_name.py $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/Frameworks \"0046C0AE0D6933F7CD8A67875F820AF13CD63439\"\n codesign -f --timestamp -o runtime -s \"0046C0AE0D6933F7CD8A67875F820AF13CD63439\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app/Contents/MacOS/GeoDa\n codesign -f --timestamp -o runtime -s \"0046C0AE0D6933F7CD8A67875F820AF13CD63439\" $TARGET_BUILD_DIR/$PRODUCT_NAME.app\nfi\n"; }; /* End PBXShellScriptBuildPhase section */ diff --git a/BuildTools/macosx/code_sign.py b/BuildTools/macosx/code_sign.py index fd2a4f51d..55d6e122f 100755 --- a/BuildTools/macosx/code_sign.py +++ b/BuildTools/macosx/code_sign.py @@ -1,5 +1,5 @@ import subprocess -import os, sys +import os, sys, re from shutil import copyfile processed_items = {} @@ -10,12 +10,30 @@ def ProcessDependency(dylib_path, cid): else: processed_items[dylib_path] = True + if dylib_path == '@rpath/libgeos.3.11.1.dylib': + dylib_path = '/opt/homebrew/opt/geos/lib/libgeos.3.11.1.dylib' 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' + if dylib_path == '@loader_path/libbrotlicommon.1.dylib': + dylib_path = '/opt/homebrew/opt/brotli/lib/libbrotlicommon.1.dylib' + + if dylib_path == '@rpath/libIlmThread-3_1.30.dylib': + dylib_path = '/usr/local/opt/openexr/lib/libIlmThread-3_1.30.dylib' + if dylib_path == '@rpath/libIex-3_1.30.dylib': + dylib_path = '/usr/local/opt/openexr/lib/libIex-3_1.30.dylib' + if dylib_path == '@rpath/libOpenEXR-3_1.30.dylib': + dylib_path = '/usr/local/opt/openexr/lib/libOpenEXR-3_1.30.dylib' + if dylib_path == '@rpath/libOpenEXRCore-3_1.30.dylib': + dylib_path = '/usr/local/opt/openexr/lib/libOpenEXRCore-3_1.30.dylib' + + m = re.search('@rpath/(libaws.*)', dylib_path) + if m: + dylib_path = '/usr/local/opt/aws-sdk-cpp/lib/' + m.group(1) + print("Process:", dylib_path) #cmd = "codesign -f -s - " @@ -32,4 +50,5 @@ def ProcessDependency(dylib_path, cid): # e.g. # python3 code_sign.py /opt/homebrew/opt/gdal/lib/libgdal.29.dylib "Apple Development: xunli@uchicago.edu (AN5USPSZF6)" -ProcessDependency(sys.argv[1], sys.argv[2]) \ No newline at end of file +# python3 code_sign.py /opt/homebrew/opt/gdal/lib/libgdal.32.dylib "Apple Development: xunli@uchicago.edu (AN5USPSZF6)" +ProcessDependency(sys.argv[1], sys.argv[2]) diff --git a/BuildTools/macosx/install.sh b/BuildTools/macosx/install.sh index a182da705..c6ddbde0e 100755 --- a/BuildTools/macosx/install.sh +++ b/BuildTools/macosx/install.sh @@ -10,7 +10,7 @@ CPUS=2 # Install boost 1.75 brew install boost -# Install libgdal 3.3 +# Install libgdal 3.6 brew install gdal cd $GEODA_HOME diff --git a/BuildTools/macosx/install_name.py b/BuildTools/macosx/install_name.py index 5694f4159..8138146ab 100644 --- a/BuildTools/macosx/install_name.py +++ b/BuildTools/macosx/install_name.py @@ -1,5 +1,5 @@ import subprocess -import os, sys +import os, sys, re from shutil import copyfile framework_path = sys.argv[1] #e.g. '/Users/xun/Github/geoda/BuildTools/macosx/build/GeoDa.app/Contents/Frameworks' @@ -21,6 +21,8 @@ def ProcessDependency(dir_path, dylib_name): 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 == '@rpath/libgeos.3.11.1.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': @@ -29,6 +31,20 @@ def ProcessDependency(dir_path, dylib_name): 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 == '@loader_path/libbrotlicommon.1.dylib': + copyitem = '/usr/local/opt/brotli/lib/libbrotlicommon.1.dylib' + if item == '@rpath/libIlmThread-3_1.30.dylib': + copyitem = '/usr/local/opt/openexr/lib/libIlmThread-3_1.30.dylib' + if item == '@rpath/libIex-3_1.30.dylib': + copyitem = '/usr/local/opt/openexr/lib/libIex-3_1.30.dylib' + if item == '@rpath/libOpenEXR-3_1.30.dylib': + copyitem = '/usr/local/opt/openexr/lib/libOpenEXR-3_1.30.dylib' + if item == '@rpath/libOpenEXRCore-3_1.30.dylib': + copyitem = '/usr/local/opt/openexr/lib/libOpenEXRCore-3_1.30.dylib' + + m = re.search('@rpath/(libaws.*)', item) + if m: + copyitem = '/usr/local/opt/aws-sdk-cpp/lib/' + m.group(1) if item.startswith('/usr/lib') == False and item.startswith('/System') == False and (codesign_only or item.startswith('@executable_path/')==False): print("Process:", item) @@ -51,4 +67,4 @@ def ProcessDependency(dir_path, dylib_name): ProcessDependency(framework_path, "libwx_osx_cocoau_gl-3.1.dylib") ProcessDependency(framework_path, "libwx_osx_cocoau-3.1.dylib") -ProcessDependency(framework_path, "libgdal.31.dylib") +ProcessDependency(framework_path, "libgdal.32.dylib") diff --git a/DialogTools/nbrMatchDlg.cpp b/DialogTools/nbrMatchDlg.cpp index ff5f6f072..e887007f5 100644 --- a/DialogTools/nbrMatchDlg.cpp +++ b/DialogTools/nbrMatchDlg.cpp @@ -1034,7 +1034,8 @@ void LocalMatchCoordinator::job(size_t nbr_sz, size_t idx, uint64_t seed_start) // compute pseudo-p-value sigVal[idx] = (countLarger + 1.0)/(permutations+1); - if (sigVal[idx] <= 0.0001) sigCat[idx] = 4; + if (sigVal[idx] <= 0.00001) sigCat[idx] = 5; + else if (sigVal[idx] <= 0.0001) sigCat[idx] = 4; else if (sigVal[idx] <= 0.001) sigCat[idx] = 3; else if (sigVal[idx] <= 0.01) sigCat[idx] = 2; else if (sigVal[idx] <= 0.05) sigCat[idx]= 1; @@ -1061,12 +1062,13 @@ void LocalMatchCoordinator::SetSignificanceFilter(int filter_id) return; } // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 - if (filter_id < 1 || filter_id > 4) return; + if (filter_id < 1 || filter_id > 5) return; significance_filter = filter_id; if (filter_id == 1) significance_cutoff = 0.05; if (filter_id == 2) significance_cutoff = 0.01; if (filter_id == 3) significance_cutoff = 0.001; if (filter_id == 4) significance_cutoff = 0.0001; + if (filter_id == 5) significance_cutoff = 0.00001; wxLogMessage("Exiting AbstractCoordinator::SetSignificanceFilter()"); } @@ -1077,6 +1079,7 @@ std::vector LocalMatchCoordinator::GetDefaultCategories() cats.push_back("p = 0.01"); cats.push_back("p = 0.001"); cats.push_back("p = 0.0001"); + cats.push_back("p = 0.00001"); return cats; } @@ -1087,6 +1090,7 @@ std::vector LocalMatchCoordinator::GetDefaultCutoffs() cutoffs.push_back(0.01); cutoffs.push_back(0.001); cutoffs.push_back(0.0001); + cutoffs.push_back(0.00001); return cutoffs; } @@ -1287,8 +1291,8 @@ void LocalMatchSignificanceCanvas::CreateAndUpdateCategories() int set_perm = gs_coord->permutations; stop_sig = 1.0 / (1.0 + set_perm); - wxString def_cats[4] = {str_p005, str_p001, str_p0001, str_p00001}; - double def_cutoffs[4] = {0.05, 0.01, 0.001, 0.0001}; + wxString def_cats[5] = {str_p005, str_p001, str_p0001, str_p00001, str_p000001}; + double def_cutoffs[5] = {0.05, 0.01, 0.001, 0.0001, 0.00001}; int cat_idx = 1; for (int j=s_f-1; j < 4; j++) { @@ -1314,7 +1318,9 @@ void LocalMatchSignificanceCanvas::CreateAndUpdateCategories() } else { int s_f = gs_coord->GetSignificanceFilter(); for (int i=0, iend=gs_coord->num_obs; i #include #include - + #include "../ShapeOperations/OGRDataAdapter.h" #include "../DataViewer/TableInterface.h" #include "../VarTools.h" @@ -83,7 +83,7 @@ class LocalMatchMapCanvas : public MapCanvas public: LocalMatchMapCanvas(wxWindow *parent, TemplateFrame* t_frame, Project* project, - const std::vector >& groups, + const std::vector >& groups, const std::vector& pval, boost::uuids::uuid weights_id, const wxPoint& pos = wxDefaultPosition, @@ -100,7 +100,7 @@ class LocalMatchMapCanvas : public MapCanvas virtual void TimeSyncVariableToggle(int var_index); virtual void UpdateStatusBar(); - std::vector > groups; + std::vector > groups; std::vector pval; DECLARE_EVENT_TABLE() @@ -111,7 +111,7 @@ class LocalMatchMapFrame : public MapFrame DECLARE_CLASS(LocalMatchMapFrame) public: LocalMatchMapFrame(wxFrame *parent, Project* project, - const std::vector >& groups, + const std::vector >& groups, const std::vector& pval, boost::uuids::uuid weights_id = boost::uuids::nil_uuid(), const wxString& title = wxEmptyString, @@ -129,73 +129,73 @@ class LocalMatchMapFrame : public MapFrame boost::uuids::uuid weights_id; DECLARE_EVENT_TABLE() -}; +}; + + + +class LocalMatchCoordinator +{ +public: + LocalMatchCoordinator(GwtWeight* spatial_w, GalWeight* variable_w, + const std::vector& cadinality, + int permutations, + uint64_t last_seed_used, + bool reuse_last_seed=false); + virtual ~LocalMatchCoordinator(); + + bool IsOk() { return true; } + wxString GetErrorMessage() { return "Error Message"; } + + void run(); + void job(size_t nbr_sz, size_t idx, uint64_t seed_start); + + int num_obs; + GwtWeight* spatial_w; + GalWeight* variable_w; + std::vector sigVal; + std::vector sigCat; + std::vector cadinality; + + int significance_filter; // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 + double significance_cutoff; // either 0.05, 0.01, 0.001 or 0.0001 + void SetSignificanceFilter(int filter_id); + int GetSignificanceFilter() { return significance_filter; } + int permutations; // any number from 9 to 99999, 99 will be default + double bo; //Bonferroni bound + double fdr; //False Discovery Rate + double user_sig_cutoff; // user defined cutoff + uint64_t last_seed_used; + bool reuse_last_seed; + + uint64_t GetLastUsedSeed() { return last_seed_used;} + + void SetLastUsedSeed(uint64_t seed) { + reuse_last_seed = true; + last_seed_used = seed; + // update global one + GdaConst::use_gda_user_seed = true; + OGRDataAdapter::GetInstance().AddEntry("use_gda_user_seed", "1"); + GdaConst::gda_user_seed = last_seed_used; + wxString val; + val << last_seed_used; + OGRDataAdapter::GetInstance().AddEntry("gda_user_seed", val); + } - + bool IsReuseLastSeed() { return reuse_last_seed; } + void SetReuseLastSeed(bool reuse) { + reuse_last_seed = reuse; + // update global one + GdaConst::use_gda_user_seed = reuse; + if (reuse) { + last_seed_used = GdaConst::gda_user_seed; + OGRDataAdapter::GetInstance().AddEntry("use_gda_user_seed", "1"); + } else { + OGRDataAdapter::GetInstance().AddEntry("use_gda_user_seed", "0"); + } + } -class LocalMatchCoordinator -{ -public: - LocalMatchCoordinator(GwtWeight* spatial_w, GalWeight* variable_w, - const std::vector& cadinality, - int permutations, - uint64_t last_seed_used, - bool reuse_last_seed=false); - virtual ~LocalMatchCoordinator(); - - bool IsOk() { return true; } - wxString GetErrorMessage() { return "Error Message"; } - - void run(); - void job(size_t nbr_sz, size_t idx, uint64_t seed_start); - - int num_obs; - GwtWeight* spatial_w; - GalWeight* variable_w; - std::vector sigVal; - std::vector sigCat; - std::vector cadinality; - - int significance_filter; // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 - double significance_cutoff; // either 0.05, 0.01, 0.001 or 0.0001 - void SetSignificanceFilter(int filter_id); - int GetSignificanceFilter() { return significance_filter; } - int permutations; // any number from 9 to 99999, 99 will be default - double bo; //Bonferroni bound - double fdr; //False Discovery Rate - double user_sig_cutoff; // user defined cutoff - uint64_t last_seed_used; - bool reuse_last_seed; - - uint64_t GetLastUsedSeed() { return last_seed_used;} - - void SetLastUsedSeed(uint64_t seed) { - reuse_last_seed = true; - last_seed_used = seed; - // update global one - GdaConst::use_gda_user_seed = true; - OGRDataAdapter::GetInstance().AddEntry("use_gda_user_seed", "1"); - GdaConst::gda_user_seed = last_seed_used; - wxString val; - val << last_seed_used; - OGRDataAdapter::GetInstance().AddEntry("gda_user_seed", val); - } - - bool IsReuseLastSeed() { return reuse_last_seed; } - void SetReuseLastSeed(bool reuse) { - reuse_last_seed = reuse; - // update global one - GdaConst::use_gda_user_seed = reuse; - if (reuse) { - last_seed_used = GdaConst::gda_user_seed; - OGRDataAdapter::GetInstance().AddEntry("use_gda_user_seed", "1"); - } else { - OGRDataAdapter::GetInstance().AddEntry("use_gda_user_seed", "0"); - } - } - - virtual std::vector GetDefaultCategories(); - virtual std::vector GetDefaultCutoffs(); + virtual std::vector GetDefaultCategories(); + virtual std::vector GetDefaultCutoffs(); }; @@ -240,6 +240,9 @@ class LocalMatchSignificanceCanvas : public MapCanvas wxString str_p001; wxString str_p0001; wxString str_p00001; + wxString str_p000001; + + const static int NUM_SIG_CATS = 5; DECLARE_EVENT_TABLE() }; diff --git a/DialogTools/quantileLisaDlg.cpp b/DialogTools/quantileLisaDlg.cpp index d48c733e7..0a00931e0 100644 --- a/DialogTools/quantileLisaDlg.cpp +++ b/DialogTools/quantileLisaDlg.cpp @@ -311,8 +311,10 @@ void QuantileLisaDlg::OnOK(wxCommandEvent& event ) var_info[0].sync_with_global_time = false; var_info[0].fixed_scale = true; + bool is_quantile_lisa = true; + JCCoordinator* lc = new JCCoordinator(w_id, project, var_info, col_ids); - MLJCMapFrame *sf = new MLJCMapFrame(parent, project, lc, false); + MLJCMapFrame *sf = new MLJCMapFrame(parent, project, lc, false, is_quantile_lisa); wxString ttl = _("Quantile LISA Map (%s, # of quantiles=%d, select quantile=%d)"); ttl = wxString::Format(ttl, var_name, n_quantiles, sel_quantile); diff --git a/DialogTools/tSNEDlg.cpp b/DialogTools/tSNEDlg.cpp index 055243e83..a45577f2c 100644 --- a/DialogTools/tSNEDlg.cpp +++ b/DialogTools/tSNEDlg.cpp @@ -695,7 +695,7 @@ void TSNEDlg::OnOK(wxCommandEvent& event ) } tsne = new TSNE(data, rows, columns, Y, new_col, perplexity, theta, num_threads, max_iteration, (int)mom_switch_iter, - (int)GdaConst::gda_user_seed, !GdaConst::use_gda_user_seed, + (unsigned int)GdaConst::gda_user_seed, !GdaConst::use_gda_user_seed, verbose, early_exaggeration, learningrate, &final_cost); int idx = 100 - m_speed_slider->GetValue(); tsne->set_speed(idx); diff --git a/Explore/AbstractClusterMap.cpp b/Explore/AbstractClusterMap.cpp index cadc9be15..65fc898cf 100644 --- a/Explore/AbstractClusterMap.cpp +++ b/Explore/AbstractClusterMap.cpp @@ -69,6 +69,7 @@ str_p005("p = 0.05"), str_p001("p = 0.01"), str_p0001("p = 0.001"), str_p00001("p = 0.0001"), +str_p000001("p = 0.00001"), clr_not_sig_point(wxColour(190, 190, 190)), clr_not_sig_polygon(wxColour(240, 240, 240)) { @@ -81,6 +82,7 @@ clr_not_sig_polygon(wxColour(240, 240, 240)) SetPredefinedColor(str_p001, wxColour(6, 196, 11)); SetPredefinedColor(str_p0001, wxColour(3, 116, 6)); SetPredefinedColor(str_p00001, wxColour(1, 70, 3)); + SetPredefinedColor(str_p000001, wxColour(0, 50, 2)); cat_classif_def.cat_classif_type = theme_type_s; // must set var_info times from AbstractCoordinator initially @@ -210,37 +212,13 @@ void AbstractMapCanvas::CreateAndUpdateCategories() std::vector def_cutoffs = a_coord->GetDefaultCutoffs(); bool is_cust_cutoff = true; - for (int i=0; i<4; i++) { + for (int i=0; i 0.05 ) { - def_cutoffs[0] = sig_cutoff; - lbl_color_dict[lbl] = lbl_color_dict[def_cats[0]]; - def_cats[0] = lbl; - } else { - for (int i = 1; i < 4; i++) { - if (def_cutoffs[i-1] + def_cutoffs[i] < 2 * sig_cutoff){ - lbl_color_dict[lbl] = lbl_color_dict[def_cats[i-1]]; - def_cutoffs[i-1] = sig_cutoff; - def_cats[i-1] = lbl; - break; - } else { - lbl_color_dict[lbl] = lbl_color_dict[def_cats[i]]; - def_cutoffs[i] = sig_cutoff; - def_cats[i] = lbl; - break; - } - } - } - } - for (int t=0; t0.05 (Not sig) 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 - num_cats = 5; - if ( has_isolates ) { - num_cats++; - } - if ( has_undefined ) { - num_cats++; - } - for (int j=0; j < def_cats.size(); j++) { - if (sig_cutoff < def_cutoffs[j]) - num_cats -= 1; - } - // issue #474 only show significance levels that can - // be mapped for the given number of permutations, - // e.g., for 99 it would stop at 0.01, for 999 at 0.001, etc. - if ( sig_cutoff >= def_cutoffs[3] && stop_sig > def_cutoffs[3] ) { - //0.0001 - num_cats -= 1; - } - if ( sig_cutoff >= def_cutoffs[2] && stop_sig > def_cutoffs[2] ) { - //0.001 - num_cats -= 1; - } - if ( sig_cutoff >= def_cutoffs[1] && stop_sig > def_cutoffs[1] ) { - //0.01 - num_cats -= 1; + // 0: >0.05 (Not sig) 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001, 5: 0.00001 + num_cats += 1; // not sig category + + if (is_cust_cutoff) { + num_cats += 1; + } else { + for (int j=0; j < NUM_SIG_CATS; j++) { + if (sig_cutoff >= def_cutoffs[j] && stop_sig <= def_cutoffs[j]) { + num_cats += 1; + } + } } cat_data.CreateCategoriesAtCanvasTm(num_cats, t); + int cat_idx = 0; + // set not sigificant category wxColour not_sig_clr = clr_not_sig_polygon; if (project->IsPointTypeData()) not_sig_clr = clr_not_sig_point; - cat_data.SetCategoryColor(t, 0, not_sig_clr); - cat_data.SetCategoryLabel(t, 0, str_not_sig); - - int cat_idx = 1; + cat_data.SetCategoryColor(t, cat_idx, not_sig_clr); + cat_data.SetCategoryLabel(t, cat_idx, str_not_sig); + cat_idx += 1; + std::map level_cat_dict; - for (int j=0; j < def_cats.size(); j++) { - if (sig_cutoff >= def_cutoffs[j] && def_cutoffs[j] >= stop_sig) { - cat_data.SetCategoryColor(t, cat_idx, lbl_color_dict[def_cats[j]]); - cat_data.SetCategoryLabel(t, cat_idx, def_cats[j]); - level_cat_dict[j] = cat_idx; - cat_idx += 1; + + if (is_cust_cutoff) { + std::ostringstream ss_sig_cutoff; + ss_sig_cutoff << std::fixed << sig_cutoff; + wxString lbl = wxString::Format("p = %s", ss_sig_cutoff.str()); + + cat_data.SetCategoryColor(t, cat_idx, lbl_color_dict[def_cats[0]]); + cat_data.SetCategoryLabel(t, cat_idx, lbl); + cat_idx += 1; + } else { + for (int j=0; j < NUM_SIG_CATS; j++) { + if (sig_cutoff >= def_cutoffs[j] && stop_sig <= def_cutoffs[j]) { + level_cat_dict[j] = cat_idx; + cat_data.SetCategoryColor(t, cat_idx, lbl_color_dict[def_cats[j]]); + cat_data.SetCategoryLabel(t, cat_idx, def_cats[j]); + cat_idx += 1; + } } } - if (has_isolates && has_undefined) { - isolates_cat = cat_idx++; - undefined_cat = cat_idx++; - - } else if (has_undefined) { - undefined_cat = cat_idx++; - - } else if (has_isolates) { + if (has_isolates) { isolates_cat = cat_idx++; + cat_data.SetCategoryLabel(t, isolates_cat, str_neighborless); + cat_data.SetCategoryColor(t, isolates_cat, lbl_color_dict[str_neighborless]); } - - if (undefined_cat != -1) { + if (has_undefined) { + undefined_cat = cat_idx++; cat_data.SetCategoryLabel(t, undefined_cat, str_undefined); cat_data.SetCategoryColor(t, undefined_cat, lbl_color_dict[str_undefined]); } - if (isolates_cat != -1) { - cat_data.SetCategoryLabel(t, isolates_cat, str_neighborless); - cat_data.SetCategoryColor(t, isolates_cat, lbl_color_dict[str_neighborless]); - } + + int not_sig_cat = 0; + for (int i=0; i sig_cutoff && cluster[i] != 5 && cluster[i] != 6) { - cat_data.AppendIdToCategory(t, 0, i); // not significant - } else if (cluster[i] == 5) { + if (p[i] > sig_cutoff + && cluster[i] != AbstractCoordinator::NEIGHBORLESS_CLUSTER + && cluster[i] != AbstractCoordinator::UNDEFINED_CLUSTER + ) { + cat_data.AppendIdToCategory(t, not_sig_cat, i); // not significant + } else if (cluster[i] == AbstractCoordinator::NEIGHBORLESS_CLUSTER) { cat_data.AppendIdToCategory(t, isolates_cat, i); - } else if (cluster[i] == 6) { + } else if (cluster[i] == AbstractCoordinator::UNDEFINED_CLUSTER) { cat_data.AppendIdToCategory(t, undefined_cat, i); } else { - // 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; + if (is_cust_cutoff) { + if (p[i] <= sig_cutoff) { + cat_data.AppendIdToCategory(t, not_sig_cat + 1, i); + } + } else { + for (int c = NUM_SIG_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/AbstractClusterMap.h b/Explore/AbstractClusterMap.h index 3ceee136d..45df34fcb 100644 --- a/Explore/AbstractClusterMap.h +++ b/Explore/AbstractClusterMap.h @@ -64,10 +64,13 @@ class AbstractMapCanvas : public MapCanvas wxString str_p001; wxString str_p0001; wxString str_p00001; + wxString str_p000001; wxColour clr_not_sig_point; wxColour clr_not_sig_polygon; + const static int NUM_SIG_CATS = 5; + DECLARE_EVENT_TABLE() }; diff --git a/Explore/AbstractCoordinator.cpp b/Explore/AbstractCoordinator.cpp index 1e1f26a7c..e064f9a16 100644 --- a/Explore/AbstractCoordinator.cpp +++ b/Explore/AbstractCoordinator.cpp @@ -145,6 +145,7 @@ std::vector AbstractCoordinator::GetDefaultCategories() cats.push_back("p = 0.01"); cats.push_back("p = 0.001"); cats.push_back("p = 0.0001"); + cats.push_back("p = 0.00001"); return cats; } @@ -155,6 +156,7 @@ std::vector AbstractCoordinator::GetDefaultCutoffs() cutoffs.push_back(0.01); cutoffs.push_back(0.001); cutoffs.push_back(0.0001); + cutoffs.push_back(0.00001); return cutoffs; } @@ -524,7 +526,7 @@ void AbstractCoordinator::CalcPseudoP_range(int obs_start, int obs_end, } int* _sigCat = sig_cat_vecs[t]; if (numNeighbors == 0) { - _sigCat[cnt] = 5; + _sigCat[cnt] = 6; } } @@ -568,7 +570,8 @@ void AbstractCoordinator::CalcPseudoP_range(int obs_start, int obs_end, _sigLocal[cnt] = (countLarger[t]+1.0)/(permutations+1); // 'significance' of local Moran - if (_sigLocal[cnt] <= 0.0001) _sigCat[cnt] = 4; + if (_sigLocal[cnt] <= 0.00001) _sigCat[cnt] = 5; + else if (_sigLocal[cnt] <= 0.0001) _sigCat[cnt] = 4; else if (_sigLocal[cnt] <= 0.001) _sigCat[cnt] = 3; else if (_sigLocal[cnt] <= 0.01) _sigCat[cnt] = 2; else if (_sigLocal[cnt] <= 0.05) _sigCat[cnt]= 1; @@ -588,13 +591,14 @@ void AbstractCoordinator::SetSignificanceFilter(int filter_id) significance_filter = filter_id; return; } - // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 - if (filter_id < 1 || filter_id > 4) return; + // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001, 5: 0.00001 + if (filter_id < 1 || filter_id > 5) return; significance_filter = filter_id; if (filter_id == 1) significance_cutoff = 0.05; if (filter_id == 2) significance_cutoff = 0.01; if (filter_id == 3) significance_cutoff = 0.001; if (filter_id == 4) significance_cutoff = 0.0001; + if (filter_id == 5) significance_cutoff = 0.00001; wxLogMessage("Exiting AbstractCoordinator::SetSignificanceFilter()"); } diff --git a/Explore/AbstractCoordinator.h b/Explore/AbstractCoordinator.h index 1486b3c5c..c59a3657a 100644 --- a/Explore/AbstractCoordinator.h +++ b/Explore/AbstractCoordinator.h @@ -215,6 +215,13 @@ class AbstractCoordinator : public WeightsManStateObserver bool is_any_sync_with_global_time; std::vector map_valid; std::vector map_error_message; + + const static int HH_CLUSTER = 1; + const static int LL_CLUSTER = 2; + const static int LH_CLUSTER = 3; + const static int HL_CLUSTER = 4; + const static int NEIGHBORLESS_CLUSTER = 5; + const static int UNDEFINED_CLUSTER = 6; /** The list of registered observer objects. */ std::list observers; diff --git a/Explore/ConditionalClusterMapView.cpp b/Explore/ConditionalClusterMapView.cpp index f7c4d23cc..691e5af76 100644 --- a/Explore/ConditionalClusterMapView.cpp +++ b/Explore/ConditionalClusterMapView.cpp @@ -414,8 +414,10 @@ void ConditionalClusterMapCanvas::ResizeSelectableShps(int virtual_scrn_w, for (int i=0; iapplyScaleTrans(st[row_c][col_c]); } @@ -1063,6 +1065,7 @@ ConditionalLISAClusterMapCanvas::~ConditionalLISAClusterMapCanvas() void ConditionalLISAClusterMapCanvas::CreateAndUpdateCategories() { + num_time_vals = lisa_coord->num_time_vals; cat_var_sorted.clear(); map_valid.resize(num_time_vals); for (int t=0; tnum_time_vals; - int lisa_t = project->GetTimeState()->GetCurrTime(); + for (int t=0; tGetClusterIndicators(lisa_t); + int* clst = lisa_coord->GetClusterIndicators(t); for (int i=0; iundef_data[0][lisa_t][i]; + cat_var_undef[t][i] = lisa_coord->undef_data[0][t][i]; } } @@ -1122,11 +1122,9 @@ void ConditionalLISAClusterMapCanvas::CreateAndUpdateCategories() int isolates_cat = -1; int num_cats = 0; double stop_sig = 0; - if (lisa_t < num_time -1) - lisa_t = t; - if (lisa_coord->GetHasIsolates(lisa_t)) + if (lisa_coord->GetHasIsolates(t)) num_cats++; - if (lisa_coord->GetHasUndefined(lisa_t)) + if (lisa_coord->GetHasUndefined(t)) num_cats++; num_cats += 5; @@ -1150,13 +1148,13 @@ void ConditionalLISAClusterMapCanvas::CreateAndUpdateCategories() cat_data.SetCategoryColor(t, 3, wxColour(150, 150, 255)); cat_data.SetCategoryLabel(t, 4, "High-Low"); cat_data.SetCategoryColor(t, 4, wxColour(255, 150, 150)); - if (lisa_coord->GetHasIsolates(lisa_t) && - lisa_coord->GetHasUndefined(lisa_t)) { + if (lisa_coord->GetHasIsolates(t) && + lisa_coord->GetHasUndefined(t)) { isolates_cat = 5; undefined_cat = 6; - } else if (lisa_coord->GetHasUndefined(lisa_t)) { + } else if (lisa_coord->GetHasUndefined(t)) { undefined_cat = 5; - } else if (lisa_coord->GetHasIsolates(lisa_t)) { + } else if (lisa_coord->GetHasIsolates(t)) { isolates_cat = 5; } @@ -1170,8 +1168,8 @@ void ConditionalLISAClusterMapCanvas::CreateAndUpdateCategories() } double cuttoff = lisa_coord->GetSignificanceCutoff(); - double* p = lisa_coord->GetLocalSignificanceValues(lisa_t); - int* cluster = lisa_coord->GetClusterIndicators(lisa_t); + double* p = lisa_coord->GetLocalSignificanceValues(t); + int* cluster = lisa_coord->GetClusterIndicators(t); //int* sigCat = lisa_coord->sig_cat_vecs[t]; for (int i=0, iend=lisa_coord->num_obs; ivar_info[0].time; + cat_data.SetCurrentCanvasTmStep(lisa_t); int mt = cat_data.GetCurrentCanvasTmStep(); num_categories = cat_data.categories[mt].cat_vec.size(); CatClassification::ChangeNumCats(GetNumCats(), cat_classif_def_map); @@ -1283,6 +1282,7 @@ ConditionalGClusterMapCanvas::~ConditionalGClusterMapCanvas() void ConditionalGClusterMapCanvas::CreateAndUpdateCategories() { + num_time_vals = g_coord->num_time_vals; cat_var_sorted.clear(); map_valid.resize(num_time_vals); for (int t=0; tnum_time_vals; - int lisa_t = project->GetTimeState()->GetCurrTime(); for (int t=0; t cluster; - g_coord->FillClusterCats(lisa_t, is_gi, is_perm, cluster); + g_coord->FillClusterCats(t, is_gi, is_perm, cluster); for (int i=0; idata_undef[0][lisa_t][i]; + cat_var_undef[t][i] = g_coord->data_undef[0][t][i]; } } @@ -1347,11 +1343,9 @@ void ConditionalGClusterMapCanvas::CreateAndUpdateCategories() int isolates_cat = -1; int num_cats = 0; double stop_sig = 0; - if (lisa_t < num_time -1) - lisa_t = t; - if (g_coord->GetHasIsolates(lisa_t)) + if (g_coord->GetHasIsolates(t)) num_cats++; - if (g_coord->GetHasUndefined(lisa_t)) + if (g_coord->GetHasUndefined(t)) num_cats++; num_cats += 3; @@ -1369,14 +1363,14 @@ void ConditionalGClusterMapCanvas::CreateAndUpdateCategories() cat_data.SetCategoryLabel(t, 2, _("Low")); cat_data.SetCategoryColor(t, 2, wxColour(0, 0, 255)); - if (g_coord->GetHasIsolates(lisa_t) && - g_coord->GetHasUndefined(lisa_t)) + if (g_coord->GetHasIsolates(t) && + g_coord->GetHasUndefined(t)) { isolates_cat = 3; undefined_cat = 4; - } else if (g_coord->GetHasUndefined(lisa_t)) { + } else if (g_coord->GetHasUndefined(t)) { undefined_cat = 3; - } else if (g_coord->GetHasIsolates(lisa_t)) { + } else if (g_coord->GetHasIsolates(t)) { isolates_cat = 3; } @@ -1390,7 +1384,7 @@ void ConditionalGClusterMapCanvas::CreateAndUpdateCategories() } vector cluster; - g_coord->FillClusterCats(lisa_t, is_gi, is_perm, cluster); + g_coord->FillClusterCats(t, is_gi, is_perm, cluster); for (int i=0, iend=g_coord->num_obs; ivar_info[0].time; + cat_data.SetCurrentCanvasTmStep(lisa_t); int mt = cat_data.GetCurrentCanvasTmStep(); num_categories = cat_data.categories[mt].cat_vec.size(); CatClassification::ChangeNumCats(GetNumCats(), cat_classif_def_map); @@ -1501,6 +1496,7 @@ ConditionalLocalGearyClusterMapCanvas::~ConditionalLocalGearyClusterMapCanvas() void ConditionalLocalGearyClusterMapCanvas::CreateAndUpdateCategories() { + num_time_vals = local_geary_coord->num_time_vals; cat_var_sorted.clear(); map_valid.resize(num_time_vals); for (int t=0; tnum_time_vals; - int lisa_t = project->GetTimeState()->GetCurrTime(); - for (int t=0; tcluster_vecs[lisa_t][i]; + cat_var_sorted[t][i].first = local_geary_coord->cluster_vecs[t][i]; cat_var_sorted[t][i].second = i; - cat_var_undef[t][i] = local_geary_coord->undef_data[0][lisa_t][i]; + cat_var_undef[t][i] = local_geary_coord->undef_data[0][t][i]; } } @@ -1563,11 +1554,10 @@ 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(lisa_t)) + if (local_geary_coord->GetHasIsolates(t)) num_cats++; - if (local_geary_coord->GetHasUndefined(lisa_t)) + if (local_geary_coord->GetHasUndefined(t)) num_cats++; num_cats += 5; @@ -1591,13 +1581,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(lisa_t) && - local_geary_coord->GetHasUndefined(lisa_t)) { + if (local_geary_coord->GetHasIsolates(t) && + local_geary_coord->GetHasUndefined(t)) { isolates_cat = 5; undefined_cat = 6; - } else if (local_geary_coord->GetHasUndefined(lisa_t)) { + } else if (local_geary_coord->GetHasUndefined(t)) { undefined_cat = 5; - } else if (local_geary_coord->GetHasIsolates(lisa_t)) { + } else if (local_geary_coord->GetHasIsolates(t)) { isolates_cat = 5; } @@ -1611,9 +1601,9 @@ void ConditionalLocalGearyClusterMapCanvas::CreateAndUpdateCategories() } double cuttoff = local_geary_coord->significance_cutoff; - 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]; + 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]; for (int i=0, iend=local_geary_coord->num_obs; i cuttoff && cluster[i] != 5 && cluster[i] != 6) { @@ -1632,7 +1622,8 @@ void ConditionalLocalGearyClusterMapCanvas::CreateAndUpdateCategories() } } - cat_data.SetCurrentCanvasTmStep(0); + int lisa_t = local_geary_coord->var_info[0].time; + cat_data.SetCurrentCanvasTmStep(lisa_t); int mt = cat_data.GetCurrentCanvasTmStep(); num_categories = cat_data.categories[mt].cat_vec.size(); CatClassification::ChangeNumCats(GetNumCats(), cat_classif_def_map); @@ -1721,6 +1712,7 @@ ConditionalLocalJoinCountClusterMapCanvas::~ConditionalLocalJoinCountClusterMapC void ConditionalLocalJoinCountClusterMapCanvas::CreateAndUpdateCategories() { + num_time_vals = local_jc_coord->num_time_vals; cat_var_sorted.clear(); map_valid.resize(num_time_vals); for (int t=0; tnum_time_vals; - int lisa_t = project->GetTimeState()->GetCurrTime(); - for (int t=0; tlocal_jc_vecs[lisa_t][i]; + cat_var_sorted[t][i].first = local_jc_coord->local_jc_vecs[t][i]; cat_var_sorted[t][i].second = i; - cat_var_undef[t][i] = local_jc_coord->undef_tms[lisa_t][i]; + cat_var_undef[t][i] = local_jc_coord->undef_tms[t][i]; } } @@ -1783,11 +1770,9 @@ void ConditionalLocalJoinCountClusterMapCanvas::CreateAndUpdateCategories() int isolates_cat = -1; int num_cats = 0; double stop_sig = 0; - if (lisa_t < num_time -1) - lisa_t = t; - if (local_jc_coord->GetHasIsolates(lisa_t)) + if (local_jc_coord->GetHasIsolates(t)) num_cats++; - if (local_jc_coord->GetHasUndefined(lisa_t)) + if (local_jc_coord->GetHasUndefined(t)) num_cats++; num_cats += 5; @@ -1809,13 +1794,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(lisa_t) && - local_jc_coord->GetHasUndefined(lisa_t)) { + if (local_jc_coord->GetHasIsolates(t) && + local_jc_coord->GetHasUndefined(t)) { isolates_cat = 4; undefined_cat = 5; - } else if (local_jc_coord->GetHasUndefined(lisa_t)) { + } else if (local_jc_coord->GetHasUndefined(t)) { undefined_cat = 4; - } else if (local_jc_coord->GetHasIsolates(lisa_t)) { + } else if (local_jc_coord->GetHasIsolates(t)) { isolates_cat = 4; } @@ -1829,9 +1814,9 @@ void ConditionalLocalJoinCountClusterMapCanvas::CreateAndUpdateCategories() } double cuttoff = local_jc_coord->significance_cutoff; - double* p = local_jc_coord->sig_local_jc_vecs[lisa_t]; + double* p = local_jc_coord->sig_local_jc_vecs[t]; std::vector cluster; - local_jc_coord->FillClusterCats(lisa_t, cluster); + local_jc_coord->FillClusterCats(t, cluster); for (int i=0, iend=local_jc_coord->num_obs; i cuttoff && cluster[i] != 4 && cluster[i] != 5) { @@ -1850,7 +1835,8 @@ void ConditionalLocalJoinCountClusterMapCanvas::CreateAndUpdateCategories() } } - cat_data.SetCurrentCanvasTmStep(0); + int lisa_t = local_jc_coord->var_info[0].time; + cat_data.SetCurrentCanvasTmStep(lisa_t); int mt = cat_data.GetCurrentCanvasTmStep(); num_categories = cat_data.categories[mt].cat_vec.size(); CatClassification::ChangeNumCats(GetNumCats(), cat_classif_def_map); diff --git a/Explore/GStatCoordinator.cpp b/Explore/GStatCoordinator.cpp index 4b5e14e78..05ac1db69 100644 --- a/Explore/GStatCoordinator.cpp +++ b/Explore/GStatCoordinator.cpp @@ -419,18 +419,18 @@ void GStatCoordinator::FillClusterCats(int canvas_time, bool is_gi, bool is_perm c_val.resize(num_obs); for (int i=0; i 0 ? 1 : 2; // high = 1, low = 2 + c_val[i] = z_val[i] > 0 ? HH_CLUSTER : LL_CLUSTER; // high = 1, low = 2 } else { if (x_vecs[t][i] == 1 && z_val[i] > 0) - c_val[i] = 1; + c_val[i] = HH_CLUSTER; else c_val[i] = 0; } @@ -779,12 +779,13 @@ void GStatCoordinator::SetSignificanceFilter(int filter_id) return; } // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 - if (filter_id < 1 || filter_id > 4) return; + if (filter_id < 1 || filter_id > 5) return; significance_filter = filter_id; if (filter_id == 1) significance_cutoff = 0.05; if (filter_id == 2) significance_cutoff = 0.01; if (filter_id == 3) significance_cutoff = 0.001; if (filter_id == 4) significance_cutoff = 0.0001; + if (filter_id == 5) significance_cutoff = 0.00001; wxLogMessage("Exiting GStatCoordinator::SetSignificanceFilter"); } diff --git a/Explore/GStatCoordinator.h b/Explore/GStatCoordinator.h index 627d8df39..5f06da567 100644 --- a/Explore/GStatCoordinator.h +++ b/Explore/GStatCoordinator.h @@ -151,6 +151,11 @@ class GStatCoordinator : public WeightsManStateObserver // number of neighbors with 1 std::vector num_neighbors_1; + const static int HH_CLUSTER = 1; + const static int LL_CLUSTER = 2; + const static int NEIGHBORLESS_CLUSTER = 3; + const static int UNDEFINED_CLUSTER = 4; + protected: // The following ten are just temporary pointers into the corresponding // space-time data arrays below diff --git a/Explore/GetisOrdMapNewView.cpp b/Explore/GetisOrdMapNewView.cpp index 5f6070784..7f5a54acd 100644 --- a/Explore/GetisOrdMapNewView.cpp +++ b/Explore/GetisOrdMapNewView.cpp @@ -19,6 +19,8 @@ #include "GetisOrdMapNewView.h" +#include +#include #include #include #include @@ -77,6 +79,7 @@ row_standardize(row_standardize_s) str_p001 = "p = 0.01"; str_p0001 = "p = 0.001"; str_p00001 = "p = 0.0001"; + str_p000001 = "p = 0.00001"; SetPredefinedColor(str_not_sig, wxColour(240, 240, 240)); SetPredefinedColor(str_high, wxColour(255, 0, 0)); @@ -87,6 +90,7 @@ row_standardize(row_standardize_s) SetPredefinedColor(str_p001, wxColour(6, 196, 11)); SetPredefinedColor(str_p0001, wxColour(3, 116, 6)); SetPredefinedColor(str_p00001, wxColour(1, 70, 3)); + SetPredefinedColor(str_p000001, wxColour(0, 50, 2)); if (is_clust) { cat_classif_def.cat_classif_type @@ -242,49 +246,54 @@ void GetisOrdMapCanvas::CreateAndUpdateCategories() int undefined_cat = -1; int isolates_cat = -1; int num_cats = 0; - double stop_sig = 0; Shapefile::Header& hdr = project->main_data.header; - if (gs_coord->GetHasIsolates(t)) { + int set_perm = gs_coord->permutations; + double stop_sig = 1.0 / (1.0 + set_perm); + double sig_cutoff = gs_coord->significance_cutoff; + wxString def_cats[NUM_SIG_CATS] = {str_p005, str_p001, str_p0001, str_p00001, str_p000001}; + double def_cutoffs[NUM_SIG_CATS] = {0.05, 0.01, 0.001, 0.0001, 0.00001}; + bool is_cust_cutoff = gs_coord->GetSignificanceFilter() < 0; + bool has_isolates = gs_coord->GetHasIsolates(t); + bool has_undefined = gs_coord->GetHasUndefined(t); + int cat_idx = 0; + + if (has_isolates) { num_cats++; } - if (gs_coord->GetHasUndefined(t)) { + if (has_undefined) { num_cats++; } if (is_clust) { + // Not Sig, HH, LL num_cats += 3; // in Local Join Count, don't display Low category - if (gs_coord->is_local_join_count) + if (gs_coord->is_local_join_count) { num_cats -= 1; + } cat_data.CreateCategoriesAtCanvasTm(num_cats, t); - cat_data.SetCategoryLabel(t, 0, str_not_sig); - cat_data.SetCategoryColor(t, 0, lbl_color_dict[str_not_sig]); - cat_data.SetCategoryLabel(t, 1, str_high); - cat_data.SetCategoryColor(t, 1, lbl_color_dict[str_high]); + cat_data.SetCategoryLabel(t, cat_idx, str_not_sig); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_not_sig]); + cat_data.SetCategoryLabel(t, cat_idx, str_high); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_high]); if (!gs_coord->is_local_join_count) { - cat_data.SetCategoryLabel(t, 2, str_low); - cat_data.SetCategoryColor(t, 2, lbl_color_dict[str_low]); + cat_data.SetCategoryLabel(t, cat_idx, str_low); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_low]); } - if (gs_coord->GetHasIsolates(t) && gs_coord->GetHasUndefined(t)) { - isolates_cat = 3 - gs_coord->is_local_join_count; - undefined_cat = 4 - gs_coord->is_local_join_count; - } else if (gs_coord->GetHasUndefined(t)) { - undefined_cat = 3 - gs_coord->is_local_join_count; - } else if (gs_coord->GetHasIsolates(t)) { - isolates_cat = 3 - gs_coord->is_local_join_count; - } - if (undefined_cat != -1) { - cat_data.SetCategoryLabel(t, undefined_cat, str_undefined); - cat_data.SetCategoryColor(t, undefined_cat, lbl_color_dict[str_undefined]); + if (has_undefined) { + undefined_cat = cat_idx; + cat_data.SetCategoryLabel(t, cat_idx, str_undefined); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_undefined]); } - if (isolates_cat != -1) { - cat_data.SetCategoryLabel(t, isolates_cat, str_neighborless); - cat_data.SetCategoryColor(t, isolates_cat, lbl_color_dict[str_neighborless]); + if (has_isolates) { + isolates_cat = cat_idx; + cat_data.SetCategoryLabel(t, cat_idx, str_neighborless); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_neighborless]); } gs_coord->FillClusterCats(t, is_gi, is_perm, cluster); @@ -292,9 +301,9 @@ void GetisOrdMapCanvas::CreateAndUpdateCategories() for (int i=0, iend=gs_coord->num_obs; ipermutations; - stop_sig = 1.0 / (1.0 + set_perm); - double sig_cutoff = gs_coord->significance_cutoff; - wxString def_cats[4] = {str_p005, str_p001, str_p0001, str_p00001}; - double def_cutoffs[4] = {0.05, 0.01, 0.001, 0.0001}; - - bool is_cust_cutoff = true; - for (int i=0; i<4; i++) { - if (sig_cutoff == def_cutoffs[i]) { - is_cust_cutoff = false; - break; - } - } + // significance map + // 0: >0.05 (Not sig) 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001, 5: 0.00001 + num_cats += 1; // not sig category - if ( is_cust_cutoff ) { - // if set customized cutoff value - wxString lbl = wxString::Format("p = %g", sig_cutoff); - if ( sig_cutoff > 0.05 ) { - def_cutoffs[0] = sig_cutoff; - lbl_color_dict[lbl] = lbl_color_dict[def_cats[0]]; - def_cats[0] = lbl; - } else { - for (int i = 1; i < 4; i++) { - if (def_cutoffs[i-1] + def_cutoffs[i] < 2 * sig_cutoff){ - lbl_color_dict[lbl] = lbl_color_dict[def_cats[i-1]]; - def_cutoffs[i-1] = sig_cutoff; - def_cats[i-1] = lbl; - break; - } else { - lbl_color_dict[lbl] = lbl_color_dict[def_cats[i]]; - def_cutoffs[i] = sig_cutoff; - def_cats[i] = lbl; - break; - } + if (is_cust_cutoff) { + num_cats += 1; + } else { + for (int j=0; j < NUM_SIG_CATS; j++) { + if (sig_cutoff >= def_cutoffs[j] && stop_sig <= def_cutoffs[j]) { + num_cats += 1; } } } - - num_cats = 5; - for (int j=0; j < 4; j++) { - if (sig_cutoff < def_cutoffs[j]) - num_cats -= 1; - } - - // issue #474 only show significance levels that can be mapped for the given number of permutations, e.g., for 99 it would stop at 0.01, for 999 at 0.001, etc. - if ( sig_cutoff >= def_cutoffs[3] && stop_sig > def_cutoffs[3] ){ //0.0001 - num_cats -= 1; - } - if ( sig_cutoff >= def_cutoffs[2] && stop_sig > def_cutoffs[2] ){ //0.001 - num_cats -= 1; - } - if ( sig_cutoff >= def_cutoffs[1] && stop_sig > def_cutoffs[1] ){ //0.01 - num_cats -= 1; - } cat_data.CreateCategoriesAtCanvasTm(num_cats, t); - // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 - cat_data.SetCategoryLabel(t, 0, str_not_sig); + int cat_idx = 0; + cat_data.SetCategoryLabel(t, cat_idx, str_not_sig); + cat_data.SetCategoryColor(t, cat_idx++, hdr.shape_type == Shapefile::POINT_TYP ? wxColour(190, 190, 190) : wxColour(240, 240, 240)); + + std::map level_cat_dict; - if (hdr.shape_type == Shapefile::POINT_TYP) { - cat_data.SetCategoryColor(t, 0, wxColour(190, 190, 190)); + if (is_cust_cutoff) { + std::ostringstream ss_sig_cutoff; + ss_sig_cutoff << std::fixed << sig_cutoff; + wxString lbl = wxString::Format("p = %s", ss_sig_cutoff.str()); + cat_data.SetCategoryColor(t, cat_idx, lbl_color_dict[def_cats[0]]); + cat_data.SetCategoryLabel(t, cat_idx++, lbl); } else { - cat_data.SetCategoryColor(t, 0, wxColour(240, 240, 240)); - } - - int cat_idx = 1; - std::map level_cat_dict; - for (int j=0; j < 4; j++) { - if (sig_cutoff >= def_cutoffs[j] && def_cutoffs[j] >= stop_sig) { - cat_data.SetCategoryColor(t, cat_idx, lbl_color_dict[def_cats[j]]); - cat_data.SetCategoryLabel(t, cat_idx, def_cats[j]); - level_cat_dict[j] = cat_idx; - cat_idx += 1; + for (int j=0; j < NUM_SIG_CATS; j++) { + if (stop_sig <= def_cutoffs[j]) { + level_cat_dict[j] = cat_idx; + cat_data.SetCategoryColor(t, cat_idx, lbl_color_dict[def_cats[j]]); + cat_data.SetCategoryLabel(t, cat_idx++, def_cats[j]); + } } } - if (gs_coord->GetHasIsolates(t) && - gs_coord->GetHasUndefined(t)) { - isolates_cat = cat_idx++; - undefined_cat = cat_idx++; - - } else if (gs_coord->GetHasUndefined(t)) { - undefined_cat = cat_idx++; - - } else if (gs_coord->GetHasIsolates(t)) { - isolates_cat = cat_idx++; - } - - if (undefined_cat != -1) { - cat_data.SetCategoryLabel(t, undefined_cat, str_undefined); - cat_data.SetCategoryColor(t, undefined_cat, lbl_color_dict[str_undefined]); + if (has_isolates) { + isolates_cat = cat_idx; + cat_data.SetCategoryLabel(t, cat_idx, str_neighborless); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_neighborless]); } - if (isolates_cat != -1) { - cat_data.SetCategoryLabel(t, isolates_cat, str_neighborless); - cat_data.SetCategoryColor(t, isolates_cat, lbl_color_dict[str_neighborless]); + if (has_undefined) { + undefined_cat = cat_idx; + cat_data.SetCategoryLabel(t, cat_idx, str_undefined); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_undefined]); } gs_coord->FillClusterCats(t, is_gi, is_perm, cluster); + double* p = 0; if (is_gi && is_perm) p = gs_coord->pseudo_p_vecs[t]; @@ -410,20 +371,24 @@ void GetisOrdMapCanvas::CreateAndUpdateCategories() if (!is_gi && !is_perm) p = gs_coord->p_star_vecs[t]; - int s_f = gs_coord->GetSignificanceFilter(); - for (int i=0, iend=gs_coord->num_obs; inum_obs; i++) { if (cluster[i] == 0) { cat_data.AppendIdToCategory(t, 0, i); // not significant - } else if (cluster[i] == 3) { + } else if (cluster[i] == GStatCoordinator::NEIGHBORLESS_CLUSTER) { cat_data.AppendIdToCategory(t, isolates_cat, i); - } else if (cluster[i] == 4) { + } else if (cluster[i] == GStatCoordinator::UNDEFINED_CLUSTER) { cat_data.AppendIdToCategory(t, undefined_cat, i); } else { - //cat_data.AppendIdToCategory(t, (sigCat[i]-s_f)+1, i); - for ( int c = 4-1; c >= 0; c-- ) { - if ( p[i] <= def_cutoffs[c] ) { - cat_data.AppendIdToCategory(t, level_cat_dict[c], i); - break; + if (is_cust_cutoff) { + if (p[i] <= sig_cutoff) { + cat_data.AppendIdToCategory(t, 1, i); + } + } else { + for (int c = NUM_SIG_CATS - 1; c >= 0; c--) { + if (p[i] <= def_cutoffs[c]) { + cat_data.AppendIdToCategory(t, level_cat_dict[c], i); + break; + } } } } @@ -431,8 +396,7 @@ void GetisOrdMapCanvas::CreateAndUpdateCategories() } for (int cat=0; cat 0) { if (data1) { if (data1[i] > reference_val && Wdata < reference_val) { - cluster[i] = 4; + cluster[i] = HL_CLUSTER; } else if (data1[i] < reference_val && Wdata > reference_val) { - cluster[i] = 3; + cluster[i] = LH_CLUSTER; } else if (data1[i] < reference_val && Wdata < reference_val) { - cluster[i] = 2; + cluster[i] = LL_CLUSTER; } else { - cluster[i] = 1; //data1[i] > 0 && Wdata > 0 + cluster[i] = HH_CLUSTER; //data1[i] > 0 && Wdata > 0 } } } @@ -575,18 +575,19 @@ void LisaCoordinator::CalcPseudoP() if (flag) { for (int cnt=0; cnt 0) { - if (data1[i] > 0 && Wdata > 0) cluster[i] = 1; - else if (data1[i] < 0 && Wdata > 0) cluster[i] = 3; - else if (data1[i] < 0 && Wdata < 0) cluster[i] = 2; - else cluster[i] = 4; //data1[i] > 0 && Wdata < 0 + if (data1[i] > 0 && Wdata > 0) cluster[i] = HH_CLUSTER; + else if (data1[i] < 0 && Wdata > 0) cluster[i] = OTHER_POSITIVE_CLUSTER; + else if (data1[i] < 0 && Wdata < 0) cluster[i] = LL_CLUSTER; + else cluster[i] = NEGATIVE_CLUSTER; //data1[i] > 0 && Wdata < 0 } else { has_isolates[t] = true; - cluster[i] = 5; // neighborless + cluster[i] = NEIGHBORLESS_CLUSTER; // neighborless } } } @@ -1003,7 +1003,7 @@ void LocalGearyCoordinator::CalcPseudoP_range(int obs_start, int obs_end, uint64 } if (local_geary_type == multivariate) { if (_cluster[cnt] < 2 ) { // ignore neighborless & undefined - _cluster[cnt] = 1; + _cluster[cnt] = MULTIVAR_POSITIVE; } } else { // positive && high-high if (cluster[cnt] == 1) cluster[cnt] = 1; @@ -1011,7 +1011,7 @@ void LocalGearyCoordinator::CalcPseudoP_range(int obs_start, int obs_end, uint64 // positive && but in outlier qudrant: other pos if (_cluster[cnt] > 2 && _cluster[cnt] < 5) { // ignore neighborless & undefined - _cluster[cnt] = 3; + _cluster[cnt] = OTHER_POSITIVE_CLUSTER; } } } else { @@ -1023,18 +1023,19 @@ void LocalGearyCoordinator::CalcPseudoP_range(int obs_start, int obs_end, uint64 } if (local_geary_type == multivariate) { if (_cluster[cnt] < 2) // ignore neighborless & undefined - _cluster[cnt] = 2; // for multivar, only show significant positive (similar) + _cluster[cnt] = MULTIVAR_NEGATIVE; // for multivar, only show significant positive (similar) } else { // negative if (_cluster[cnt] < 5) // ignore neighborless & undefined - _cluster[cnt] = 4; + _cluster[cnt] = NEGATIVE_CLUSTER; } } int kp = local_geary_type == multivariate ? num_vars : 1; _siglocalGeary[cnt] = (countLarger[t]+1.0)/(permutations+1); // 'significance' of local Moran - if (_siglocalGeary[cnt] <= 0.0001) _sigCat[cnt] = 4; + if (_siglocalGeary[cnt] <= 0.00001) _sigCat[cnt] = 5; + else if (_siglocalGeary[cnt] <= 0.0001) _sigCat[cnt] = 4; else if (_siglocalGeary[cnt] <= 0.001) _sigCat[cnt] = 3; else if (_siglocalGeary[cnt] <= 0.01) _sigCat[cnt] = 2; else if (_siglocalGeary[cnt] <= 0.05) _sigCat[cnt]= 1; @@ -1043,7 +1044,7 @@ void LocalGearyCoordinator::CalcPseudoP_range(int obs_start, int obs_end, uint64 // observations with no neighbors get marked as isolates // NOTE: undefined should be marked as well, however, since undefined_cat has covered undefined category, we don't need to handle here if (numNeighbors == 0) { - _sigCat[cnt] = 5; + _sigCat[cnt] = 6; } } @@ -1059,8 +1060,8 @@ void LocalGearyCoordinator::SetSignificanceFilter(int filter_id) significance_filter = filter_id; return; } - // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 - if (filter_id < 1 || filter_id > 4) return; + // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 5: 0.00001 + if (filter_id < 1 || filter_id > 5) return; significance_filter = filter_id; //int kp = local_geary_type == multivariate ? num_vars : 1; @@ -1069,6 +1070,7 @@ void LocalGearyCoordinator::SetSignificanceFilter(int filter_id) if (filter_id == 2) significance_cutoff = 0.01; if (filter_id == 3) significance_cutoff = 0.001; if (filter_id == 4) significance_cutoff = 0.0001; + if (filter_id == 5) significance_cutoff = 0.00001; } void LocalGearyCoordinator::update(WeightsManState* o) diff --git a/Explore/LocalGearyCoordinator.h b/Explore/LocalGearyCoordinator.h index 623f3fd41..0223106b8 100644 --- a/Explore/LocalGearyCoordinator.h +++ b/Explore/LocalGearyCoordinator.h @@ -204,6 +204,17 @@ class LocalGearyCoordinator : public WeightsManStateObserver void VarInfoAttributeChange(); void GetRawData(int time, double* data1, double* data2); + + const static int HH_CLUSTER = 1; + const static int LL_CLUSTER = 2; + const static int OTHER_POSITIVE_CLUSTER = 3; + const static int NEGATIVE_CLUSTER = 4; + const static int NEIGHBORLESS_CLUSTER = 5; + const static int UNDEFINED_CLUSTER = 6; + const static int MULTIVAR_POSITIVE = 1; + const static int MULTIVAR_NEGATIVE = 2; + const static int MULTIVAR_NEIGHBORLESS_CLUSTER = 3; + const static int MULTIVAR_UNDEFINED_CLUSTER = 4; protected: void DeallocateVectors(); diff --git a/Explore/LocalGearyMapNewView.cpp b/Explore/LocalGearyMapNewView.cpp index 1ce0bfcab..27d8e12b6 100644 --- a/Explore/LocalGearyMapNewView.cpp +++ b/Explore/LocalGearyMapNewView.cpp @@ -18,6 +18,7 @@ */ #include +#include #include #include #include @@ -80,6 +81,7 @@ is_diff(local_geary_coordinator->local_geary_type == LocalGearyCoordinator::diff str_p001 = "p = 0.01"; str_p0001 = "p = 0.001"; str_p00001 = "p = 0.0001"; + str_p000001 = "p = 0.00001"; SetPredefinedColor(str_not_sig, wxColour(240, 240, 240)); SetPredefinedColor(str_highhigh, wxColour(178,24,43)); @@ -93,6 +95,7 @@ is_diff(local_geary_coordinator->local_geary_type == LocalGearyCoordinator::diff SetPredefinedColor(str_p001, wxColour(6, 196, 11)); SetPredefinedColor(str_p0001, wxColour(3, 116, 6)); SetPredefinedColor(str_p00001, wxColour(1, 70, 3)); + SetPredefinedColor(str_p000001, wxColour(0, 50, 2)); cat_classif_def.cat_classif_type = theme_type_s; // must set var_info times from LocalGearyCoordinator initially @@ -281,41 +284,9 @@ void LocalGearyMapCanvas::CreateAndUpdateCategories() int s_f = local_geary_coord->GetSignificanceFilter(); int set_perm = local_geary_coord->permutations; double stop_sig = 1.0 / (1.0 + set_perm); - - wxString def_cats[4] = {str_p005, str_p001, str_p0001, str_p00001}; - double def_cutoffs[4] = {0.05, 0.01, 0.001, 0.0001}; - - bool is_cust_cutoff = true; - for (int i=0; i<4; i++) { - if (sig_cutoff == def_cutoffs[i]) { - is_cust_cutoff = false; - break; - } - } - - if ( is_cust_cutoff ) { - // if set customized cutoff value - wxString lbl = wxString::Format("p = %g", sig_cutoff); - if ( sig_cutoff > 0.05 ) { - def_cutoffs[0] = sig_cutoff; - lbl_color_dict[lbl] = lbl_color_dict[def_cats[0]]; - def_cats[0] = lbl; - } else { - for (int i = 1; i < 4; i++) { - if (def_cutoffs[i-1] + def_cutoffs[i] < 2 * sig_cutoff){ - lbl_color_dict[lbl] = lbl_color_dict[def_cats[i-1]]; - def_cutoffs[i-1] = sig_cutoff; - def_cats[i-1] = lbl; - break; - } else { - lbl_color_dict[lbl] = lbl_color_dict[def_cats[i]]; - def_cutoffs[i] = sig_cutoff; - def_cats[i] = lbl; - break; - } - } - } - } + bool is_cust_cutoff = local_geary_coord->GetSignificanceFilter() < 0; + wxString def_cats[NUM_SIG_CATS] = {str_p005, str_p001, str_p0001, str_p00001, str_p000001}; + double def_cutoffs[NUM_SIG_CATS] = {0.05, 0.01, 0.001, 0.0001, 0.00001}; for (int t=0; tmain_data.header; + bool has_isolates = local_geary_coord->GetHasIsolates(t); + bool has_undefined = local_geary_coord->GetHasUndefined(t); - if (local_geary_coord->GetHasIsolates(t)) + if (has_isolates) { num_cats++; - if (local_geary_coord->GetHasUndefined(t)) + } + if (has_undefined) { num_cats++; + } + + int cat_idx = 0; if (is_clust) { - if (local_geary_coord->local_geary_type == LocalGearyCoordinator::multivariate) { - num_cats += 3; - } else if (local_geary_coord->local_geary_type == LocalGearyCoordinator::bivariate) { + if (local_geary_coord->local_geary_type == LocalGearyCoordinator::multivariate + || local_geary_coord->local_geary_type == LocalGearyCoordinator::bivariate + ) { + // not sig, positive, negative num_cats += 3; } else { + // not sig, HH, LL, Other Positive, Negative num_cats += 5; } cat_data.CreateCategoriesAtCanvasTm(num_cats, t); - cat_data.SetCategoryLabel(t, 0, str_not_sig); - - if (hdr.shape_type == Shapefile::POINT_TYP) { - cat_data.SetCategoryColor(t, 0, wxColour(190, 190, 190)); - } else { - cat_data.SetCategoryColor(t, 0, wxColour(240, 240, 240)); - } - if (local_geary_coord->local_geary_type == LocalGearyCoordinator::multivariate) { - cat_data.SetCategoryLabel(t, 1, str_positive); - cat_data.SetCategoryColor(t, 1, lbl_color_dict[str_positive]); - cat_data.SetCategoryLabel(t, 2, str_negative); - cat_data.SetCategoryColor(t, 2, lbl_color_dict[str_negative]); - if (local_geary_coord->GetHasIsolates(t) && - local_geary_coord->GetHasUndefined(t)) { - isolates_cat = 3; - undefined_cat = 4; - } else if (local_geary_coord->GetHasUndefined(t)) { - undefined_cat = 3; - } else if (local_geary_coord->GetHasIsolates(t)) { - isolates_cat = 3; - } - - } else if (local_geary_coord->local_geary_type == LocalGearyCoordinator::bivariate) { - cat_data.SetCategoryLabel(t, 1, str_positive); - cat_data.SetCategoryColor(t, 1, lbl_color_dict[str_positive]); - cat_data.SetCategoryLabel(t, 2, str_negative); - cat_data.SetCategoryColor(t, 2, lbl_color_dict[str_negative]);//wxColour(113,250,142)); - - if (local_geary_coord->GetHasIsolates(t) && - local_geary_coord->GetHasUndefined(t)) { - isolates_cat = 3; - undefined_cat = 4; - } else if (local_geary_coord->GetHasUndefined(t)) { - undefined_cat = 3; - } else if (local_geary_coord->GetHasIsolates(t)) { - isolates_cat = 3; - } + cat_data.SetCategoryLabel(t, cat_idx, str_not_sig); + cat_data.SetCategoryColor(t, cat_idx++, hdr.shape_type == Shapefile::POINT_TYP ? wxColour(190, 190, 190) : wxColour(240, 240, 240)); + + if (local_geary_coord->local_geary_type == LocalGearyCoordinator::multivariate + || local_geary_coord->local_geary_type == LocalGearyCoordinator::bivariate + ) { + cat_data.SetCategoryLabel(t, cat_idx, str_positive); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_positive]); + cat_data.SetCategoryLabel(t, cat_idx, str_negative); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_negative]); } else { - cat_data.SetCategoryLabel(t, 1, str_highhigh); - cat_data.SetCategoryColor(t, 1, lbl_color_dict[str_highhigh]); - cat_data.SetCategoryLabel(t, 2, str_lowlow); - cat_data.SetCategoryColor(t, 2, lbl_color_dict[str_lowlow]); - cat_data.SetCategoryLabel(t, 3, str_otherpos); - cat_data.SetCategoryColor(t, 3, lbl_color_dict[str_otherpos]); - cat_data.SetCategoryLabel(t, 4, str_negative); - cat_data.SetCategoryColor(t, 4, lbl_color_dict[str_negative]);//wxColour(103,173,199)); + cat_data.SetCategoryLabel(t, cat_idx, str_highhigh); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_highhigh]); + cat_data.SetCategoryLabel(t, cat_idx, str_lowlow); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_lowlow]); + cat_data.SetCategoryLabel(t, cat_idx, str_otherpos); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_otherpos]); + cat_data.SetCategoryLabel(t, cat_idx, str_negative); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_negative]); - if (local_geary_coord->GetHasIsolates(t) && - local_geary_coord->GetHasUndefined(t)) { - isolates_cat = 5; - undefined_cat = 6; - } else if (local_geary_coord->GetHasUndefined(t)) { - undefined_cat = 5; - } else if (local_geary_coord->GetHasIsolates(t)) { - isolates_cat = 5; - } } if (undefined_cat != -1) { - cat_data.SetCategoryLabel(t, undefined_cat, str_undefined); - cat_data.SetCategoryColor(t, undefined_cat, lbl_color_dict[str_undefined]); + undefined_cat = cat_idx; + cat_data.SetCategoryLabel(t, cat_idx, str_undefined); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_undefined]); } if (isolates_cat != -1) { - cat_data.SetCategoryLabel(t, isolates_cat, str_neighborless); - cat_data.SetCategoryColor(t, isolates_cat, lbl_color_dict[str_neighborless]); + isolates_cat = cat_idx; + cat_data.SetCategoryLabel(t, cat_idx, str_neighborless); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_neighborless]); } if (local_geary_coord->local_geary_type == LocalGearyCoordinator::multivariate) { for (int i=0, iend=local_geary_coord->num_obs; inum_obs; i sig_cutoff && cluster[i] != 5 && cluster[i] != 6) { + if (p[i] > sig_cutoff + && cluster[i] != LocalGearyCoordinator::NEIGHBORLESS_CLUSTER + && cluster[i] != LocalGearyCoordinator::UNDEFINED_CLUSTER + ) { cat_data.AppendIdToCategory(t, 0, i); // not significant - } else if (cluster[i] == 5) { + } else if (cluster[i] == LocalGearyCoordinator::NEIGHBORLESS_CLUSTER) { cat_data.AppendIdToCategory(t, isolates_cat, i); - } else if (cluster[i] == 6) { + } else if (cluster[i] == LocalGearyCoordinator::UNDEFINED_CLUSTER) { cat_data.AppendIdToCategory(t, undefined_cat, i); } else { cat_data.AppendIdToCategory(t, cluster[i], i); @@ -437,99 +385,103 @@ void LocalGearyMapCanvas::CreateAndUpdateCategories() } else { // significance map - // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 + // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001, 5: 0.00001 + num_cats += 1; // not sig category - num_cats = 5; - for (int j=0; j < 4; j++) { - if (sig_cutoff < def_cutoffs[j]) - num_cats -= 1; + if (is_cust_cutoff) { + num_cats += 1; + } else { + for (int j=0; j < NUM_SIG_CATS; j++) { + if (sig_cutoff >= def_cutoffs[j] && stop_sig <= def_cutoffs[j]) { + num_cats += 1; + } + } } - // issue #474 only show significance levels that can be mapped for the given number of permutations, e.g., for 99 it would stop at 0.01, for 999 at 0.001, etc. - if ( sig_cutoff >= def_cutoffs[3] && stop_sig > def_cutoffs[3] ){ //0.0001 - num_cats -= 1; - } - if ( sig_cutoff >= def_cutoffs[2] && stop_sig > def_cutoffs[2] ){ //0.001 - num_cats -= 1; - } - if ( sig_cutoff >= def_cutoffs[1] && stop_sig > def_cutoffs[1] ){ //0.01 - num_cats -= 1; - } cat_data.CreateCategoriesAtCanvasTm(num_cats, t); - // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 - cat_data.SetCategoryLabel(t, 0, str_not_sig); - - if (hdr.shape_type == Shapefile::POINT_TYP) { - cat_data.SetCategoryColor(t, 0, wxColour(190, 190, 190)); - } else { - cat_data.SetCategoryColor(t, 0, wxColour(240, 240, 240)); - } + int cat_idx = 0; + cat_data.SetCategoryLabel(t, cat_idx, str_not_sig); + cat_data.SetCategoryColor(t, cat_idx++, hdr.shape_type == Shapefile::POINT_TYP ? wxColour(190, 190, 190) : wxColour(240, 240, 240)); + - int cat_idx = 1; std::map level_cat_dict; - for (int j=0; j < 4; j++) { - if (sig_cutoff >= def_cutoffs[j] && def_cutoffs[j] >= stop_sig) { - cat_data.SetCategoryColor(t, cat_idx, lbl_color_dict[def_cats[j]]); - cat_data.SetCategoryLabel(t, cat_idx, def_cats[j]); - level_cat_dict[j] = cat_idx; - cat_idx += 1; - } - } - if (local_geary_coord->GetHasIsolates(t) && - local_geary_coord->GetHasUndefined(t)) { - isolates_cat = cat_idx++; - undefined_cat = cat_idx++; - - } else if (local_geary_coord->GetHasUndefined(t)) { - undefined_cat = cat_idx++; - - } else if (local_geary_coord->GetHasIsolates(t)) { - isolates_cat = cat_idx++; + if (is_cust_cutoff) { + std::ostringstream ss_sig_cutoff; + ss_sig_cutoff << std::fixed << sig_cutoff; + wxString lbl = wxString::Format("p = %s", ss_sig_cutoff.str()); + cat_data.SetCategoryColor(t, cat_idx, lbl_color_dict[def_cats[0]]); + cat_data.SetCategoryLabel(t, cat_idx++, lbl); + } else { + for (int j=0; j < NUM_SIG_CATS; j++) { + if (sig_cutoff >= def_cutoffs[j] && stop_sig <= def_cutoffs[j]) { + level_cat_dict[j] = cat_idx; + cat_data.SetCategoryColor(t, cat_idx, lbl_color_dict[def_cats[j]]); + cat_data.SetCategoryLabel(t, cat_idx++, def_cats[j]); + } + } } if (undefined_cat != -1) { - cat_data.SetCategoryLabel(t, undefined_cat, str_undefined); - cat_data.SetCategoryColor(t, undefined_cat, lbl_color_dict[str_undefined]); + undefined_cat = cat_idx; + cat_data.SetCategoryLabel(t, cat_idx, str_undefined); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_undefined]); } if (isolates_cat != -1) { - cat_data.SetCategoryLabel(t, isolates_cat, str_neighborless); - cat_data.SetCategoryColor(t, isolates_cat, lbl_color_dict[str_neighborless]); + isolates_cat = cat_idx; + cat_data.SetCategoryLabel(t, cat_idx, str_neighborless); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_neighborless]); } - int s_f = local_geary_coord->GetSignificanceFilter(); + if (local_geary_coord->local_geary_type == LocalGearyCoordinator::multivariate) { - for (int i=0, iend=local_geary_coord->num_obs; i sig_cutoff && cluster[i] != 3 && cluster[i] != 4) { + for (int i=0; inum_obs; i++) { + if (p[i] > sig_cutoff && + cluster[i] != LocalGearyCoordinator::MULTIVAR_NEIGHBORLESS_CLUSTER && + cluster[i] != LocalGearyCoordinator::MULTIVAR_UNDEFINED_CLUSTER + ) { cat_data.AppendIdToCategory(t, 0, i); // not significant - } else if (cluster[i] == 3) { + } else if (cluster[i] == LocalGearyCoordinator::MULTIVAR_NEIGHBORLESS_CLUSTER) { cat_data.AppendIdToCategory(t, isolates_cat, i); - } else if (cluster[i] == 4) { + } else if (cluster[i] == LocalGearyCoordinator::MULTIVAR_UNDEFINED_CLUSTER) { cat_data.AppendIdToCategory(t, undefined_cat, i); } else { - //cat_data.AppendIdToCategory(t, (sigCat[i]-s_f)+1, i); - for ( int c = 4-1; c >= 0; c-- ) { - if ( p[i] <= def_cutoffs[c] ) { - cat_data.AppendIdToCategory(t, level_cat_dict[c], i); - break; + if (is_cust_cutoff) { + if (p[i] <= sig_cutoff) { + cat_data.AppendIdToCategory(t, 1, i); + } + } else { + for (int c = NUM_SIG_CATS - 1; c >= 0; c--) { + if (p[i] <= def_cutoffs[c]) { + cat_data.AppendIdToCategory(t, level_cat_dict[c], i); + break; + } } } } } } else { - for (int i=0, iend=local_geary_coord->num_obs; i sig_cutoff && cluster[i] != 5 && cluster[i] != 6) { + for (int i=0; inum_obs; i++) { + if (p[i] > sig_cutoff && + cluster[i] != LocalGearyCoordinator::NEIGHBORLESS_CLUSTER && + cluster[i] != LocalGearyCoordinator::UNDEFINED_CLUSTER + ) { cat_data.AppendIdToCategory(t, 0, i); // not significant - } else if (cluster[i] == 5) { + } else if (cluster[i] == LocalGearyCoordinator::NEIGHBORLESS_CLUSTER) { cat_data.AppendIdToCategory(t, isolates_cat, i); - } else if (cluster[i] == 6) { + } else if (cluster[i] == LocalGearyCoordinator::UNDEFINED_CLUSTER) { cat_data.AppendIdToCategory(t, undefined_cat, i); } else { - //cat_data.AppendIdToCategory(t, (sigCat[i]-s_f)+1, i); - for ( int c = 4-1; c >= 0; c-- ) { - if ( p[i] <= def_cutoffs[c] ) { - cat_data.AppendIdToCategory(t, level_cat_dict[c], i); - break; + if (is_cust_cutoff) { + if (p[i] <= sig_cutoff) { + cat_data.AppendIdToCategory(t, 1, i); + } + } else { + for (int c = NUM_SIG_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/LocalGearyMapNewView.h b/Explore/LocalGearyMapNewView.h index 960069593..1ef462a60 100644 --- a/Explore/LocalGearyMapNewView.h +++ b/Explore/LocalGearyMapNewView.h @@ -76,6 +76,9 @@ class LocalGearyMapCanvas : public MapCanvas wxString str_p001; wxString str_p0001; wxString str_p00001; + wxString str_p000001; + + const static int NUM_SIG_CATS = 5; DECLARE_EVENT_TABLE() }; diff --git a/Explore/MLJCCoordinator.cpp b/Explore/MLJCCoordinator.cpp index 842cafce3..d374a0b38 100644 --- a/Explore/MLJCCoordinator.cpp +++ b/Explore/MLJCCoordinator.cpp @@ -292,10 +292,10 @@ void JCCoordinator::FillClusterCats(int canvas_time, std::vector& c_val for (int i=0; i0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 - if (filter_id < 1 || filter_id > 4) return; + // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001, 5: 0.00001 + if (filter_id < 1 || filter_id > 5) return; significance_filter = filter_id; if (filter_id == 1) significance_cutoff = 0.05; if (filter_id == 2) significance_cutoff = 0.01; if (filter_id == 3) significance_cutoff = 0.001; if (filter_id == 4) significance_cutoff = 0.0001; + if (filter_id == 5) significance_cutoff = 0.00001; } void JCCoordinator::update(WeightsManState* o) diff --git a/Explore/MLJCCoordinator.h b/Explore/MLJCCoordinator.h index 9757239ab..d0d284e50 100644 --- a/Explore/MLJCCoordinator.h +++ b/Explore/MLJCCoordinator.h @@ -86,8 +86,8 @@ class JCCoordinator : public WeightsManStateObserver bool IsOk() { return true; } wxString GetErrorMessage() { return "Error Message"; } - int significance_filter; // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 - double significance_cutoff; // either 0.05, 0.01, 0.001 or 0.0001 + int significance_filter; // 0: >0.05 1: 0.05, 2: 0.01, 3: 0.001, 4: 0.0001 5: 0.00001 + double significance_cutoff; // either 0.05, 0.01, 0.001 or 0.0001 or 0.00001 void SetSignificanceFilter(int filter_id); int GetSignificanceFilter() { return significance_filter; } int permutations; // any number from 9 to 99999, 99 will be default @@ -182,6 +182,9 @@ class JCCoordinator : public WeightsManStateObserver void FillClusterCats(int canvas_time,std::vector& c_val); + const static int NEIGHBORLESS_CLUSTER = 5; + const static int UNDEFINED_CLUSTER = 6; + protected: // The following ten are just temporary pointers into the corresponding // space-time data arrays below diff --git a/Explore/MLJCMapNewView.cpp b/Explore/MLJCMapNewView.cpp index 9264e6ecc..70259d476 100644 --- a/Explore/MLJCMapNewView.cpp +++ b/Explore/MLJCMapNewView.cpp @@ -49,9 +49,9 @@ BEGIN_EVENT_TABLE(MLJCMapCanvas, MapCanvas) END_EVENT_TABLE() -MLJCMapCanvas::MLJCMapCanvas(wxWindow *parent, TemplateFrame* t_frame, bool is_clust_p, Project* project, JCCoordinator* gs_coordinator, const wxPoint& pos, const wxSize& size) +MLJCMapCanvas::MLJCMapCanvas(wxWindow *parent, TemplateFrame* t_frame, bool is_clust_p, Project* project, JCCoordinator* gs_coordinator, bool is_quantile_lisa, const wxPoint& pos, const wxSize& size) : MapCanvas(parent, t_frame, project, std::vector(0), std::vector(0), CatClassification::no_theme, no_smoothing, 1, boost::uuids::nil_uuid(), pos, size), -gs_coord(gs_coordinator), is_clust(is_clust_p) +gs_coord(gs_coordinator), is_clust(is_clust_p), is_quantile_lisa(is_quantile_lisa) { LOG_MSG("Entering MLJCMapCanvas::MLJCMapCanvas"); @@ -65,6 +65,7 @@ gs_coord(gs_coordinator), is_clust(is_clust_p) str_p001 = "p = 0.01"; str_p0001 = "p = 0.001"; str_p00001 ="p = 0.0001"; + str_p000001 = "p = 0.00001"; SetPredefinedColor(str_sig, wxColour(240, 240, 240)); SetPredefinedColor(str_high, wxColour(255, 0, 0)); @@ -76,6 +77,7 @@ gs_coord(gs_coordinator), is_clust(is_clust_p) SetPredefinedColor(str_p001, wxColour(6, 196, 11)); SetPredefinedColor(str_p0001, wxColour(3, 116, 6)); SetPredefinedColor(str_p00001, wxColour(1, 70, 3)); + SetPredefinedColor(str_p000001, wxColour(0, 50, 2)); if (is_clust) { cat_classif_def.cat_classif_type = CatClassification::local_join_count_categories; @@ -121,14 +123,17 @@ wxString MLJCMapCanvas::GetCanvasTitle() { wxString new_title; - new_title << _("Local Join Count "); - - new_title << (is_clust ? "Cluster" : "Significance") << " Map "; - new_title << "(" << gs_coord->weight_name << "): "; - for (int i=0; inum_vars; i++) { - new_title << GetNameWithTime(i); - if (i < gs_coord->num_vars-1) { - new_title << ","; + if (is_quantile_lisa) { + new_title << template_frame->GetTitle(); + } else { + new_title << _("Local Join Count "); + new_title << (is_clust ? "Cluster" : "Significance") << " Map "; + new_title << "(" << gs_coord->weight_name << "): "; + for (int i=0; inum_vars; i++) { + new_title << GetNameWithTime(i); + if (i < gs_coord->num_vars-1) { + new_title << ","; + } } } new_title << wxString::Format(", pseudo p (%d perm)", gs_coord->permutations); @@ -233,174 +238,119 @@ void MLJCMapCanvas::CreateAndUpdateCategories() int undefined_cat = -1; int isolates_cat = -1; int num_cats = 0; - double stop_sig = 0; + int set_perm = gs_coord->permutations; + double stop_sig = 1.0 / (1.0 + set_perm); + double sig_cutoff = gs_coord->significance_cutoff; + bool is_cust_cutoff = gs_coord->GetSignificanceFilter() < 0; + bool has_isolates = gs_coord->GetHasIsolates(t); + bool has_undefined = gs_coord->GetHasUndefined(t); + wxString def_cats[NUM_SIG_CATS] = {str_p005, str_p001, str_p0001, str_p00001, str_p000001}; + double def_cutoffs[NUM_SIG_CATS] = {0.05, 0.01, 0.001, 0.0001, 0.00001}; + int cat_idx = 0; + std::map level_cat_dict; - if (gs_coord->GetHasIsolates(t)) { + if (has_isolates) { num_cats++; } - if (gs_coord->GetHasUndefined(t)) { + if (has_undefined) { num_cats++; } if (is_clust) { num_cats += 4; // 0 not sig 1 no loc 2 has loc 3 loc cluster + cat_data.CreateCategoriesAtCanvasTm(num_cats, t); + cat_data.SetCategoryLabel(t, cat_idx, str_sig); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_sig]); + cat_data.SetCategoryLabel(t, cat_idx, str_low); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_low]); + cat_data.SetCategoryLabel(t, cat_idx, str_med); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_med]); + cat_data.SetCategoryLabel(t, cat_idx, str_high); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_high]); } else { - int set_perm = gs_coord->permutations; - stop_sig = 1.0 / (1.0 + set_perm); - double sig_cutoff = gs_coord->significance_cutoff; - - if (gs_coord->GetSignificanceFilter() < 0) { - // user specified cutoff - num_cats += 2; + num_cats += 1; // not sig category + if (is_cust_cutoff) { + // user specified cutoff: Custom cutoff + num_cats += 1; } else { - num_cats += 6 - gs_coord->GetSignificanceFilter(); - - if ( sig_cutoff >= 0.0001 && stop_sig > 0.0001) { - num_cats -= 1; - } - if ( sig_cutoff >= 0.001 && stop_sig > 0.001 ) { - num_cats -= 1; - } - if ( sig_cutoff >= 0.01 && stop_sig > 0.01 ) { - num_cats -= 1; + for (int j=0; j < NUM_SIG_CATS; j++) { + if (sig_cutoff >= def_cutoffs[j] && stop_sig <= def_cutoffs[j]) { + num_cats += 1; + } } } - } - cat_data.CreateCategoriesAtCanvasTm(num_cats, t); - - if (is_clust) { - cat_data.SetCategoryLabel(t, 0, str_sig); - cat_data.SetCategoryColor(t, 0, lbl_color_dict[str_sig]); - cat_data.SetCategoryLabel(t, 1, str_low); - cat_data.SetCategoryColor(t, 1, lbl_color_dict[str_low]); - cat_data.SetCategoryLabel(t, 2, str_med); - cat_data.SetCategoryColor(t, 2, lbl_color_dict[str_med]); - cat_data.SetCategoryLabel(t, 3, str_high); - cat_data.SetCategoryColor(t, 3, lbl_color_dict[str_high]); + cat_data.CreateCategoriesAtCanvasTm(num_cats, t); - if (gs_coord->GetHasIsolates(t) && gs_coord->GetHasUndefined(t)) { - isolates_cat = 4; - undefined_cat = 5; - } else if (gs_coord->GetHasUndefined(t)) { - undefined_cat = 4; - } else if (gs_coord->GetHasIsolates(t)) { - isolates_cat = 4; - } + // set not sigificant category + cat_data.SetCategoryLabel(t, cat_idx, str_sig); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_sig]); - } else { - cat_data.SetCategoryLabel(t, 0, str_sig); - cat_data.SetCategoryColor(t, 0, lbl_color_dict[str_sig]); - - if (gs_coord->GetSignificanceFilter() < 0) { - // user specified cutoff - wxString lbl = wxString::Format("p = %g", gs_coord->significance_cutoff); - cat_data.SetCategoryLabel(t, 1, lbl); - cat_data.SetCategoryColor(t, 1, wxColour(3, 116, 6)); - - if (gs_coord->GetHasIsolates(t) && - gs_coord->GetHasUndefined(t)) - { - isolates_cat = 2; - undefined_cat = 3; - } else if (gs_coord->GetHasUndefined(t)) { - undefined_cat = 2; - } else if (gs_coord->GetHasIsolates(t)) { - isolates_cat = 2; - } + if (is_cust_cutoff) { + std::ostringstream ss_sig_cutoff; + ss_sig_cutoff << std::fixed << sig_cutoff; + wxString lbl = wxString::Format("p = %s", ss_sig_cutoff.str()); + cat_data.SetCategoryLabel(t, cat_idx, lbl); + cat_data.SetCategoryColor(t, cat_idx++, wxColour(3, 116, 6)); } else { - int s_f = gs_coord->GetSignificanceFilter(); - int set_perm = gs_coord->permutations; - stop_sig = 1.0 / (1.0 + set_perm); - - wxString def_cats[4] = {str_p005, str_p001, str_p0001, str_p00001}; - double def_cutoffs[4] = {0.05, 0.01, 0.001, 0.0001}; - - int cat_idx = 1; - for (int j=s_f-1; j < 4; j++) { - if (def_cutoffs[j] >= stop_sig) { - cat_data.SetCategoryLabel(t, cat_idx, def_cats[j]); - cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[def_cats[j]]); + for (int j=0; j < NUM_SIG_CATS; j++) { + if (sig_cutoff >= def_cutoffs[j] && stop_sig <= def_cutoffs[j]) { + level_cat_dict[j] = cat_idx; + cat_data.SetCategoryColor(t, cat_idx, lbl_color_dict[def_cats[j]]); + cat_data.SetCategoryLabel(t, cat_idx++, def_cats[j]); } } - if (gs_coord->GetHasIsolates(t) && - gs_coord->GetHasUndefined(t)) { - isolates_cat = cat_idx++; - undefined_cat = cat_idx++; - - } else if (gs_coord->GetHasUndefined(t)) { - undefined_cat = cat_idx++; - - } else if (gs_coord->GetHasIsolates(t)) { - isolates_cat = cat_idx++; - } } } - if (undefined_cat != -1) { - cat_data.SetCategoryLabel(t, undefined_cat, str_undefined); - cat_data.SetCategoryColor(t, undefined_cat, lbl_color_dict[str_undefined]); - } - if (isolates_cat != -1) { - cat_data.SetCategoryLabel(t, isolates_cat, str_neighborless); - cat_data.SetCategoryColor(t, isolates_cat, lbl_color_dict[str_neighborless]); + if (has_isolates) { + isolates_cat = cat_idx; + cat_data.SetCategoryLabel(t, cat_idx, str_neighborless); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_neighborless]); + } + if (has_undefined) { + undefined_cat = cat_idx; + cat_data.SetCategoryLabel(t, cat_idx, str_undefined); + cat_data.SetCategoryColor(t, cat_idx++, lbl_color_dict[str_undefined]); } gs_coord->FillClusterCats(t, cluster); if (is_clust) { - for (int i=0, iend=gs_coord->num_obs; inum_obs; i++) { if (cluster[i] == 0) { cat_data.AppendIdToCategory(t, 0, i); // not significant - } else if (cluster[i] == 4) { + } else if (cluster[i] == JCCoordinator::NEIGHBORLESS_CLUSTER) { cat_data.AppendIdToCategory(t, isolates_cat, i); - } else if (cluster[i] == 5) { + } else if (cluster[i] == JCCoordinator::UNDEFINED_CLUSTER) { cat_data.AppendIdToCategory(t, undefined_cat, i); } else { cat_data.AppendIdToCategory(t, cluster[i], i); } } } else { - double* p_val = gs_coord->sig_local_jc_vecs[t]; + double* p = gs_coord->sig_local_jc_vecs[t]; - if (gs_coord->GetSignificanceFilter() < 0) { - // user specified cutoff - int s_f = 1; - double sig_cutoff = gs_coord->significance_cutoff; - for (int i=0, iend=gs_coord->num_obs; inum_obs; i++) { + if (cluster[i] == JCCoordinator::NEIGHBORLESS_CLUSTER) { + cat_data.AppendIdToCategory(t, isolates_cat, i); + } else if (cluster[i] == JCCoordinator::UNDEFINED_CLUSTER) { + cat_data.AppendIdToCategory(t, undefined_cat, i); + } else if (cluster[i] == 0) { + cat_data.AppendIdToCategory(t, 0, i); // not significant + } else { + if (is_cust_cutoff) { + if (p[i] <= sig_cutoff) { cat_data.AppendIdToCategory(t, 1, i); - } else { - cat_data.AppendIdToCategory(t, 0, i); // not significant } - } - - } - } else { - int s_f = gs_coord->GetSignificanceFilter(); - for (int i=0, iend=gs_coord->num_obs; i= 0; c--) { + if (p[i] <= def_cutoffs[c]) { + cat_data.AppendIdToCategory(t, level_cat_dict[c], i); + break; + } + } } } } @@ -495,10 +445,11 @@ IMPLEMENT_CLASS(MLJCMapFrame, MapFrame) EVT_ACTIVATE(MLJCMapFrame::OnActivate) END_EVENT_TABLE() -MLJCMapFrame::MLJCMapFrame(wxFrame *parent, Project* project, JCCoordinator* gs_coordinator, bool isClusterMap, const wxPoint& pos, const wxSize& size, const long style) +MLJCMapFrame::MLJCMapFrame(wxFrame *parent, Project* project, JCCoordinator* gs_coordinator, bool is_cluster_map, bool is_quantile_lisa, const wxPoint& pos, const wxSize& size, const long style) : MapFrame(parent, project, pos, size, style), gs_coord(gs_coordinator), -is_clust(isClusterMap) +is_clust(is_cluster_map), +is_quantile_lisa(is_quantile_lisa) { wxLogMessage("Entering MLJCMapFrame::MLJCMapFrame"); @@ -514,7 +465,7 @@ is_clust(isClusterMap) splitter_win->SetMinimumPaneSize(10); wxPanel* rpanel = new wxPanel(splitter_win); - template_canvas = new MLJCMapCanvas(rpanel, this, is_clust, project, gs_coordinator); + template_canvas = new MLJCMapCanvas(rpanel, this, is_clust, project, gs_coordinator, is_quantile_lisa); template_canvas->SetScrollRate(1,1); wxBoxSizer* rbox = new wxBoxSizer(wxVERTICAL); rbox->Add(template_canvas, 1, wxEXPAND); diff --git a/Explore/MLJCMapNewView.h b/Explore/MLJCMapNewView.h index 4d61a34af..c82067876 100644 --- a/Explore/MLJCMapNewView.h +++ b/Explore/MLJCMapNewView.h @@ -40,6 +40,7 @@ class MLJCMapCanvas : public MapCanvas bool is_clust, Project* project, JCCoordinator* gs_coordinator, + bool is_quantile_lisa = false, const wxPoint& pos = wxDefaultPosition, const wxSize& size = wxDefaultSize); virtual ~MLJCMapCanvas(); @@ -62,7 +63,8 @@ class MLJCMapCanvas : public MapCanvas protected: JCCoordinator* gs_coord; bool is_clust; // true = cluster map, false = significance map - + bool is_quantile_lisa; + wxString str_sig; wxString str_high; wxString str_med; @@ -73,6 +75,9 @@ class MLJCMapCanvas : public MapCanvas wxString str_p001; wxString str_p0001; wxString str_p00001; + wxString str_p000001; + + const static int NUM_SIG_CATS = 5; DECLARE_EVENT_TABLE() }; @@ -84,7 +89,8 @@ class MLJCMapFrame : public MapFrame, public JCCoordinatorObserver MLJCMapFrame(wxFrame *parent, Project* project, JCCoordinator* gs_coordinator, - bool isClusterMap, + bool is_cluster_map, + bool is_quantile_lisa = false, const wxPoint& pos = wxDefaultPosition, const wxSize& size = GdaConst::map_default_size, const long style = wxDEFAULT_FRAME_STYLE); @@ -132,7 +138,8 @@ class MLJCMapFrame : public MapFrame, public JCCoordinatorObserver void CoreSelectHelper(const std::vector& elem); JCCoordinator* gs_coord; bool is_clust; // true = cluster map, false = significance map - + bool is_quantile_lisa; + DECLARE_EVENT_TABLE() }; diff --git a/Explore/PCPNewView.cpp b/Explore/PCPNewView.cpp index bf6e96594..4a525d032 100644 --- a/Explore/PCPNewView.cpp +++ b/Explore/PCPNewView.cpp @@ -64,8 +64,7 @@ num_time_vals(1), num_vars(v_info.size()), data(v_info.size()), data_undef(v_info.size()), custom_classif_state(0), display_stats(false), show_axes(true), standardized(false), -pcp_selectstate(pcp_start), show_pcp_control(false), -overall_abs_max_std_exists(false), theme_var(0), +pcp_selectstate(pcp_start), show_pcp_control(false), theme_var(0), num_categories(6), all_init(false) { LOG_MSG("Entering PCPCanvas::PCPCanvas"); @@ -84,6 +83,9 @@ num_categories(6), all_init(false) max_ts = ts; } undef_markers.resize(max_ts); + overall_abs_max_std_exists.resize(max_ts, false); + overall_abs_max_std.resize(max_ts); + overall_abs_min_std.resize(max_ts); for (int t=0; tGetColUndefined(col_ids[v], data_undef[v]); int data_times = data[v].shape()[0]; data_stats[v].resize(data_times); - - std::vector temp_vec; - - for (int t=0; t temp_vec; for (int i=0; i overall_abs_max_std) { - overall_abs_max_std = abs_max; - } + if (!overall_abs_max_std_exists[t]) { + overall_abs_max_std_exists[t] = true; + overall_abs_max_std[t] = s_max; + overall_abs_min_std[t] = s_min; + } else if (s_max > overall_abs_max_std[t]) { + overall_abs_max_std[t] = s_max; + } else if (s_min < overall_abs_min_std[t]) { + overall_abs_min_std[t] = s_min; + } } } } @@ -485,32 +491,43 @@ void PCPCanvas::PopulateCanvas() GdaShape* s = 0; wxRealPoint* pts = new wxRealPoint[num_vars]; + + int t = project->GetTimeState()->GetCurrTime(); + double std_fact = 1; - if (overall_abs_max_std_exists) std_fact = 100.0/(2.0*overall_abs_max_std); + if (overall_abs_max_std_exists[t]) { + std_fact = 100.0/(overall_abs_max_std[t] - overall_abs_min_std[t]); + } double nvf = 100.0/((double) (num_vars-1)); for (int i=0; iGetSize(dc, s_w, s_h); if (s_w > max_label_width) max_label_width = s_w; foreground_shps.push_back(s); - int sd_abs = overall_abs_max_std; - for (int i=1; i<=sd_abs && overall_abs_max_std_exists; i++) { - double sd_p = (double) i; - sd_p += overall_abs_max_std; - sd_p *= std_fact; - double sd_m = (double) -i; - sd_m += overall_abs_max_std; - sd_m *= std_fact; + int sd_left = (int)overall_abs_min_std[t]; + int sd_right = (int)overall_abs_max_std[t]; + for (int i = sd_left; i <= sd_right && overall_abs_max_std_exists[t]; i++) { + double sd_p = (i - overall_abs_min_std[t]) * std_fact; s = new GdaPolyLine(sd_p, 0, sd_p, 100); s->setPen(*GdaConst::scatterplot_origin_axes_pen); foreground_shps.push_back(s); @@ -624,15 +637,6 @@ void PCPCanvas::PopulateCanvas() *GdaConst::small_font, wxRealPoint(sd_p, 0), 0, GdaShapeText::h_center, GdaShapeText::v_center, 0, 12); ((GdaShapeText*)s)->GetSize(dc, s_w, s_h); - if (s_w > max_label_width) max_label_width = s_w; - foreground_shps.push_back(s); - s = new GdaPolyLine(sd_m, 0, sd_m, 100); - s->setPen(*GdaConst::scatterplot_origin_axes_pen); - foreground_shps.push_back(s); - s = new GdaShapeText(wxString::Format("%d", -i), - *GdaConst::small_font, wxRealPoint(sd_m, 0), 0, - GdaShapeText::h_center, GdaShapeText::v_center, 0, 12); - ((GdaShapeText*)s)->GetSize(dc, s_w, s_h); if (s_w > max_label_width) max_label_width = s_w; foreground_shps.push_back(s); } @@ -796,7 +800,7 @@ void PCPCanvas::TimeSyncVariableToggle(int var_index) void PCPCanvas::FixedScaleVariableToggle(int var_index) { - var_info[var_index].fixed_scale = !var_info[var_index].fixed_scale; + var_info[var_index].fixed_scale = false; // !var_info[var_index].fixed_scale; VarInfoAttributeChange(); invalidateBms(); PopulateCanvas(); diff --git a/Explore/PCPNewView.h b/Explore/PCPNewView.h index c53007294..c57665f20 100644 --- a/Explore/PCPNewView.h +++ b/Explore/PCPNewView.h @@ -116,8 +116,9 @@ class PCPCanvas : public TemplateCanvas, public CatClassifStateObserver //std::vector< std::vector > hinge_stats; std::vector< std::vector > data_stats; // overall absolute value maximum of standardized data - double overall_abs_max_std; - double overall_abs_max_std_exists; + std::vector overall_abs_min_std; + std::vector overall_abs_max_std; + std::vector overall_abs_max_std_exists; bool is_any_time_variant; bool is_any_sync_with_global_time; std::vector cats_valid; // cats diff --git a/version.h b/version.h index 251595714..040af623a 100644 --- a/version.h +++ b/version.h @@ -2,9 +2,9 @@ namespace Gda { const int version_major = 1; const int version_minor = 20; const int version_build = 0; - const int version_subbuild = 24; + const int version_subbuild = 32; const int version_year = 2022; - const int version_month = 10; + const int version_month = 12; const int version_day = 30; const int version_night = 0; const int version_type = 2; // 0: alpha, 1: beta, 2: release