From 8f331fdf6acf38e839a43b54f7427257cb461ff6 Mon Sep 17 00:00:00 2001
From: Matthew D Jones <matthew.d.jones@tessella.com>
Date: Fri, 27 Nov 2015 13:53:24 +0000
Subject: [PATCH] Re #14523 Masked data in MDWorkspaces displayed as NaN in
 SliceViewer

---
 Framework/API/inc/MantidAPI/IMDWorkspace.h    |  6 +++
 Framework/API/inc/MantidAPI/MatrixWorkspace.h |  4 ++
 Framework/API/src/MatrixWorkspace.cpp         | 14 +++++++
 .../inc/MantidDataObjects/MDEventWorkspace.h  |  8 ++++
 .../MantidDataObjects/MDEventWorkspace.tcc    | 38 ++++++++++++++++---
 .../inc/MantidDataObjects/MDHistoWorkspace.h  |  6 +++
 .../DataObjects/src/MDHistoWorkspace.cpp      | 22 +++++++++--
 MantidQt/API/src/QwtRasterDataMD.cpp          |  4 +-
 8 files changed, 92 insertions(+), 10 deletions(-)

diff --git a/Framework/API/inc/MantidAPI/IMDWorkspace.h b/Framework/API/inc/MantidAPI/IMDWorkspace.h
index 2d5a6819ddb..7359b2e27bf 100644
--- a/Framework/API/inc/MantidAPI/IMDWorkspace.h
+++ b/Framework/API/inc/MantidAPI/IMDWorkspace.h
@@ -101,6 +101,12 @@ public:
   getSignalAtCoord(const coord_t *coords,
                    const Mantid::API::MDNormalization &normalization) const = 0;
 
