From 75c0f607d0df34733cba4f90ff9dd25944d46b86 Mon Sep 17 00:00:00 2001
From: Janik Zikovsky <zikovskyjl@ornl.gov>
Date: Wed, 13 Jul 2011 20:41:01 +0000
Subject: [PATCH] Refs #3316: Make sure boxes have sequential IDs for saving.
 Fix Mac build.

---
 .../Framework/MDEvents/src/LoadMDEW.cpp       |  4 +-
 .../Framework/MDEvents/src/MDGridBox.cpp      | 49 +++++++++++--------
 .../Framework/MDEvents/src/SaveMDEW.cpp       | 13 ++++-
 .../Framework/MDEvents/test/LoadMDEWTest.h    |  7 +++
 .../Framework/MDEvents/test/MDGridBoxTest.h   | 17 ++++++-
 5 files changed, 64 insertions(+), 26 deletions(-)

diff --git a/Code/Mantid/Framework/MDEvents/src/LoadMDEW.cpp b/Code/Mantid/Framework/MDEvents/src/LoadMDEW.cpp
index 64e535a0083..151574196d2 100644
--- a/Code/Mantid/Framework/MDEvents/src/LoadMDEW.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/LoadMDEW.cpp
@@ -76,7 +76,7 @@ namespace MDEvents
 
     file->openGroup("workspace", "NXworkspace");
 
-    std::vector<size_t> vecDims;
+    std::vector<int32_t> vecDims;
     file->readData("dimensions", vecDims);
     if (vecDims.empty())
       throw std::runtime_error("LoadMDEW:: Error loading number of dimensions.");
@@ -270,7 +270,7 @@ namespace MDEvents
     bc->setMaxId(numBoxes);
     // Refresh cache
     ws->refreshCache();
-    std::cout << ws->getNPoints() << " points after refresh." << std::endl;
+    if (verbose) std::cout << tim << " to refreshCache(). " << ws->getNPoints() << " points after refresh." << std::endl;
 
     file->closeGroup();
     file->close();
diff --git a/Code/Mantid/Framework/MDEvents/src/MDGridBox.cpp b/Code/Mantid/Framework/MDEvents/src/MDGridBox.cpp
index bd4b2d6aab2..f66d2c5b064 100644
--- a/Code/Mantid/Framework/MDEvents/src/MDGridBox.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/MDGridBox.cpp
@@ -95,32 +95,39 @@ namespace MDEvents
 
     size_t indices[nd];
     for (size_t d=0; d<nd; d++) indices[d] = 0;
-    for (size_t i=0; i<tot; i++)
-    {
-      // Create the box
-      // (Increase the depth of this box to one more than the parent (this))
-      MDBox<MDE,nd> * myBox = new MDBox<MDE,nd>(bc, this->m_depth + 1);
 
-      // Set the extents of this box.
-      for (size_t d=0; d<nd; d++)
+    // Splitting an input MDBox requires creating a bunch of children
+    // But the IDs of these children MUST be sequential. Hence the critical block
+    // to avoid interleaved IDs when splitting boxes in parallel.
+    PARALLEL_CRITICAL(MDGridBox_splitting)
+    {
+      for (size_t i=0; i<tot; i++)
       {
-        coord_t min = this->extents[d].min + boxSize[d] * double(indices[d]);
-        myBox->setExtents(d, min, min + boxSize[d]);
-      }
-      myBox->setInverseVolume(inverseVolume); // Set the cached inverse volume
-      boxes.push_back(myBox);
+        // Create the box
+        // (Increase the depth of this box to one more than the parent (this))
+        MDBox<MDE,nd> * myBox = new MDBox<MDE,nd>(bc, this->m_depth + 1);
 
-      // Increment the indices, rolling back as needed
-      indices[0]++;
-      for (size_t d=0; d<nd-1; d++) //This is not run if nd=1; that's okay, you can ignore the warning
-      {
-        if (indices[d] >= split[d])
+        // Set the extents of this box.
+        for (size_t d=0; d<nd; d++)
         {
-          indices[d] = 0;
-          indices[d+1]++;
+          coord_t min = this->extents[d].min + boxSize[d] * double(indices[d]);
+          myBox->setExtents(d, min, min + boxSize[d]);
         }
-      }
-    } // for each box
+        myBox->setInverseVolume(inverseVolume); // Set the cached inverse volume
+        boxes.push_back(myBox);
+
+        // Increment the indices, rolling back as needed
+        indices[0]++;
+        for (size_t d=0; d<nd-1; d++) //This is not run if nd=1; that's okay, you can ignore the warning
+        {
+          if (indices[d] >= split[d])
+          {
+            indices[d] = 0;
+            indices[d+1]++;
+          }
+        }
+      } // for each box
+    }
 
     // Now distribute the events that were in the box before
     this->addEvents(box->getEvents());
