Commit 185dc48a authored by Whitfield, Ross's avatar Whitfield, Ross
Browse files

Get something working for LeanPeaksWorkspace

WorkspaceFactory.createPeaks('LeanPeaksWorkspace')
parent 7e4dfc72
......@@ -31,6 +31,7 @@ set(SRC_FILES
src/LeanElasticPeak.cpp
src/BasePeak.cpp
src/PeakColumn.cpp
src/LeanPeakColumn.cpp
src/PeakNoShapeFactory.cpp
src/PeakShapeBase.cpp
src/PeakShapeEllipsoid.cpp
......@@ -38,6 +39,7 @@ set(SRC_FILES
src/PeakShapeSpherical.cpp
src/PeakShapeSphericalFactory.cpp
src/PeaksWorkspace.cpp
src/LeanPeaksWorkspace.cpp
src/PropertyWithValue.cpp
src/RebinnedOutput.cpp
src/ReflectometryTransform.cpp
......@@ -113,6 +115,7 @@ set(INC_FILES
inc/MantidDataObjects/LeanElasticPeak.h
inc/MantidDataObjects/BasePeak.h
inc/MantidDataObjects/PeakColumn.h
inc/MantidDataObjects/LeanPeakColumn.h
inc/MantidDataObjects/PeakNoShapeFactory.h
inc/MantidDataObjects/PeakShapeBase.h
inc/MantidDataObjects/PeakShapeEllipsoid.h
......@@ -121,6 +124,7 @@ set(INC_FILES
inc/MantidDataObjects/PeakShapeSpherical.h
inc/MantidDataObjects/PeakShapeSphericalFactory.h
inc/MantidDataObjects/PeaksWorkspace.h
inc/MantidDataObjects/LeanPeaksWorkspace.h
inc/MantidDataObjects/RebinnedOutput.h
inc/MantidDataObjects/ReflectometryTransform.h
inc/MantidDataObjects/ScanningWorkspaceBuilder.h
......
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright © 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#pragma once
#include "MantidAPI/Column.h"
#include "MantidDataObjects/LeanPeak.h"
#include <boost/variant.hpp>
#include <list>
namespace Mantid {
namespace DataObjects {
/** PeakColumn : a Column sub-class used to display
* peak information as a TableWorkspace.
*
* The column holds a reference to a vector of Peak objects.
* Values in the column are taken directly from those Peak objects.
*
* @author Janik Zikovsky
* @date 2011-04-25 18:06:32.952258
*/
class DLLExport LeanPeakColumn : public Mantid::API::Column {
public:
/// Construct a column with a reference to the peaks list, a name & type
LeanPeakColumn(std::vector<LeanPeak> &peaks, const std::string &name);
/// Number of individual elements in the column.
size_t size() const override { return m_peaks.size(); }
/// Returns typeid for the data in the column
const std::type_info &get_type_info() const override;
/// Returns typeid for the pointer type to the data element in the column
const std::type_info &get_pointer_type_info() const override;
bool getReadOnly() const override;
/// Prints
void print(size_t index, std::ostream &s) const override;
void read(size_t index, const std::string &text) override;
/// Sets item from a stream
void read(const size_t index, std::istringstream &in) override;
/// Specialized type check
bool isBool() const override;
bool isNumber() const override;
/// Must return overall memory size taken by the column.
long int sizeOfData() const override;
/// Clone.
LeanPeakColumn *clone() const override;
/// Cast to double
double toDouble(size_t i) const override;
/// Assign from double
void fromDouble(size_t i, double value) override;
/// Reference to the data.
const std::vector<LeanPeak> &data() const { return m_peaks; }
bool equals(const Column &otherColumn, double tolerance) const override {
(void)otherColumn;
(void)tolerance;
throw std::runtime_error(
"equals not implemented, to compare use CompareWorkspace");
}
protected:
/// Sets the new column size.
void resize(size_t count) override;
/// Inserts an item.
void insert(size_t index) override;
/// Removes an item.
void remove(size_t index) override;
/// Pointer to a data element
void *void_pointer(size_t index) override;
/// Pointer to a data element
const void *void_pointer(size_t index) const override;
private:
/// Reference to the peaks object saved in the PeaksWorkspace.
std::vector<LeanPeak> &m_peaks;
/// Precision of hkl in table workspace
int m_hklPrec;
/// Type of the row cache value
using CacheValueType = boost::variant<double, int, std::string, Kernel::V3D>;
///
mutable std::list<CacheValueType> m_oldRows;
/// Sets the correct value in the referenced peak.
void setPeakHKLOrRunNumber(const size_t index, const double val);
};
} // namespace DataObjects
} // namespace Mantid
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2010 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#pragma once
#include "MantidAPI/IPeaksWorkspace.h"
#include "MantidAPI/ITableWorkspace.h"
#include "MantidDataObjects/DllConfig.h"
#include "MantidDataObjects/LeanPeak.h"
#include "MantidDataObjects/LeanPeakColumn.h"
#include "MantidGeometry/Crystal/IPeak.h"
#include "MantidKernel/SpecialCoordinateSystem.h"
#include "MantidKernel/V3D.h"
// IsamplePosition should be IsampleOrientation
namespace Mantid {
//----------------------------------------------------------------------
// Forward declarations
//----------------------------------------------------------------------
namespace Kernel {
class Logger;
}
namespace DataObjects {
//==========================================================================================
/** @class Mantid::DataObjects::LeanPeaksWorkspace
The class LeanPeaksWorkspace stores information about a set of SCD lean
peaks.
@author Ruth Mikkelson, SNS ORNL
@date 3/10/2010
*/
class MANTID_DATAOBJECTS_DLL LeanPeaksWorkspace
: public Mantid::API::IPeaksWorkspace {
public:
using ColumnAndDirection = std::pair<std::string, bool>;
public:
const std::string id() const override { return "LeanPeaksWorkspace"; }
LeanPeaksWorkspace();
LeanPeaksWorkspace &operator=(const LeanPeaksWorkspace &other) = delete;
/** Get access to shared pointer containing workspace porperties. This
function is there to provide common interface of iTableWorkspace
* Despite it is non-constant method, one should be very carefull using it to
change the log values when cloning of a table workspace can occur
as the changes may depend on the order of PeakWorkspace cloning & changes
applyed through this pointer.
* See PeakWorkspaceTest (test_getSetLogAccess) -- for example of this
behaviour.
* Use mutableRun interface to change log values rather then this method.
**/
API::LogManager_sptr logs() override;
API::LogManager_const_sptr getLogs() const override;
/// Returns a clone of the workspace
std::unique_ptr<LeanPeaksWorkspace> clone() const {
return std::unique_ptr<LeanPeaksWorkspace>(doClone());
}
/// Returns a default-initialized clone of the workspace
std::unique_ptr<LeanPeaksWorkspace> cloneEmpty() const {
return std::unique_ptr<LeanPeaksWorkspace>(doCloneEmpty());
}
void appendFile(std::string filename, Geometry::Instrument_sptr inst);
/** @return true because this type of the workspace needs custom sorting calls
*/
bool customSort() const override { return true; }
void sort(std::vector<std::pair<std::string, bool>> &criteria) override;
int getNumberPeaks() const override;
std::string getConvention() const override;
void removePeak(int peakNum) override;
void removePeaks(std::vector<int> badPeaks) override;
void addPeak(const Geometry::IPeak &peak) override;
/// Move a peak object into this peaks workspace
void addPeak(LeanPeak &&peak);
void addPeak(const Kernel::V3D &position,
const Kernel::SpecialCoordinateSystem &frame) override;
LeanPeak &getPeak(int peakNum) override;
const LeanPeak &getPeak(int peakNum) const override;
std::unique_ptr<Geometry::IPeak> createPeak(
const Kernel::V3D &QLabFrame,
boost::optional<double> detectorDistance = boost::none) const override;
std::unique_ptr<Geometry::IPeak>
createPeak(const Kernel::V3D &Position,
const Kernel::SpecialCoordinateSystem &frame) const override;
std::vector<std::pair<std::string, std::string>>
peakInfo(const Kernel::V3D &qFrame, bool labCoords) const override;
std::unique_ptr<Geometry::IPeak>
createPeakHKL(const Kernel::V3D &HKL) const override;
int peakInfoNumber(const Kernel::V3D &qFrame, bool labCoords) const override;
std::vector<LeanPeak> &getPeaks();
const std::vector<LeanPeak> &getPeaks() const;
bool hasIntegratedPeaks() const override;
size_t getMemorySize() const override;
/// Creates a new TableWorkspace giving the IDs of the detectors that
/// contribute to the
/// peaks within the workspace
API::ITableWorkspace_sptr createDetectorTable() const override;
/// Set the special coordinate system.
void setCoordinateSystem(
const Kernel::SpecialCoordinateSystem coordinateSystem) override;
/// Get the special coordinate system.
Kernel::SpecialCoordinateSystem getSpecialCoordinateSystem() const override;
// ====================================== ITableWorkspace Methods
// ==================================
/// Number of columns in the workspace.
size_t columnCount() const override {
return static_cast<int>(columns.size());
}
/// Number of rows in the workspace.
size_t rowCount() const override { return getNumberPeaks(); }
/// Gets the shared pointer to a column by name.
std::shared_ptr<Mantid::API::Column>
getColumn(const std::string &name) override {
return getColumn(getColumnIndex(name));
}
/// Gets the shared pointer to a column by name.
std::shared_ptr<const Mantid::API::Column>
getColumn(const std::string &name) const override {
return getColumn(getColumnIndex(name));
}
/// @return the index of the column with the given name.
virtual size_t getColumnIndex(const std::string &name) const;
/// Gets the shared pointer to a column by index.
std::shared_ptr<Mantid::API::Column> getColumn(size_t index) override;
/// Gets the shared pointer to a column by index - return none-modifyable
/// column.
API::Column_const_sptr getColumn(size_t index) const override;
// ====================================== End ITableWorkspace Methods
// ==================================
//---------------------------------------------------------------------------------------------
/// Returns a vector of all column names.
std::vector<std::string> getColumnNames() const override {
return this->columnNames;
}
/// This is always threadsafe
bool threadSafe() const override { return true; }
// --- Nexus Methods ---
// Save to Nexus
void saveNexus(::NeXus::File *file) const;
protected:
/// Protected copy constructor. May be used by childs for cloning.
LeanPeaksWorkspace(const LeanPeaksWorkspace &other);
private:
LeanPeaksWorkspace *doClone() const override {
return new LeanPeaksWorkspace(*this);
}
LeanPeaksWorkspace *doCloneEmpty() const override {
return new LeanPeaksWorkspace();
}
ITableWorkspace *
doCloneColumns(const std::vector<std::string> &colNames) const override;
/// Initialize the table structure
void initColumns();
/// Adds a new PeakColumn of the given type
void addPeakColumn(const std::string &name);
/// Create a peak from a QSample position
std::unique_ptr<Geometry::IPeak>
createPeakQSample(const Kernel::V3D &position) const;
// ====================================== ITableWorkspace Methods
// ==================================
// ===== Methods that are not implemented (read-only table) ==========
API::Column_sptr addColumn(const std::string & /*type*/,
const std::string & /*name*/) override {
throw Mantid::Kernel::Exception::NotImplementedError(
"LeanPeaksWorkspace structure is read-only. Cannot add column.");
}
bool addColumns(const std::string & /*type*/, const std::string & /*name*/,
size_t /*n*/) override {
throw Mantid::Kernel::Exception::NotImplementedError(
"LeanPeaksWorkspace structure is read-only. Cannot add columns.");
}
void removeColumn(const std::string & /*name*/) override {
throw Mantid::Kernel::Exception::NotImplementedError(
"LeanPeaksWorkspace structure is read-only. Cannot remove column.");
}
void setRowCount(size_t /*count*/) override {
throw Mantid::Kernel::Exception::NotImplementedError(
"LeanPeaksWorkspace structure is read-only. Cannot setRowCount");
}
size_t insertRow(size_t /*index*/) override {
throw Mantid::Kernel::Exception::NotImplementedError(
"LeanPeaksWorkspace structure is read-only. Cannot insertRow");
}
void removeRow(size_t /*index*/) override {
throw Mantid::Kernel::Exception::NotImplementedError(
"LeanPeaksWorkspace structure is read-only. Cannot removeRow.");
}
/// find method to get the index of integer cell value in a table workspace
void find(size_t /*value*/, size_t & /*row*/,
const size_t & /*col*/) override {
throw Mantid::Kernel::Exception::NotImplementedError(
"LeanPeaksWorkspace::find() not implemented.");
}
/// find method to get the index of double cell value in a table workspace
void find(double /*value*/, size_t & /*row*/,
const size_t & /*col*/) override {
throw Mantid::Kernel::Exception::NotImplementedError(
"LeanPeaksWorkspace::find() not implemented.");
}
/// find method to get the index of float cell value in a table workspace
void find(float /*value*/, size_t & /*row*/,
const size_t & /*col*/) override {
throw Mantid::Kernel::Exception::NotImplementedError(
"LeanPeaksWorkspace::find() not implemented.");
}
/// find method to get the index of API::Boolean value cell in a table
/// workspace
void find(API::Boolean /*value*/, size_t & /*row*/,
const size_t & /*col*/) override {
throw Mantid::Kernel::Exception::NotImplementedError(
"LeanPeaksWorkspace::find() not implemented.");
}
/// find method to get the index of cellstd::string value in a table
/// workspace
void find(std::string /*value*/, size_t & /*row*/,
const size_t & /*col*/) override {
throw Mantid::Kernel::Exception::NotImplementedError(
"LeanPeaksWorkspace::find() not implemented.");
}
/// find method to get the index of Mantid::Kernel::V3D cell value in a table
/// workspace
void find(Mantid::Kernel::V3D /*value*/, size_t & /*row*/,
const size_t & /*col*/) override {
throw Mantid::Kernel::Exception::NotImplementedError(
"LeanPeaksWorkspace::find() not implemented.");
}
// ====================================== End ITableWorkspace Methods
// ==================================
/** Vector of Peak contained within. */
std::vector<LeanPeak> peaks;
/** Column shared pointers. */
std::vector<std::shared_ptr<Mantid::DataObjects::LeanPeakColumn>> columns;
/** Column names */
std::vector<std::string> columnNames;
/// Coordinates
Kernel::SpecialCoordinateSystem m_coordSystem;
};
/// Typedef for a shared pointer to a peaks workspace.
using LeanPeaksWorkspace_sptr = std::shared_ptr<LeanPeaksWorkspace>;
/// Typedef for a shared pointer to a const peaks workspace.
using LeanPeaksWorkspace_const_sptr = std::shared_ptr<const LeanPeaksWorkspace>;
} // namespace DataObjects
} // namespace Mantid
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2018 ISIS Rutherford Appleton Laboratory UKRI,
// NScD Oak Ridge National Laboratory, European Spallation Source,
// Institut Laue - Langevin & CSNS, Institute of High Energy Physics, CAS
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidDataObjects/LeanPeakColumn.h"
#include "MantidKernel/ConfigService.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/MultiThreaded.h"
#include "MantidKernel/Strings.h"
#include "MantidKernel/System.h"
#include <boost/variant/get.hpp>
using namespace Mantid::Kernel;
namespace Mantid {
namespace DataObjects {
namespace {
/// static logger
Kernel::Logger g_log("LeanPeakColumn");
/// Number of items to keep around in the cell cache (see void_pointer())
size_t NCELL_ITEM_CACHED = 100;
/**
* Private implementation to wrap a map such that it can be
* initialized in a thread-safe manner with a local static
*/
class ColumnNameToType {
public:
ColumnNameToType() {
// Assume double if not in this map
m_type_index.emplace("DetID", "int");
m_type_index.emplace("RunNumber", "int");
m_type_index.emplace("h", "double");
m_type_index.emplace("k", "double");
m_type_index.emplace("l", "double");
m_type_index.emplace("Wavelength", "double");
m_type_index.emplace("Energy", "double");
m_type_index.emplace("TOF", "double");
m_type_index.emplace("DSpacing", "double");
m_type_index.emplace("Intens", "double");
m_type_index.emplace("SigInt", "double");
m_type_index.emplace("Intens/SigInt", "double");
m_type_index.emplace("BinCount", "double");
m_type_index.emplace("BankName", "str");
m_type_index.emplace("Row", "double");
m_type_index.emplace("Col", "double");
m_type_index.emplace("QLab", "V3D");
m_type_index.emplace("QSample", "V3D");
m_type_index.emplace("PeakNumber", "int");
m_type_index.emplace("TBar", "double");
}
inline const auto &data() const { return m_type_index; }
private:
std::unordered_map<std::string, std::string> m_type_index;
};
/**
* Returns a string type identifier from the given name
* @param name :: The name of the column
* @returns A string identifier for the column type
*/
const std::string typeFromName(const std::string &name) {
static ColumnNameToType typeIndex;
auto iter = typeIndex.data().find(name);
if (iter != typeIndex.data().end()) {
return iter->second;
} else {
throw std::runtime_error("LeanPeakColumn - Unknown column name: \"" + name +
"\""
"Peak column names/types must be explicitly "
"marked in LeanPeakColumn.cpp");
}
}
} // namespace
//----------------------------------------------------------------------------------------------
/** Constructor
* @param peaks :: vector of peaks
* @param name :: name for the column
*/
LeanPeakColumn::LeanPeakColumn(std::vector<LeanPeak> &peaks,
const std::string &name)
: m_peaks(peaks), m_oldRows() {
this->m_name = name;
this->m_type = typeFromName(name); // Throws if the name is unknown
const std::string key = "LeanPeakColumn.hklPrec";
auto hklPrec = ConfigService::Instance().getValue<int>(key);
this->m_hklPrec = hklPrec.get_value_or(2);
if (!hklPrec.is_initialized()) {
g_log.information()
<< "In LeanPeakColumn constructor, did not find any value for '" << key
<< "' from the Config Service. Using default: " << this->m_hklPrec
<< "\n";
}
}
/// Returns typeid for the data in the column
const std::type_info &LeanPeakColumn::get_type_info() const {
// This is horrible copy-and-paste with the method below. The whole thing
// around columns could be much better implemented using templates & traits to
// avoid this
// type of thing!
if (type() == "double") {
return typeid(double);
} else if (type() == "int") {
return typeid(int);
} else if (type() == "str") {
return typeid(std::string);
} else if (type() == "V3D") {
return typeid(V3D);
} else {
throw std::runtime_error(
"LeanPeakColumn::get_type_info() - Unknown column type: " + m_name);
}
}
/// Returns typeid for the pointer type to the data element in the column
const std::type_info &LeanPeakColumn::get_pointer_type_info() const {
if (type() == "double") {
return typeid(double *);
} else if (type() == "int") {
return typeid(int *);
} else if (type() == "str") {
return typeid(std::string *);
} else if (type() == "V3D") {
return typeid(V3D *);
} else {
throw std::runtime_error("LeanPeakColumn::get_pointer_type_info() -: " +
m_name);
}
}
//-------------------------------------------------------------------------------------
/** Prints out the column string at the given row index.
*
* @param s :: stream to output
* @param index :: row index
*/
void LeanPeakColumn::print(size_t index, std::ostream &s) const {
LeanPeak &peak = m_peaks[index];
s.imbue(std::locale("C"));
std::ios::fmtflags fflags(s.flags());
if (m_name == "RunNumber")
s << peak.getRunNumber();
else if (m_name == "DetID")
s << peak.getDetectorID();
else if (m_name == "BankName")
s << peak.getBankName();
else if (m_name == "QLab")
s << peak.getQLabFrame();
else if (m_name == "QSample")
s << peak.getQSampleFrame();
else if (m_name == "h") {
s << std::fixed << std::setprecision(m_hklPrec) << peak.getH();
} else if (m_name == "k") {
s << std::fixed << std::setprecision(m_hklPrec) << peak.getK();
} else if (m_name == "l") {
s << std::fixed << std::setprecision(m_hklPrec) << peak.getL();
} else if (m_name == "PeakNumber") {