Commit 1c3d9c7b authored by Lynch, Vickie's avatar Lynch, Vickie
Browse files

Refs #12863 Fix load/save nexus peaks file; ChangeQConvention added

parent e0f656cc
......@@ -120,6 +120,7 @@ public:
createIterator(Mantid::Geometry::MDImplicitFunction *function = NULL) const;
std::string getConvention() const;
std::string changeQConvention();
signal_t getSignalAtVMD(const Mantid::Kernel::VMD &coords,
const Mantid::API::MDNormalization &normalization =
......
......@@ -48,6 +48,15 @@ IMDIterator *IMDWorkspace::createIterator(
*/
std::string IMDWorkspace::getConvention() const { return convention; }
//---------------------------------------------------------------------------------------------
/** @return the convention
*/
std::string IMDWorkspace::changeQConvention() {
if (this->getConvention() == "Crystallography")convention = "Inelastic";
else convention = "Crystallography";
return convention;
}
//-------------------------------------------------------------------------------------------
/** Returns the signal (normalized by volume) at a given coordinates
*
......
......@@ -1068,20 +1068,26 @@ API::Workspace_sptr LoadNexusProcessed::loadPeaksEntry(NXEntry &entry) {
}
}
}
std::string m_QConvention = "Inelastic";
try {
m_cppFile->getAttr("QConvention", m_QConvention);
} catch (std::exception &) {}
// peaks_workspace
m_cppFile->closeGroup();
// HKL is flipped by -1 due to different q convention in Crystallography.
// Always write out in ki-kf so consistent with old files
// Change convention of loaded file to that in Preferen
double qSign = 1.0;
std::string convention =
ConfigService::Instance().getString("default.convention");
if (convention == "Crystallography")
ConfigService::Instance().getString("Q.convention");
if (convention != m_QConvention)
qSign = -1.0;
for (int r = 0; r < numberPeaks; r++) {
Kernel::V3D v3d;
v3d[2] = 1.0;
if(convention == "Crystallography") v3d[2] = -1.0;
else v3d[2] = 1.0;
Geometry::IPeak *p;
p = peakWS->createPeak(v3d);
peakWS->addPeak(*p);
......
......@@ -9,7 +9,6 @@
#include "MantidKernel/PhysicalConstants.h"
#include "MantidKernel/System.h"
#include "MantidGeometry/Crystal/PeakShape.h"
#include "MantidKernel/ConfigService.h"
#include <boost/shared_ptr.hpp>
#include <boost/optional.hpp>
......
......@@ -3,6 +3,7 @@
#include "MantidGeometry/Instrument/RectangularDetector.h"
#include "MantidGeometry/Instrument/ReferenceFrame.h"
#include "MantidGeometry/Objects/InstrumentRayTracer.h"
#include "MantidKernel/ConfigService.h"
#include "MantidKernel/Strings.h"
#include "MantidKernel/System.h"
#include <algorithm>
......
......@@ -610,20 +610,14 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
std::vector<double> goniometerMatrix(9 * np);
std::vector<std::string> shapes(np);
// HKL is flipped by -1 due to different q convention in Crystallography.
// Always write out in ki-kf so consistent with old files
double qSign = 1.0;
if (this->getConvention() == "Crystallography")
qSign = -1.0;
// 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();
H[i] = qSign * p.getH();
K[i] = qSign * p.getK();
L[i] = qSign * p.getL();
H[i] = p.getH();
K[i] = p.getK();
L[i] = p.getL();
intensity[i] = p.getIntensity();
sigmaIntensity[i] = p.getSigmaIntensity();
binCount[i] = p.getBinCount();
......@@ -663,6 +657,13 @@ void PeaksWorkspace::saveNexus(::NeXus::File *file) const {
// Coordinate system
file->writeData("coordinate_system", static_cast<uint32_t>(m_coordSystem));
// Write out the Qconvention
// ki-kf for Inelastic convention; kf-ki for Crystallography convention
std::string m_QConvention = this->getConvention();
file->putAttr("QConvention", m_QConvention);
// Detectors column
file->writeData("column_1", detectorID);
file->openData("column_1");
......
......@@ -12,6 +12,7 @@ set ( SRC_FILES
src/CalculateCoverageDGS.cpp
src/CentroidPeaksMD.cpp
src/CentroidPeaksMD2.cpp
src/ChangeQConvention.cpp
src/CloneMDWorkspace.cpp
src/CompactMD.cpp
src/CompareMDWorkspaces.cpp
......@@ -139,6 +140,7 @@ set ( INC_FILES
inc/MantidMDAlgorithms/CalculateCoverageDGS.h
inc/MantidMDAlgorithms/CentroidPeaksMD.h
inc/MantidMDAlgorithms/CentroidPeaksMD2.h
inc/MantidMDAlgorithms/ChangeQConvention.h
inc/MantidMDAlgorithms/CloneMDWorkspace.h
inc/MantidMDAlgorithms/CompactMD.h
inc/MantidMDAlgorithms/CompareMDWorkspaces.h
......@@ -264,6 +266,7 @@ set ( TEST_FILES
CalculateCoverageDGSTest.h
CentroidPeaksMD2Test.h
CentroidPeaksMDTest.h
ChangeQConventionTest.h
CloneMDWorkspaceTest.h
CompactMDTest.h
CompareMDWorkspacesTest.h
......
#ifndef MANTID_MDALGORITHMS_ChangeQConvention_H_
#define MANTID_MDALGORITHMS_ChangeQConvention_H_
#include "MantidKernel/System.h"
#include "MantidAPI/Algorithm.h"
#include "MantidDataObjects/MDEventWorkspace.h"
namespace Mantid {
namespace MDAlgorithms {
/** Save a MDEventWorkspace to a .nxs file.
Copyright &copy; 2015 ISIS Rutherford Appleton Laboratory, NScD Oak Ridge
National Laboratory & European Spallation Source
This file is part of Mantid.
Mantid is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
Mantid is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
File change history is stored at: <https://github.com/mantidproject/mantid>
Code Documentation is available at: <http://doxygen.mantidproject.org>
*/
class DLLExport ChangeQConvention : public API::Algorithm {
public:
ChangeQConvention();
~ChangeQConvention();
/// Algorithm's name for identification
virtual const std::string name() const { return "ChangeQConvention"; };
/// Summary of algorithms purpose
virtual const std::string summary() const {
return "Change the convention of MD workspace.";
}
/// Algorithm's version for identification
virtual int version() const { return 2; };
/// Algorithm's category for identification
virtual const std::string category() const {
return "MDAlgorithms\\DataHandling";
}
private:
/// Initialise the properties
void init();
/// Run the algorithm
void exec();
};
} // namespace DataObjects
} // namespace Mantid
#endif /* MANTID_MDALGORITHMS_ChangeQConvention_H_ */
......@@ -4,7 +4,6 @@
#include "MantidMDAlgorithms/MDTransfInterface.h"
#include "MantidMDAlgorithms/MDTransfFactory.h"
#include "MantidMDAlgorithms/MDTransfModQ.h"
#include "MantidKernel/ConfigService.h"
//
namespace Mantid {
namespace MDAlgorithms {
......
......@@ -74,28 +74,9 @@ void BinaryOperationMD::exec() {
m_rhs = getProperty(inputPropName2());
m_out = getProperty(outputPropName());
if (m_lhs->getConvention() != m_rhs->getConvention()) {
// Convert to the Qconvention from Preferences
// ki-kf for Inelastic convention; kf-ki for Crystallography convention
std::string pref_QConvention =
Kernel::ConfigService::Instance().getString("Q.convention");
if (pref_QConvention != m_lhs->getConvention()) {
g_log.information() << "Transforming Q in lhs" << std::endl;
Algorithm_sptr transform_alg = createChildAlgorithm("TransformMD");
transform_alg->setProperty(
"InputWorkspace", boost::dynamic_pointer_cast<IMDWorkspace>(m_lhs));
transform_alg->setProperty("Scaling", "-1.0");
transform_alg->executeAsChildAlg();
m_lhs = transform_alg->getProperty("OutputWorkspace");
} else {
g_log.information() << "Transforming Q in rhs" << std::endl;
Algorithm_sptr transform_alg = createChildAlgorithm("TransformMD");
transform_alg->setProperty(
"InputWorkspace", boost::dynamic_pointer_cast<IMDWorkspace>(m_rhs));
transform_alg->setProperty("Scaling", "-1.0");
transform_alg->executeAsChildAlg();
m_rhs = transform_alg->getProperty("OutputWorkspace");
}
throw std::runtime_error(
"Workspaces have different conventions for Q. "
"Use algorithm ChangeQConvention on one workspace. ");
}
// Flip LHS and RHS if commutative and :
......
#include "MantidAPI/CoordTransform.h"
#include "MantidAPI/FileProperty.h"
#include "MantidAPI/IMDEventWorkspace.h"
#include "MantidKernel/Matrix.h"
#include "MantidKernel/System.h"
#include "MantidDataObjects/MDBoxIterator.h"
#include "MantidDataObjects/MDEventFactory.h"
#include "MantidDataObjects/MDEventWorkspace.h"
#include "MantidMDAlgorithms/ChangeQConvention.h"
#include "MantidDataObjects/MDBox.h"
#include "MantidAPI/Progress.h"
#include "MantidKernel/EnabledWhenProperty.h"
#include <Poco/File.h>
#include "MantidDataObjects/MDHistoWorkspace.h"
#include "MantidDataObjects/MDBoxFlatTree.h"
#include "MantidDataObjects/BoxControllerNeXusIO.h"
#include "MantidKernel/ConfigService.h"
using namespace Mantid::Kernel;
using namespace Mantid::API;
using namespace Mantid::DataObjects;
using namespace Mantid::Geometry;
namespace Mantid {
namespace MDAlgorithms {
// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(ChangeQConvention)
//----------------------------------------------------------------------------------------------
/** Constructor
*/
ChangeQConvention::ChangeQConvention() {}
//----------------------------------------------------------------------------------------------
/** Destructor
*/
ChangeQConvention::~ChangeQConvention() {}
//----------------------------------------------------------------------------------------------
//----------------------------------------------------------------------------------------------
/** Initialize the algorithm's properties.
*/
void ChangeQConvention::init() {
declareProperty(new WorkspaceProperty<IMDWorkspace>("InputWorkspace", "",
Direction::InOut),
"An input MDEventWorkspace or MDHistoWorkspace.");
}
//----------------------------------------------------------------------------------------------
/** Execute the algorithm.
*/
void ChangeQConvention::exec() {
IMDWorkspace_sptr ws = getProperty("InputWorkspace");
g_log.information() << "Transforming Q in workspace" << std::endl;
Algorithm_sptr transform_alg = createChildAlgorithm("TransformMD");
transform_alg->setProperty("InputWorkspace",
boost::dynamic_pointer_cast<IMDWorkspace>(ws));
transform_alg->setProperty("Scaling", "-1.0");
transform_alg->executeAsChildAlg();
ws = transform_alg->getProperty("OutputWorkspace");
ws->changeQConvention();
setProperty("InputWorkspace", ws);
}
} // namespace Mantid
} // namespace DataObjects
#include "MantidMDAlgorithms/MDTransfQ3D.h"
#include "MantidKernel/RegistrationHelper.h"
#include "MantidKernel/ConfigService.h"
namespace Mantid {
namespace MDAlgorithms {
......
#ifndef MANTID_MDEVENTS_ChangeQConventionTEST_H_
#define MANTID_MDEVENTS_ChangeQConventionTEST_H_
#include "MantidAPI/IMDEventWorkspace.h"
#include "MantidAPI/FrameworkManager.h"
#include "MantidDataObjects/MDEventFactory.h"
#include "MantidMDAlgorithms/BinMD.h"
#include "MantidMDAlgorithms/ChangeQConvention.h"
#include "MantidTestHelpers/MDEventsTestHelper.h"
#include <cxxtest/TestSuite.h>
#include <Poco/File.h>
using namespace Mantid::API;
using namespace Mantid::DataObjects;
using namespace Mantid::MDAlgorithms;
class ChangeQConventionTest : public CxxTest::TestSuite {
public:
void test_Init() {
ChangeQConvention alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize())
TS_ASSERT(alg.isInitialized())
}
void test_exec() {
Mantid::Kernel::ConfigService::Instance().setString("Q.convention",
"Inelastic");
std::string wsName = "ChangeQConventionTest_ws";
// Make a 3D MDEventWorkspace
MDEventWorkspace3Lean::sptr ws =
MDEventsTestHelper::makeMDEW<3>(10, 0.0, 10.0, 1);
// Make sure it is split
ws->splitBox();
AnalysisDataService::Instance().addOrReplace(wsName, ws);
ws->refreshCache();
// There are this many boxes, so this is the max ID.
TS_ASSERT_EQUALS(ws->getBoxController()->getMaxId(), 1001);
ChangeQConvention alg;
TS_ASSERT_THROWS_NOTHING(alg.initialize())
TS_ASSERT(alg.isInitialized())
TS_ASSERT_THROWS_NOTHING(
alg.setPropertyValue("InputWorkspace", wsName));
alg.execute();
TS_ASSERT(alg.isExecuted());
auto ws2 = AnalysisDataService::Instance().retrieveWS<IMDWorkspace>(wsName);
TS_ASSERT_EQUALS("Crystallography", ws2->getConvention());
}
};
#endif /* MANTID_MDEVENTS_ChangeQConventionTEST_H_ */
.. algorithm::
.. summary::
.. alias::
.. properties::
Description
-----------
This algorithm changes the sign of Q and the label of the workspace convention.
.. categories::
.. sourcelink::
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