diff --git a/Code/Mantid/Framework/MDEvents/src/SaveMDEW.cpp b/Code/Mantid/Framework/MDEvents/src/SaveMDEW.cpp
index bfae1cb98b9..141602476ac 100644
--- a/Code/Mantid/Framework/MDEvents/src/SaveMDEW.cpp
+++ b/Code/Mantid/Framework/MDEvents/src/SaveMDEW.cpp
@@ -74,7 +74,7 @@ namespace MDEvents
 
     // Write out some general information like # of dimensions
     file->makeGroup("workspace", "NXworkspace", 1);
-    file->writeData("dimensions", size_t(nd));
+    file->writeData("dimensions", int32_t(nd));
     file->writeData("event_type", MDE::getTypeName());
 
     // Save each dimension, as their XML representation
@@ -153,6 +153,17 @@ namespace MDEvents
         size_t numChildren = box->getNumChildren();
         if (numChildren > 0)
         {
+          size_t lastId = box->getChild(0)->getId();
+          for (size_t i = 1; i < numChildren; i++)
+          {
+            std::cout << "Child " << i << " : " << box->getChild(i)->getId() << std::endl;
+            if (box->getChild(i)->getId() != lastId+1)
+            {
+              throw std::runtime_error("Non-sequential child ID encountered!");
+            }
+            lastId = box->getChild(i)->getId();
+          }
+
           box_children[id*2] = int(box->getChild(0)->getId());
           box_children[id*2+1] = int(box->getChild(numChildren-1)->getId());
           boxType[id] = 2;
diff --git a/Code/Mantid/Framework/MDEvents/test/LoadMDEWTest.h b/Code/Mantid/Framework/MDEvents/test/LoadMDEWTest.h
index b49f46fd174..f5007bbae5b 100644
--- a/Code/Mantid/Framework/MDEvents/test/LoadMDEWTest.h
+++ b/Code/Mantid/Framework/MDEvents/test/LoadMDEWTest.h
@@ -136,6 +136,13 @@ public:
   }
   
 
+  void xtest_exec_from_file()
+  {
+    AlgorithmHelper::runAlgorithm("LoadMDEW", 4,
+        "Filename", "pg3.nxs",
+        "OutputWorkspace", "DontCare");
+  }
+
 };
 
 
diff --git a/Code/Mantid/Framework/MDEvents/test/MDGridBoxTest.h b/Code/Mantid/Framework/MDEvents/test/MDGridBoxTest.h
index 895380d0016..eec48737c85 100644
--- a/Code/Mantid/Framework/MDEvents/test/MDGridBoxTest.h
+++ b/Code/Mantid/Framework/MDEvents/test/MDGridBoxTest.h
@@ -617,8 +617,21 @@ public:
     TS_ASSERT_EQUALS(boxes.size(), 100);
     for (size_t i=0; i<boxes.size(); i++)
     {
-      TS_ASSERT_EQUALS( boxes[i]->getNPoints(), num_repeat );
-      TS_ASSERT( dynamic_cast<gbox_t *>(boxes[i]) );
+      ibox_t * box = boxes[i];
+      TS_ASSERT_EQUALS( box->getNPoints(), num_repeat );
+      TS_ASSERT( dynamic_cast<gbox_t *>(box) );
+
+      size_t numChildren = box->getNumChildren();
+      if (numChildren > 0)
+      {
+        size_t lastId = box->getChild(0)->getId();
+        for (size_t i = 1; i < numChildren; i++)
+        {
+          TSM_ASSERT_EQUALS("Children IDs need to be sequential!", box->getChild(i)->getId(), lastId+1);
+          lastId = box->getChild(i)->getId();
+        }
+      }
+
     }
 
   }
-- 
GitLab