+  /// Returns the (normalized) signal at a given coordinates or NaN if the value
+  // is masked, used for plotting
+  virtual signal_t
+    getSignalWithMaskAtCoord(const coord_t *coords,
+                     const Mantid::API::MDNormalization &normalization) const = 0;
+
   /// Method to generate a line plot through a MD-workspace
   virtual void getLinePlot(const Mantid::Kernel::VMD &start,
                            const Mantid::Kernel::VMD &end,
diff --git a/Framework/API/inc/MantidAPI/MatrixWorkspace.h b/Framework/API/inc/MantidAPI/MatrixWorkspace.h
index aeed3918118..f6cc31df146 100644
--- a/Framework/API/inc/MantidAPI/MatrixWorkspace.h
+++ b/Framework/API/inc/MantidAPI/MatrixWorkspace.h
@@ -418,6 +418,10 @@ public:
   virtual signal_t
   getSignalAtCoord(const coord_t *coords,
                    const Mantid::API::MDNormalization &normalization) const;
+  /// Get the signal at a coordinate in the workspace
+  virtual signal_t
+    getSignalWithMaskAtCoord(const coord_t *coords,
+                             const Mantid::API::MDNormalization &normalization) const;
   /// Create iterators. Partitions the iterators according to the number of
   /// cores.
   virtual std::vector<IMDIterator *>
diff --git a/Framework/API/src/MatrixWorkspace.cpp b/Framework/API/src/MatrixWorkspace.cpp
index 10ce0e137d6..aa101d29b68 100644
--- a/Framework/API/src/MatrixWorkspace.cpp
+++ b/Framework/API/src/MatrixWorkspace.cpp
@@ -1601,6 +1601,20 @@ signal_t MatrixWorkspace::getSignalAtCoord(
     return std::numeric_limits<double>::quiet_NaN();
 }
 
+//------------------------------------------------------------------------------------
+/** Returns the (normalized) signal at a given coordinates
+ * Implementation differs from getSignalAtCoord for MD workspaces
+*
+* @param coords :: bare array, size 2, of coordinates. X, Y
+* @param normalization :: how to normalize the signal
+* @return normalized signal.
+*/
+signal_t
+MatrixWorkspace::getSignalWithMaskAtCoord(const coord_t *coords,
+                           const Mantid::API::MDNormalization &normalization) const {
+  return getSignalAtCoord(coords, normalization);
+}
+
 //--------------------------------------------------------------------------------------------
 /** Save the spectra detector map to an open NeXus file.
 * @param file :: open NeXus file
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h
index d2662f5096b..9a491c56714 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.h
@@ -76,6 +76,14 @@ public:
   getSignalAtCoord(const coord_t *coords,
                    const Mantid::API::MDNormalization &normalization) const;
 
+  /// Returns the (normalized) signal at a given coordinates
+  // or NaN if masked
+  virtual signal_t
+    getSignalWithMaskAtCoord(const coord_t *coords,
+                     const Mantid::API::MDNormalization &normalization) const;
+
+  bool isInBounds(const coord_t *coords) const;
+
   virtual void getLinePlot(const Mantid::Kernel::VMD &start,
                            const Mantid::Kernel::VMD &end,
                            API::MDNormalization normalize,
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc
index 4050994a565..f4683de3c8d 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDEventWorkspace.tcc
@@ -273,11 +273,8 @@ TMDE(std::vector<Mantid::API::IMDIterator *> MDEventWorkspace)::createIterators(
 TMDE(signal_t MDEventWorkspace)::getSignalAtCoord(
     const coord_t *coords,
     const Mantid::API::MDNormalization &normalization) const {
-  // Do an initial bounds check
-  for (size_t d = 0; d < nd; d++) {
-    coord_t x = coords[d];
-    if (data->getExtents(d).outside(x))
-      return std::numeric_limits<signal_t>::quiet_NaN();
+  if (!isInBounds(coords)) {
+    return std::numeric_limits<signal_t>::quiet_NaN();
   }
   // If you got here, then the point is in the workspace.
   const API::IMDNode *box = data->getBoxAtCoord(coords);
@@ -297,6 +294,37 @@ TMDE(signal_t MDEventWorkspace)::getSignalAtCoord(
     return std::numeric_limits<signal_t>::quiet_NaN();
 }
 
+TMDE(bool MDEventWorkspace)::isInBounds(const coord_t *coords) const {
+  for (size_t d = 0; d < nd; d++) {
+    coord_t x = coords[d];
+    if (data->getExtents(d).outside(x))
+      return false;
+  }
+  return true;
+}
+
+//----------------------------------------------------------------------------------------------
+/** Get the signal at a particular coordinate in the workspace
+ * or return NaN if masked
+ *
+ * @param coords :: numDimensions-sized array of the coordinates to look at
+ * @param normalization : Normalisation to use.
+ * @return the (normalized) signal at a given coordinates.
+ *         NaN if outside the range of this workspace
+ */
+TMDE(signal_t MDEventWorkspace)::getSignalWithMaskAtCoord(const coord_t *coords,
+                                           const Mantid::API::MDNormalization &normalization) const {
+  if (!isInBounds(coords)) {
+    return std::numeric_limits<signal_t>::quiet_NaN();
+  }
+  // Check if masked
+  const API::IMDNode *box = data->getBoxAtCoord(coords);
+  if (box->getIsMasked()) {
+    return std::numeric_limits<signal_t>::quiet_NaN();
+  }
+  return getSignalAtCoord(coords, normalization);
+}
+
 //-----------------------------------------------------------------------------------------------
 /** Get a vector of the minimum extents that still contain all the events in the
  *workspace.
diff --git a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h
index 3608d17aa93..8c7cd897a97 100644
--- a/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h
+++ b/Framework/DataObjects/inc/MantidDataObjects/MDHistoWorkspace.h
@@ -175,6 +175,12 @@ public:
   getSignalAtCoord(const coord_t *coords,
                    const Mantid::API::MDNormalization &normalization) const;
 
+  /// Returns the (normalized) signal at a given coordinates
+  // or NaN if masked
+  virtual signal_t
+    getSignalWithMaskAtCoord(const coord_t *coords,
+                             const Mantid::API::MDNormalization &normalization) const;
+
   /// Sets the signal at the specified index.
   void setSignalAt(size_t index, signal_t value) { m_signals[index] = value; }
 
diff --git a/Framework/DataObjects/src/MDHistoWorkspace.cpp b/Framework/DataObjects/src/MDHistoWorkspace.cpp
index c8f225f6889..7be6d0c6287 100644
--- a/Framework/DataObjects/src/MDHistoWorkspace.cpp
+++ b/Framework/DataObjects/src/MDHistoWorkspace.cpp
@@ -368,9 +368,6 @@ signal_t MDHistoWorkspace::getSignalAtCoord(
     const coord_t *coords,
     const Mantid::API::MDNormalization &normalization) const {
   size_t linearIndex = this->getLinearIndexAtCoord(coords);
-  if (this->getIsMaskedAt(linearIndex)) {
-    return std::numeric_limits<signal_t>::quiet_NaN();
-  }
   if (linearIndex < m_length) {
     // What is our normalization factor?
     switch (normalization) {
@@ -387,6 +384,25 @@ signal_t MDHistoWorkspace::getSignalAtCoord(
     return std::numeric_limits<signal_t>::quiet_NaN();
 }
 
+//----------------------------------------------------------------------------------------------
+/** Get the signal at a particular coordinate in the workspace
+ * or return NaN if masked
+ *
+ * @param coords :: numDimensions-sized array of the coordinates to look at
+ * @param normalization : Normalisation to use.
+ * @return the (normalized) signal at a given coordinates.
+ *         NaN if outside the range of this workspace
+ */
+signal_t
+MDHistoWorkspace::getSignalWithMaskAtCoord(const coord_t *coords,
+                           const Mantid::API::MDNormalization &normalization) const {
+  size_t linearIndex = this->getLinearIndexAtCoord(coords);
+  if (this->getIsMaskedAt(linearIndex)) {
+    return std::numeric_limits<signal_t>::quiet_NaN();
+  }
+  return getSignalAtCoord(coords, normalization);
+}
+
 //----------------------------------------------------------------------------------------------
 /** Get the linear index into the histo array at these coordinates
  *
diff --git a/MantidQt/API/src/QwtRasterDataMD.cpp b/MantidQt/API/src/QwtRasterDataMD.cpp
index 1a1267c3382..e5e98e3e190 100644
--- a/MantidQt/API/src/QwtRasterDataMD.cpp
+++ b/MantidQt/API/src/QwtRasterDataMD.cpp
@@ -88,12 +88,12 @@ double QwtRasterDataMD::value(double x, double y) const
       && (y >= m_overlayYMin) && (y < m_overlayYMax))
   {
     // Point is in the overlaid workspace
-    value = m_overlayWS->getSignalAtCoord(lookPoint, m_normalization);
+    value = m_overlayWS->getSignalWithMaskAtCoord(lookPoint, m_normalization);
   }
   else
   {
     // No overlay, or not within range of that workspace
-    value = m_ws->getSignalAtCoord(lookPoint, m_normalization);
+    value = m_ws->getSignalWithMaskAtCoord(lookPoint, m_normalization);
   }
   delete [] lookPoint;
 
-- 
GitLab