Skip to content

Commit

Permalink
WIP Add code + tests for reading spe headers.
Browse files Browse the repository at this point in the history
Refs #11056
  • Loading branch information
martyngigg committed Dec 7, 2015
1 parent 948317d commit d8c64b0
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 7 deletions.
78 changes: 77 additions & 1 deletion Framework/MDAlgorithms/src/LoadSQW2.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,21 @@
#include "MantidMDAlgorithms/LoadSQW2.h"

#include "MantidAPI/FileProperty.h"
#include "MantidGeometry/Crystal/OrientedLattice.h"
#include "MantidGeometry/Instrument/Goniometer.h"
#include "MantidKernel/make_unique.h"
#include "MantidKernel/V3D.h"

namespace Mantid {
namespace MDAlgorithms {

using API::ExperimentInfo;
using Geometry::Goniometer;
using Geometry::OrientedLattice;
using Kernel::BinaryStreamReader;
using Kernel::Logger;
using Kernel::make_unique;
using Kernel::V3D;

// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(LoadSQW2)
Expand Down Expand Up @@ -125,7 +131,77 @@ void LoadSQW2::readAllSPEHeaders(const int32_t nfiles) {
* @param experiment A reference to an ExperimentInfo object to store the data
*/
void LoadSQW2::readSingleSPEHeader(API::ExperimentInfo &experiment) {

auto &sample = experiment.mutableSample();
auto &run = experiment.mutableRun();

std::string chars;
// skip filename, filepath
*m_reader >> chars >> chars;
float efix(1.0f);
int32_t emode(0);
// add ei as log but skip emode
*m_reader >> efix >> emode;
run.addProperty("Ei", static_cast<double>(efix), true);

// lattice - alatt, angdeg, cu, cv = 12 values
std::vector<float> floats;
m_reader->read(floats, 12);
auto lattice = new OrientedLattice(floats[0], floats[1], floats[2], floats[3],
floats[4], floats[5]);
V3D uVec(floats[6], floats[7], floats[8]),
vVec(floats[9], floats[10], floats[11]);
lattice->setUFromVectors(uVec, vVec);
sample.setOrientedLattice(lattice);
if (g_log.is(Logger::Priority::PRIO_DEBUG)) {
std::stringstream os;
os << "Lattice:"
<< " alatt: " << lattice->a1() << " " << lattice->a2() << " "
<< lattice->a3() << "\n"
<< " angdeg: " << lattice->alpha() << " " << lattice->beta() << " "
<< lattice->gamma() << "\n"
<< " cu: " << floats[6] << " " << floats[7] << " " << floats[8]
<< "\n"
<< " cv: " << floats[9] << " " << floats[10] << " " << floats[11]
<< "\n";
g_log.debug(os.str());
}

// goniometer angles
float psi(0.0f), omega(0.0f), dpsi(0.0f), gl(0.0f), gs(0.0f);
*m_reader >> psi >> omega >> dpsi >> gl >> gs;
V3D uvCross = uVec.cross_prod(vVec);
Goniometer goniometer;
goniometer.pushAxis("psi", uvCross[0], uvCross[1], uvCross[2], psi);
goniometer.pushAxis("omega", uvCross[0], uvCross[1], uvCross[2], omega);
goniometer.pushAxis("gl", 1.0, 0.0, 0.0, gl);
goniometer.pushAxis("gs", 0.0, 0.0, 1.0, gs);
goniometer.pushAxis("dpsi", 0.0, 1.0, 0.0, dpsi);
run.setGoniometer(goniometer, false);
if (g_log.is(Logger::Priority::PRIO_DEBUG)) {
std::stringstream os;
os << "Goniometer angles:\n"
<< " psi: " << psi << "\n"
<< " omega: " << omega << "\n"
<< " gl: " << gl << "\n"
<< " gs: " << gs << "\n"
<< " dpsi: " << dpsi << "\n"
<< " goniometer matrix: " << goniometer.getR() << "\n";
g_log.debug(os.str());
}
// energy bins
int32_t nbounds(0);
*m_reader >> nbounds;
std::vector<float> enBins(nbounds);
m_reader->read(enBins, nbounds);
run.storeHistogramBinBoundaries(
std::vector<double>(enBins.begin(), enBins.end()));

// skip uoffset (4*4), u_to_rlu (16*4), ulen (4*4), ulabel_shape (2*4),
// ulabel (size based on shape)
m_file->seekg(96, std::ios_base::cur);
std::vector<int32_t> ulabel_shape(2);
m_reader->read(ulabel_shape, 2);
m_file->seekg(ulabel_shape[0] * ulabel_shape[1], std::ios_base::cur);
}

/// Create the output workspace object
Expand Down
85 changes: 79 additions & 6 deletions Framework/MDAlgorithms/test/LoadSQW2Test.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,22 @@
#include <cxxtest/TestSuite.h>

#include "MantidAPI/IMDEventWorkspace.h"
#include "MantidAPI/Run.h"
#include "MantidAPI/Sample.h"
#include "MantidGeometry/Crystal/OrientedLattice.h"
#include "MantidMDAlgorithms/LoadSQW2.h"
#include "MantidKernel/make_unique.h"

using Mantid::API::ExperimentInfo;
using Mantid::API::IAlgorithm;
using Mantid::API::IAlgorithm_uptr;
using Mantid::API::IMDEventWorkspace;
using Mantid::API::IMDEventWorkspace_sptr;
using Mantid::API::Run;
using Mantid::API::Sample;
using Mantid::MDAlgorithms::LoadSQW2;
using Mantid::Kernel::make_unique;
using Mantid::Kernel::V3D;

class LoadSQW2Test : public CxxTest::TestSuite {
public:
Expand Down Expand Up @@ -40,16 +48,16 @@ class LoadSQW2Test : public CxxTest::TestSuite {
void test_SQW_Is_Accepted_Filename() {
IAlgorithm_uptr alg;
TS_ASSERT_THROWS_NOTHING(alg = createAlgorithm());
TS_ASSERT_THROWS_NOTHING(
alg->setProperty("Filename", m_filename));
TS_ASSERT_THROWS_NOTHING(alg->setProperty("Filename", m_filename));
}

void test_OutputWorkspace_Has_Correct_Data() {
IMDEventWorkspace_sptr outputWS = runAlgorithm();
TS_ASSERT_EQUALS(4, outputWS->getNumDims());
TS_ASSERT_EQUALS(2, outputWS->getNumExperimentInfo());

checkGeometryAsExpected(*outputWS);
checkExperimentInfoAsExpected(*outputWS);
}

//----------------------------------------------------------------------------
// Failure tests
//----------------------------------------------------------------------------
Expand All @@ -75,7 +83,72 @@ class LoadSQW2Test : public CxxTest::TestSuite {
return alg;
}


void checkGeometryAsExpected(const IMDEventWorkspace &outputWS) {
TS_ASSERT_EQUALS(4, outputWS.getNumDims());
}

void checkExperimentInfoAsExpected(const IMDEventWorkspace &outputWS) {
TS_ASSERT_EQUALS(2, outputWS.getNumExperimentInfo());
for (uint16_t i = 0; i < 2; ++i) {
checkExperimentInfoAsExpected(*outputWS.getExperimentInfo(i), i);
}
}

void checkExperimentInfoAsExpected(const ExperimentInfo &expt,
const uint16_t index) {
checkRunAsExpected(expt.run(), index);
checkSampleAsExpected(expt.sample(), index);
}

void checkRunAsExpected(const Run &run, const size_t index) {
const double efix(787.0);
TS_ASSERT_DELTA(efix, run.getLogAsSingleValue("Ei"), 1e-04);
// histogram bins
const auto enBins = run.getBinBoundaries();
std::vector<double> expectedBins(31);
double en(-5.0);
std::generate(begin(expectedBins), end(expectedBins), [&en]() {
en += 5.0;
return en;
});
TS_ASSERT_DELTA(expectedBins, enBins, 1e-4);
// goniometer
const auto &gR = run.getGoniometerMatrix();
std::vector<double> expectedG;
if (index == 0) {
expectedG = {1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0};
} else {
expectedG = {1.0, 0.000304617, 0.0, -0.000304617, 1.0,
-0.0, -0.0, 0.0, 1.0};
}
TSM_ASSERT_DELTA("Goniometer for run index " + std::to_string(index) +
" is incorrect",
expectedG, gR.getVector(), 1e-04);
}

void checkSampleAsExpected(const Sample &sample, const size_t) {
const auto &lattice = sample.getOrientedLattice();
// lattice
TS_ASSERT_DELTA(2.87, lattice.a1(), 1e-04);
TS_ASSERT_DELTA(2.87, lattice.a2(), 1e-04);
TS_ASSERT_DELTA(2.87, lattice.a3(), 1e-04);
TS_ASSERT_DELTA(90.0, lattice.alpha(), 1e-04);
TS_ASSERT_DELTA(90.0, lattice.beta(), 1e-04);
TS_ASSERT_DELTA(90.0, lattice.gamma(), 1e-04);
auto uVec(lattice.getuVector()), vVec(lattice.getvVector());
uVec.normalize();
vVec.normalize();
TS_ASSERT_DELTA(1.0, uVec[0], 1e-04);
TS_ASSERT_DELTA(0.0, uVec[1], 1e-04);
TS_ASSERT_DELTA(0.0, uVec[2], 1e-04);
TS_ASSERT_DELTA(0.0, vVec[0], 1e-04);
TS_ASSERT_DELTA(1.0, vVec[1], 1e-04);
TS_ASSERT_DELTA(0.0, vVec[2], 1e-04);
}

//----------------------------------------------------------------------------
// Private data
//----------------------------------------------------------------------------
std::string m_filename;
};

Expand Down

0 comments on commit d8c64b0

Please sign in to comment.