diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindNeighborhoods.cpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindNeighborhoods.cpp index 7d5facbd67..a1625c5ab6 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindNeighborhoods.cpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindNeighborhoods.cpp @@ -12,67 +12,77 @@ using namespace complex; class FindNeighborhoodsImpl { public: - FindNeighborhoodsImpl(FindNeighborhoods* filter, size_t totalFeatures, const Float32Array& centroids, const std::vector& bins, const std::vector& criticalDistance) + FindNeighborhoodsImpl(FindNeighborhoods* filter, usize totalFeatures, const std::vector& bins, const std::vector& criticalDistance, const std::atomic_bool& shouldCancel) : m_Filter(filter) , m_TotalFeatures(totalFeatures) - , m_Centroids(centroids) , m_Bins(bins) , m_CriticalDistance(criticalDistance) + , m_ShouldCancel(shouldCancel) { } - void convert(size_t start, size_t end) const + void convert(usize start, usize end) const { - int64_t bin1x = 0, bin2x = 0, bin1y = 0, bin2y = 0, bin1z = 0, bin2z = 0; - float dBinX = 0, dBinY = 0, dBinZ = 0; - float criticalDistance1 = 0, criticalDistance2 = 0; + int64 bin1x, bin2x, bin1y, bin2y, bin1z, bin2z; + float32 dBinX, dBinY, dBinZ; + float32 criticalDistance1, criticalDistance2; - size_t increment = (end - start) / 100; - size_t incCount = 0; + auto increment = static_cast(end - start) / 100.0; + float64 incCount = 0.0; // NEVER start at 0. if(start == 0) { start = 1; } - for(size_t i = start; i < end; i++) + + auto startTime = std::chrono::steady_clock::now(); + for(usize featureIdx = start; featureIdx < end; featureIdx++) { incCount++; - if(incCount == increment || i == end - 1) + if(incCount >= increment) { - incCount = 0; - m_Filter->updateProgress(increment, m_TotalFeatures); + auto now = std::chrono::steady_clock::now(); + if(std::chrono::duration_cast(now - startTime).count() > 1000) + { + incCount = 0; + m_Filter->updateProgress(incCount, now); + startTime = now; + } } - if(m_Filter->getCancel()) + + if(m_ShouldCancel) { - break; + return; } - bin1x = m_Bins[3 * i]; - bin1y = m_Bins[3 * i + 1]; - bin1z = m_Bins[3 * i + 2]; - criticalDistance1 = m_CriticalDistance[i]; - for(size_t j = i + 1; j < m_TotalFeatures; j++) + bin1x = m_Bins[3 * featureIdx]; + bin1y = m_Bins[3 * featureIdx + 1]; + bin1z = m_Bins[3 * featureIdx + 2]; + criticalDistance1 = m_CriticalDistance[featureIdx]; + + for(usize j = featureIdx + 1; j < m_TotalFeatures; j++) { bin2x = m_Bins[3 * j]; bin2y = m_Bins[3 * j + 1]; bin2z = m_Bins[3 * j + 2]; criticalDistance2 = m_CriticalDistance[j]; - dBinX = std::abs(bin2x - bin1x); - dBinY = std::abs(bin2y - bin1y); - dBinZ = std::abs(bin2z - bin1z); + dBinX = std::abs(static_cast(bin2x - bin1x)); + dBinY = std::abs(static_cast(bin2y - bin1y)); + dBinZ = std::abs(static_cast(bin2z - bin1z)); if(dBinX < criticalDistance1 && dBinY < criticalDistance1 && dBinZ < criticalDistance1) { - m_Filter->updateNeighborHood(i, j); + m_Filter->updateNeighborHood(featureIdx, j); } if(dBinX < criticalDistance2 && dBinY < criticalDistance2 && dBinZ < criticalDistance2) { - m_Filter->updateNeighborHood(j, i); + m_Filter->updateNeighborHood(j, featureIdx); } } } + m_Filter->updateProgress(incCount); } void operator()(const Range& range) const @@ -82,10 +92,10 @@ class FindNeighborhoodsImpl private: FindNeighborhoods* m_Filter = nullptr; - size_t m_TotalFeatures = 0; - const Float32Array& m_Centroids; - const std::vector& m_Bins; - const std::vector& m_CriticalDistance; + usize m_TotalFeatures = 0; + const std::vector& m_Bins; + const std::vector& m_CriticalDistance; + const std::atomic_bool& m_ShouldCancel; }; // ----------------------------------------------------------------------------- @@ -107,7 +117,7 @@ const std::atomic_bool& FindNeighborhoods::getCancel() } // ----------------------------------------------------------------------------- -void FindNeighborhoods::updateNeighborHood(size_t sourceIndex, size_t destIndex) +void FindNeighborhoods::updateNeighborHood(usize sourceIndex, usize destIndex) { const std::lock_guard lock(m_Mutex); (*m_Neighborhoods)[sourceIndex]++; @@ -117,26 +127,27 @@ void FindNeighborhoods::updateNeighborHood(size_t sourceIndex, size_t destIndex) // ----------------------------------------------------------------------------- // // ----------------------------------------------------------------------------- -void FindNeighborhoods::updateProgress(size_t numCompleted, size_t totalFeatures) +void FindNeighborhoods::updateProgress(float64 counter, const std::chrono::steady_clock::time_point& now) { const std::lock_guard lock(m_Mutex); - m_IncCount += numCompleted; - m_NumCompleted = m_NumCompleted + numCompleted; - if(m_IncCount > m_ProgIncrement) + + m_ProgressCounter += counter; + + if(std::chrono::duration_cast(now - m_InitialTime).count() > 1000) // every second update { - m_IncCount = 0; - m_MessageHandler(IFilter::Message::Type::Info, fmt::format("Working on Feature {} of {}", m_NumCompleted, totalFeatures)); + auto progressInt = static_cast((m_ProgressCounter / m_TotalFeatures) * 100.0); + std::string progressMessage = "Finding Feature Neighborhoods:"; + m_MessageHandler(IFilter::ProgressMessage{IFilter::Message::Type::Progress, progressMessage, progressInt}); + m_InitialTime = std::chrono::steady_clock::now(); } } // ----------------------------------------------------------------------------- Result<> FindNeighborhoods::operator()() { - m_IncCount = 0; + // m_ProgressCounter initialized to zero on filter creation - float x = 0.0f, y = 0.0f, z = 0.0f; - m_NumCompleted = 0; - std::vector criticalDistance; + std::vector criticalDistance; auto multiplesOfAverage = m_InputValues->MultiplesOfAverage; const auto& equivalentDiameters = m_DataStructure.getDataRefAs(m_InputValues->EquivalentDiametersArrayPath); @@ -144,58 +155,50 @@ Result<> FindNeighborhoods::operator()() m_Neighborhoods = m_DataStructure.getDataAs(m_InputValues->NeighborhoodsArrayName); - size_t totalFeatures = equivalentDiameters.getNumberOfTuples(); - - m_ProgIncrement = totalFeatures / 100; + usize totalFeatures = equivalentDiameters.getNumberOfTuples(); + m_TotalFeatures = static_cast(totalFeatures); // Pre-cast to save time in lock later m_LocalNeighborhoodList.resize(totalFeatures); criticalDistance.resize(totalFeatures); - float aveDiam = 0.0f; - for(size_t i = 1; i < totalFeatures; i++) + float32 aveDiam = 0.0f; + for(usize i = 1; i < totalFeatures; i++) { (*m_Neighborhoods)[i] = 0; aveDiam += equivalentDiameters[i]; criticalDistance[i] = equivalentDiameters[i] * multiplesOfAverage; } - aveDiam /= totalFeatures; - for(size_t i = 1; i < totalFeatures; i++) + aveDiam /= static_cast(totalFeatures); + for(usize i = 1; i < totalFeatures; i++) { criticalDistance[i] /= aveDiam; } - auto* gridGeom = m_DataStructure.getDataAs(m_InputValues->InputImageGeometry); - - FloatVec3 origin = gridGeom->getOrigin(); - - size_t xbin = 0, ybin = 0, zbin = 0; - std::vector bins(3 * totalFeatures, 0); - for(size_t i = 1; i < totalFeatures; i++) + std::vector bins(3 * totalFeatures, 0); + FloatVec3 origin = m_DataStructure.getDataAs(m_InputValues->InputImageGeometry)->getOrigin(); + for(usize i = 1; i < totalFeatures; i++) { - x = centroids[3 * i]; - y = centroids[3 * i + 1]; - z = centroids[3 * i + 2]; - xbin = static_cast((x - origin[0]) / aveDiam); - ybin = static_cast((y - origin[1]) / aveDiam); - zbin = static_cast((z - origin[2]) / aveDiam); - bins[3 * i] = static_cast(xbin); - bins[3 * i + 1] = static_cast(ybin); - bins[3 * i + 2] = static_cast(zbin); + float32 x = centroids[3 * i]; + float32 y = centroids[3 * i + 1]; + float32 z = centroids[3 * i + 2]; + bins[3 * i] = static_cast((x - origin[0]) / aveDiam); // x-Bin + bins[3 * i + 1] = static_cast((y - origin[1]) / aveDiam); // y-Bin + bins[3 * i + 2] = static_cast((z - origin[2]) / aveDiam); // z-Bin } ParallelDataAlgorithm parallelAlgorithm; parallelAlgorithm.setRange(Range(0, totalFeatures)); - parallelAlgorithm.setParallelizationEnabled(false); - parallelAlgorithm.execute(FindNeighborhoodsImpl(this, totalFeatures, centroids, bins, criticalDistance)); + parallelAlgorithm.setParallelizationEnabled(true); + parallelAlgorithm.execute(FindNeighborhoodsImpl(this, totalFeatures, bins, criticalDistance, m_ShouldCancel)); // Output Variables auto& outputNeighborList = m_DataStructure.getDataRefAs>(m_InputValues->NeighborhoodListArrayName); // Set the vector for each list into the NeighborList Object - for(size_t i = 1; i < totalFeatures; i++) + for(usize i = 1; i < totalFeatures; i++) { // Construct a shared vector through the std::vector<> copy constructor. - NeighborList::SharedVectorType sharedMisorientationList(new std::vector(m_LocalNeighborhoodList[i])); - outputNeighborList.setList(static_cast(i), sharedMisorientationList); + NeighborList::SharedVectorType sharedMisOrientationList(new std::vector(m_LocalNeighborhoodList[i])); + outputNeighborList.setList(static_cast(i), sharedMisOrientationList); } m_LocalNeighborhoodList.clear(); diff --git a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindNeighborhoods.hpp b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindNeighborhoods.hpp index 550b5900d8..9af1048f6d 100644 --- a/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindNeighborhoods.hpp +++ b/src/Plugins/ComplexCore/src/ComplexCore/Filters/Algorithms/FindNeighborhoods.hpp @@ -45,8 +45,8 @@ class COMPLEXCORE_EXPORT FindNeighborhoods const std::atomic_bool& getCancel(); - void updateNeighborHood(size_t sourceIndex, size_t targetIndex); - void updateProgress(size_t numCompleted, size_t totalFeatures); + void updateNeighborHood(usize sourceIndex, usize targetIndex); + void updateProgress(float64 counter, const std::chrono::steady_clock::time_point& now = std::chrono::steady_clock::now()); private: DataStructure& m_DataStructure; @@ -55,12 +55,12 @@ class COMPLEXCORE_EXPORT FindNeighborhoods const IFilter::MessageHandler& m_MessageHandler; std::mutex m_Mutex; + std::chrono::steady_clock::time_point m_InitialTime = std::chrono::steady_clock::now(); + float64 m_TotalFeatures = 0; + float64 m_ProgressCounter = 0; Int32Array* m_Neighborhoods = nullptr; std::vector> m_LocalNeighborhoodList; - size_t m_NumCompleted = 0; - size_t m_ProgIncrement = 0; - size_t m_IncCount = 0; }; } // namespace complex