From e9c6fd094c836124332a0e0df31e5ed8808221be Mon Sep 17 00:00:00 2001
From: Michael Wedel <michael.wedel@esss.se>
Date: Wed, 8 Mar 2017 07:45:21 +0100
Subject: [PATCH] Refs #19049. Improve PointGroup performance

---
 .../inc/MantidGeometry/Crystal/PointGroup.h   |  2 +-
 Framework/Geometry/src/Crystal/PointGroup.cpp | 34 +++++++++++--------
 2 files changed, 20 insertions(+), 16 deletions(-)

diff --git a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h
index 9c65a1294ef..d24e34d0112 100644
--- a/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h
+++ b/Framework/Geometry/inc/MantidGeometry/Crystal/PointGroup.h
@@ -63,7 +63,7 @@ public:
   Kernel::V3D getReflectionFamily(const Kernel::V3D &hkl) const;
 
 protected:
-  std::vector<Kernel::V3D> getEquivalentSet(const Kernel::V3D &hkl) const;
+  std::vector<Kernel::V3D> getAllEquivalents(const Kernel::V3D &hkl) const;
 
   CrystalSystem getCrystalSystemFromGroup() const;
   LatticeSystem getLatticeSystemFromCrystalSystemAndGroup(
diff --git a/Framework/Geometry/src/Crystal/PointGroup.cpp b/Framework/Geometry/src/Crystal/PointGroup.cpp
index b5b0bdab0d7..24bfef2362c 100644
--- a/Framework/Geometry/src/Crystal/PointGroup.cpp
+++ b/Framework/Geometry/src/Crystal/PointGroup.cpp
@@ -31,7 +31,14 @@ using Kernel::IntMatrix;
  * @return :: std::vector containing all equivalent hkls.
  */
 std::vector<V3D> PointGroup::getEquivalents(const V3D &hkl) const {
-  return getEquivalentSet(hkl);
+  auto equivalents = getAllEquivalents(hkl);
+
+  std::sort(equivalents.begin(), equivalents.end(), std::greater<V3D>());
+
+  equivalents.erase(std::unique(equivalents.begin(), equivalents.end()),
+                    equivalents.end());
+
+  return equivalents;
 }
 
 /**
@@ -48,7 +55,9 @@ std::vector<V3D> PointGroup::getEquivalents(const V3D &hkl) const {
  * @return :: hkl specific to a family of index-triplets
  */
 V3D PointGroup::getReflectionFamily(const Kernel::V3D &hkl) const {
-  return *getEquivalentSet(hkl).begin();
+  auto equivalents = getAllEquivalents(hkl);
+
+  return *std::max_element(equivalents.begin(), equivalents.end());
 }
 
 /// Protected constructor - can not be used directly.
@@ -65,9 +74,9 @@ std::string PointGroup::getSymbol() const { return m_symbolHM; }
 
 bool PointGroup::isEquivalent(const Kernel::V3D &hkl,
                               const Kernel::V3D &hkl2) const {
-  std::vector<V3D> hklEquivalents = getEquivalentSet(hkl);
+  auto hklEquivalents = getAllEquivalents(hkl);
 
-  return (std::find(hklEquivalents.begin(), hklEquivalents.end(), hkl2) !=
+  return (std::find(hklEquivalents.cbegin(), hklEquivalents.cend(), hkl2) !=
           hklEquivalents.end());
 }
 
@@ -75,29 +84,24 @@ bool PointGroup::isEquivalent(const Kernel::V3D &hkl,
  * Generates a set of hkls
  *
  * This method applies all transformation matrices to the supplied hkl and puts
- * it into a set, which is returned in the end. Using a set ensures that each
- * hkl occurs once and only once. This set is the set of equivalent hkls,
- * specific to a concrete point group.
+ * them into a vector, which is returned in the end. For special reflections
+ * such as 100 or 110 or 111, the vector may contain duplicates that need to
+ * be filtered out.
  *
  * The symmetry operations need to be set prior to calling this method by a call
  * to PointGroup::setTransformationMatrices.
  *
  * @param hkl :: Arbitrary hkl
- * @return :: set of hkls.
+ * @return :: vector of hkls.
  */
-std::vector<V3D> PointGroup::getEquivalentSet(const Kernel::V3D &hkl) const {
+std::vector<V3D> PointGroup::getAllEquivalents(const Kernel::V3D &hkl) const {
   std::vector<V3D> equivalents;
   equivalents.reserve(m_allOperations.size());
 
   for (const auto &operation : m_allOperations) {
-    equivalents.push_back(operation.transformHKL(hkl));
+    equivalents.emplace_back(operation.transformHKL(hkl));
   }
 
-  std::sort(equivalents.begin(), equivalents.end(), std::greater<V3D>());
-
-  equivalents.erase(std::unique(equivalents.begin(), equivalents.end()),
-                    equivalents.end());
-
   return equivalents;
 }
 
-- 
GitLab