Commit 3d4836d9 authored by Owen Arnold's avatar Owen Arnold
Browse files

refs #10878. Read and write shapes to NeXus format

parent 72ba5a0d
......@@ -30,6 +30,9 @@
#include <Poco/StringTokenizer.h>
#include "MantidDataObjects/PeaksWorkspace.h"
#include "MantidKernel/MultiThreaded.h"
#include "MantidDataObjects/PeakNoShapeFactory.h"
#include "MantidDataObjects/PeakShapeSphericalFactory.h"
#include "MantidDataObjects/PeakShape.h"
namespace Mantid {
namespace DataHandling {
......@@ -1114,9 +1117,37 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) {
peakWS->getPeak(r).setGoniometerMatrix(gm);
}
}
if (!str.compare("column_16")) {
// Read shape information
using namespace Mantid::DataObjects;
PeakShapeFactory_sptr peakFactory = boost::make_shared<PeakShapeSphericalFactory>();
peakFactory->setSuccessor(boost::make_shared<PeakNoShapeFactory>());
NXInfo info = nx_tw.getDataSetInfo(str.c_str());
NXChar data = nx_tw.openNXChar(str.c_str());
const int maxShapeJSONLength = info.dims[1];
data.load();
for (int r = 0; r < numberPeaks; r++) {
// iR = peak row number
auto startPoint = data() + (maxShapeJSONLength * r);
std::string shapeJSON(startPoint, startPoint + maxShapeJSONLength);
boost::trim_right(shapeJSON);
// Make the shape
PeakShape* peakShape = peakFactory->create(shapeJSON);
// Set the shape
peakWS->getPeak(r).setPeakShape(peakShape);
}
}
}
return boost::static_pointer_cast<API::Workspace>(peakWS);
return boost::static_pointer_cast<API::Workspace>(peakWS);
}
//-------------------------------------------------------------------------------------------------
......
......@@ -583,8 +583,10 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
std::vector<double> TOF(np);
std::vector<int> runNumber(np);
std::vector<double> goniometerMatrix(9 * np);
std::vector<std::string> shapes(np);
// Populate column vectors from Peak Workspace
size_t maxShapeJSONLength = 0;
for (size_t i = 0; i < np; i++) {
Peak p = peaks[i];
detectorID[i] = p.getDetectorID();
......@@ -613,12 +615,18 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
goniometerMatrix[9 * i + 7] = gm[1][2];
goniometerMatrix[9 * i + 8] = gm[2][2];
}
// etc.
const std::string shapeJSON = p.getPeakShape().toJSON();
shapes[i] = shapeJSON;
if(shapeJSON.size() > maxShapeJSONLength)
{
maxShapeJSONLength = shapeJSON.size();
}
}
// Start Peaks Workspace in Nexus File
std::string specifyInteger = "An integer";
std::string specifyDouble = "A double";
const std::string specifyInteger = "An integer";
const std::string specifyDouble = "A double";
const std::string specifyString = "A string";
file->makeGroup("peaks_workspace", "NXentry",
true); // For when peaksWorkspace can be loaded
......@@ -745,6 +753,32 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
file->putAttr("units", "Not known"); // Units may need changing when known
file->closeData();
// Shape
std::vector<int64_t> dims;
dims.push_back(np);
dims.push_back(static_cast<int>(maxShapeJSONLength));
const std::string name = "column_16";
file->makeData(name, NeXus::CHAR, dims, false);
file->openData(name);
char *toNexus = new char[maxShapeJSONLength * np];
for (int ii = 0; ii < np; ii++) {
std::string rowStr = shapes[ii];
for (size_t ic = 0; ic < rowStr.size(); ic++)
toNexus[ii * maxShapeJSONLength + ic] = rowStr[ic];
for (size_t ic = rowStr.size(); ic < static_cast<size_t>(maxShapeJSONLength); ic++)
toNexus[ii * maxShapeJSONLength + ic] = ' ';
}
file->putData((void *)(toNexus));
delete[] toNexus;
file->putAttr("units", "Not known"); // Units may need changing when known
file->putAttr("name", "Shape");
file->putAttr("interpret_as", specifyString);
file->closeData();
// QLab & QSample are calculated and do not need to be saved
file->closeGroup(); // end of peaks workpace
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment