Skip to content

Commit

Permalink
WIP Implemented reading SQW header information
Browse files Browse the repository at this point in the history
Refs #11056
  • Loading branch information
martyngigg committed Dec 3, 2015
1 parent fc87be4 commit 9acb79d
Show file tree
Hide file tree
Showing 4 changed files with 267 additions and 0 deletions.
3 changes: 3 additions & 0 deletions Framework/MDAlgorithms/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ set ( SRC_FILES
src/LoadILLAsciiHelper.cpp
src/LoadMD.cpp
src/LoadSQW.cpp
src/LoadSQW2.cpp
src/LogarithmMD.cpp
src/MDEventWSWrapper.cpp
src/MDNormDirectSC.cpp
Expand Down Expand Up @@ -189,6 +190,7 @@ set ( INC_FILES
inc/MantidMDAlgorithms/LoadILLAsciiHelper.h
inc/MantidMDAlgorithms/LoadMD.h
inc/MantidMDAlgorithms/LoadSQW.h
inc/MantidMDAlgorithms/LoadSQW2.h
inc/MantidMDAlgorithms/LogarithmMD.h
inc/MantidMDAlgorithms/MDEventWSWrapper.h
inc/MantidMDAlgorithms/MDNormDirectSC.h
Expand Down Expand Up @@ -311,6 +313,7 @@ set ( TEST_FILES
LessThanMDTest.h
LoadMDTest.h
LoadSQWTest.h
LoadSQW2Test.h
LogarithmMDTest.h
MDEventWSWrapperTest.h
MDNormDirectSCTest.h
Expand Down
71 changes: 71 additions & 0 deletions Framework/MDAlgorithms/inc/MantidMDAlgorithms/LoadSQW2.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
#ifndef MANTID_MDALGORITHMS_LOADSQW2_H_
#define MANTID_MDALGORITHMS_LOADSQW2_H_

#include "MantidAPI/Algorithm.h"
#include "MantidDataObjects/MDEvent.h"
#include "MantidDataObjects/MDEventWorkspace.h"
#include "MantidKernel/BinaryStreamReader.h"

#include <fstream>

namespace Mantid {
namespace MDAlgorithms {

/**
*
* 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 LoadSQW2 : public API::Algorithm {
public:
LoadSQW2();
~LoadSQW2();

virtual const std::string name() const;
virtual int version() const;
virtual const std::string category() const;
virtual const std::string summary() const;

private:
/// Local typedef for
typedef DataObjects::MDEventWorkspace<DataObjects::MDEvent<4>, 4>
SQWWorkspace;

/// Classes that define the sections of the file
struct SQWHeader {
int32_t nfiles;
};

void init();
void exec();
void initFileReader();
SQWHeader readMainHeader();
void createOutputWorkspace();

std::unique_ptr<std::ifstream> m_file;
std::unique_ptr<Kernel::BinaryStreamReader> m_reader;
boost::shared_ptr<SQWWorkspace> m_outputWS;
};

} // namespace MDAlgorithms
} // namespace Mantid

#endif /* MANTID_MDALGORITHMS_LOADSQW2_H_ */
112 changes: 112 additions & 0 deletions Framework/MDAlgorithms/src/LoadSQW2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
//------------------------------------------------------------------------------
// Includes
//------------------------------------------------------------------------------
#include "MantidMDAlgorithms/LoadSQW2.h"

#include "MantidAPI/FileProperty.h"
#include "MantidKernel/make_unique.h"

namespace Mantid {
namespace MDAlgorithms {

using Kernel::BinaryStreamReader;
using Kernel::Logger;
using Kernel::make_unique;

// Register the algorithm into the AlgorithmFactory
DECLARE_ALGORITHM(LoadSQW2)

//------------------------------------------------------------------------------
// Public methods
//------------------------------------------------------------------------------
/// Default constructor
LoadSQW2::LoadSQW2() : API::Algorithm(), m_file(), m_reader(), m_outputWS() {}

/// Default destructor
LoadSQW2::~LoadSQW2() {}

/// Algorithms name for identification. @see Algorithm::name
const std::string LoadSQW2::name() const { return "LoadSQW"; }

/// Algorithm's version for identification. @see Algorithm::version
int LoadSQW2::version() const { return 2; }

/// Algorithm's category for identification. @see Algorithm::category
const std::string LoadSQW2::category() const { return "DataHandling"; }

/// Algorithm's summary for use in the GUI and help. @see Algorithm::summary
const std::string LoadSQW2::summary() const {
return "Load an N-dimensional workspace from a .sqw file produced by Horace.";
}

/// Initialize the algorithm's properties.
void LoadSQW2::init() {
using namespace API;

declareProperty(
new FileProperty("Filename", "", FileProperty::Load, {".sqw"}),
"File of type SQW format");
declareProperty(new WorkspaceProperty<IMDEventWorkspace>(
"OutputWorkspace", "", Kernel::Direction::Output),
"Output IMDEventWorkspace reflecting SQW data");
}

/// Execute the algorithm.
void LoadSQW2::exec() {
initFileReader();
readMainHeader();
createOutputWorkspace();

setProperty("OutputWorkspace", m_outputWS);
}

/**
* Opens the file given to the algorithm and initializes the reader
*/
void LoadSQW2::initFileReader() {
m_file = make_unique<std::ifstream>(getPropertyValue("Filename"),
std::ios_base::binary);
m_reader = make_unique<BinaryStreamReader>(*m_file);
}

/**
* Reads the initial header section. Skips specifically the
* following: app_name, app_version, sqw_type, ndims, filename, filepath, title.
* Stores the number of files.
* @return A SQWHeader object describing the section
*/
LoadSQW2::SQWHeader LoadSQW2::readMainHeader() {
std::string appName, filename, filepath, title;
double appVersion(0.0);
int32_t sqwType(-1);
int32_t numDims(-1);
SQWHeader header;
*m_reader >> appName >> appVersion >> sqwType >> numDims >> filename >>
filepath >> title >> header.nfiles;

if (g_log.is(Logger::Priority::PRIO_DEBUG)) {
std::ostringstream os;
os << "Skipped preamable section:\n"
<< " app_name: " << appName << "\n"
<< " app_version: " << appVersion << "\n"
<< " sqw_type: " << sqwType << "\n"
<< " ndims: " << numDims << "\n"
<< " filename: " << filename << "\n"
<< " filepath: " << filepath << "\n"
<< " title: " << title << "\n";
g_log.debug(os.str());
}
return header;
}

/// Create the output workspace object
void LoadSQW2::createOutputWorkspace() {
m_outputWS = boost::make_shared<SQWWorkspace>();
}

//------------------------------------------------------------------------------
// Public methods
//------------------------------------------------------------------------------

} // namespace MDAlgorithms
} // namespace Mantid
81 changes: 81 additions & 0 deletions Framework/MDAlgorithms/test/LoadSQW2Test.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
#ifndef MANTID_MDALGORITHMS_LOADSQW2TEST_H_
#define MANTID_MDALGORITHMS_LOADSQW2TEST_H_

#include <cxxtest/TestSuite.h>

#include "MantidAPI/IMDEventWorkspace.h"
#include "MantidMDAlgorithms/LoadSQW2.h"
#include "MantidKernel/make_unique.h"

using Mantid::API::IAlgorithm;
using Mantid::API::IAlgorithm_uptr;
using Mantid::API::IMDEventWorkspace_sptr;
using Mantid::MDAlgorithms::LoadSQW2;
using Mantid::Kernel::make_unique;

class LoadSQW2Test : public CxxTest::TestSuite {
public:
// This pair of boilerplate methods prevent the suite being created statically
// This means the constructor isn't called when running other tests
static LoadSQW2Test *createSuite() { return new LoadSQW2Test(); }
static void destroySuite(LoadSQW2Test *suite) { delete suite; }

LoadSQW2Test() : CxxTest::TestSuite(), m_filename("test_horace_reader.sqw") {}

//----------------------------------------------------------------------------
// Success tests
//----------------------------------------------------------------------------
void test_Algorithm_Initializes_Correctly() {
IAlgorithm_uptr alg;
TS_ASSERT_THROWS_NOTHING(alg = createAlgorithm());
TS_ASSERT(alg->isInitialized());
}

void test_Algorithm_Is_Version_2_LoadSQW() {
IAlgorithm_uptr alg = createAlgorithm();
TS_ASSERT_EQUALS("LoadSQW", alg->name());
TS_ASSERT_EQUALS(2, alg->version());
}

void test_SQW_Is_Accepted_Filename() {
IAlgorithm_uptr alg;
TS_ASSERT_THROWS_NOTHING(alg = createAlgorithm());
TS_ASSERT_THROWS_NOTHING(
alg->setProperty("Filename", m_filename));
}

void test_OutputWorkspace_Is_4D_MDEventWorkspace() {
auto outputWS = runAlgorithm();
TS_ASSERT_EQUALS(4, outputWS->getNumDims());
}

//----------------------------------------------------------------------------
// Failure tests
//----------------------------------------------------------------------------
void test_Filename_Property_Throws_If_Not_Found() {
auto alg = createAlgorithm();
TS_ASSERT_THROWS(alg->setPropertyValue("Filename", "x.sqw"),
std::invalid_argument);
}

private:
IMDEventWorkspace_sptr runAlgorithm() {
auto algm = createAlgorithm();
algm->setProperty("Filename", m_filename);
algm->setProperty("OutputWorkspace", "__unused_value_for_child_algorithm");
algm->execute();
return algm->getProperty("OutputWorkspace");
}

IAlgorithm_uptr createAlgorithm() {
IAlgorithm_uptr alg(make_unique<LoadSQW2>());
alg->initialize();
alg->setChild(true);
return alg;
}


std::string m_filename;
};

#endif /* MANTID_MDALGORITHMS_LOADSQW2TEST_H_ */

0 comments on commit 9acb79d

Please sign in to comment.