Commit 22b4f867 authored by Whitfield, Ross's avatar Whitfield, Ross
Browse files

Move common code from LeanPeak to BasePeak

parent 567dd536
......@@ -29,6 +29,7 @@ set(SRC_FILES
src/OffsetsWorkspace.cpp
src/Peak.cpp
src/LeanPeak.cpp
src/BasePeak.cpp
src/PeakColumn.cpp
src/PeakNoShapeFactory.cpp
src/PeakShapeBase.cpp
......@@ -110,6 +111,7 @@ set(INC_FILES
inc/MantidDataObjects/OffsetsWorkspace.h
inc/MantidDataObjects/Peak.h
inc/MantidDataObjects/LeanPeak.h
inc/MantidDataObjects/BasePeak.h
inc/MantidDataObjects/PeakColumn.h
inc/MantidDataObjects/PeakNoShapeFactory.h
inc/MantidDataObjects/PeakShapeBase.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 "MantidGeometry/Crystal/IPeak.h"
#include "MantidGeometry/Crystal/PeakShape.h"
#include "MantidGeometry/Instrument.h"
#include "MantidKernel/Logger.h"
#include "MantidKernel/Matrix.h"
#include "MantidKernel/PhysicalConstants.h"
#include "MantidKernel/System.h"
#include "MantidKernel/V3D.h"
#include <boost/optional.hpp>
#include <memory>
namespace Mantid {
namespace Geometry {
class InstrumentRayTracer;
}
namespace DataObjects {
/** Structure describing a single-crystal peak
*
* @author Janik Zikovsky
* @date 2011-04-15 13:24:07.963491
*/
class DLLExport BasePeak : public Geometry::IPeak {
public:
/// Allow PeakColumn class to directly access members.
friend class PeakColumn;
BasePeak();
BasePeak(const Mantid::Kernel::Matrix<double> &goniometer);
/// Copy constructor
BasePeak(const BasePeak &other);
// MSVC 2015/17 can build with noexcept = default however
// intellisense still incorrectly reports this as an error despite compiling.
// https://connect.microsoft.com/VisualStudio/feedback/details/1795240/visual-c-2015-default-move-constructor-and-noexcept-keyw
// ord-bug For that reason we still use the supplied default which should be
// noexcept once the above is fixed we can remove this workaround
#if defined(_MSC_VER) && _MSC_VER <= 1910
BasePeak(BasePeak &&) = default;
BasePeak &operator=(BasePeak &&) = default;
#elif ((__GNUC__ < 4) || (__GNUC__ == 4 && __GNUC_MINOR__ <= 8))
// The noexcept default declaration was fixed in GCC 4.9.0
// so for versions 4.8.x and below use default only
// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=53903
BasePeak(BasePeak &&) = default;
BasePeak &operator=(BasePeak &&) = default;
#else
BasePeak(BasePeak &&) noexcept = default;
BasePeak &operator=(BasePeak &&) noexcept = default;
#endif
// Construct a peak from a reference to the interface
explicit BasePeak(const Geometry::IPeak &ipeak);
int getRunNumber() const override;
void setRunNumber(int m_runNumber) override;
double getMonitorCount() const override;
void setMonitorCount(double m_monitorCount) override;
double getH() const override;
double getK() const override;
double getL() const override;
Mantid::Kernel::V3D getHKL() const override;
bool isIndexed() const override;
Mantid::Kernel::V3D getIntHKL() const override;
Mantid::Kernel::V3D getIntMNP() const override;
void setH(double m_H) override;
void setK(double m_K) override;
void setL(double m_L) override;
void setBankName(std::string m_bankName);
void setHKL(double H, double K, double L) override;
void setHKL(const Mantid::Kernel::V3D &HKL) override;
void setIntHKL(const Kernel::V3D &HKL) override;
void setIntMNP(const Mantid::Kernel::V3D &MNP) override;
void setWavelength(double wavelength) override;
double getWavelength() const override;
double getInitialEnergy() const override;
double getFinalEnergy() const override;
double getEnergyTransfer() const override;
void setInitialEnergy(double m_initialEnergy) override;
void setFinalEnergy(double m_finalEnergy) override;
double getIntensity() const override;
double getSigmaIntensity() const override;
double getIntensityOverSigma() const override;
void setIntensity(double m_intensity) override;
void setSigmaIntensity(double m_sigmaIntensity) override;
double getBinCount() const override;
void setBinCount(double m_binCount) override;
Mantid::Kernel::Matrix<double> getGoniometerMatrix() const override;
void setGoniometerMatrix(
const Mantid::Kernel::Matrix<double> &goniometerMatrix) override;
std::string getBankName() const override;
int getRow() const override;
int getCol() const override;
void setRow(int m_row);
void setCol(int m_col);
void setPeakNumber(int m_peakNumber) override;
int getPeakNumber() const override;
double getValueByColName(std::string colName) const;
/// Get the peak shape.
const Mantid::Geometry::PeakShape &getPeakShape() const override;
/// Set the PeakShape
void setPeakShape(Mantid::Geometry::PeakShape *shape);
/// Set the PeakShape
void setPeakShape(Mantid::Geometry::PeakShape_const_sptr shape);
/// Assignment
BasePeak &operator=(const BasePeak &other);
void setAbsorptionWeightedPathLength(double pathLength) override;
double getAbsorptionWeightedPathLength() const override;
protected:
/// Orientation matrix of the goniometer angles.
Mantid::Kernel::Matrix<double> m_GoniometerMatrix;
/// Inverse of the goniometer rotation matrix; used to go from Q in lab frame
/// to Q in sample frame
Mantid::Kernel::Matrix<double> m_InverseGoniometerMatrix;
private:
/// Name of the parent bank
std::string m_bankName;
/// H of the peak
double m_H;
/// K of the peak
double m_K;
/// L of the peak
double m_L;
/// Integrated peak intensity
double m_intensity;
/// Error (sigma) on peak intensity
double m_sigmaIntensity;
/// Count in the bin at the peak
double m_binCount;
/// Initial energy of neutrons at the peak
double m_initialEnergy;
/// Final energy of the neutrons at peak (normally same as m_InitialEnergy)
double m_finalEnergy;
/// absorption weighted path length (aka t bar)
double m_absorptionWeightedPathLength;
/// Originating run number for this peak
int m_runNumber;
/// Integrated monitor count over TOF range for this run
double m_monitorCount;
/// Cached row in the detector
int m_row;
/// Cached column in the detector
int m_col;
int m_peakNumber;
Mantid::Kernel::V3D m_intHKL;
Mantid::Kernel::V3D m_intMNP;
/// Peak shape
Mantid::Geometry::PeakShape_const_sptr m_peakShape;
/// Static logger
static Mantid::Kernel::Logger g_log;
};
} // namespace DataObjects
} // namespace Mantid
......@@ -6,9 +6,8 @@
// SPDX - License - Identifier: GPL - 3.0 +
#pragma once
#include "MantidDataObjects/BasePeak.h"
#include "MantidGeometry/Crystal/IPeak.h"
#include "MantidGeometry/Crystal/PeakShape.h"
#include "MantidGeometry/Instrument.h"
#include "MantidKernel/Logger.h"
#include "MantidKernel/Matrix.h"
#include "MantidKernel/PhysicalConstants.h"
......@@ -19,10 +18,6 @@
namespace Mantid {
namespace Geometry {
class InstrumentRayTracer;
}
namespace DataObjects {
/** Structure describing a single-crystal peak
......@@ -30,7 +25,7 @@ namespace DataObjects {
* @author Janik Zikovsky
* @date 2011-04-15 13:24:07.963491
*/
class DLLExport LeanPeak : public Geometry::IPeak {
class DLLExport LeanPeak : public BasePeak {
public:
/// Allow PeakColumn class to directly access members.
friend class PeakColumn;
......@@ -51,7 +46,6 @@ public:
// https://connect.microsoft.com/VisualStudio/feedback/details/1795240/visual-c-2015-default-move-constructor-and-noexcept-keyword-bug
// For that reason we still use the supplied default which should be noexcept
// once the above is fixed we can remove this workaround
#if defined(_MSC_VER) && _MSC_VER <= 1910
LeanPeak(LeanPeak &&) = default;
LeanPeak &operator=(LeanPeak &&) = default;
......@@ -79,27 +73,6 @@ public:
bool findDetector() override;
bool findDetector(const Geometry::InstrumentRayTracer &tracer) override;
int getRunNumber() const override;
void setRunNumber(int m_runNumber) override;
double getMonitorCount() const override;
void setMonitorCount(double m_monitorCount) override;
double getH() const override;
double getK() const override;
double getL() const override;
Mantid::Kernel::V3D getHKL() const override;
bool isIndexed() const override;
Mantid::Kernel::V3D getIntHKL() const override;
Mantid::Kernel::V3D getIntMNP() const override;
void setH(double m_H) override;
void setK(double m_K) override;
void setL(double m_L) override;
void setBankName(std::string m_bankName);
void setHKL(double H, double K, double L) override;
void setHKL(const Mantid::Kernel::V3D &HKL) override;
void setIntHKL(const Kernel::V3D &HKL) override;
void setIntMNP(const Mantid::Kernel::V3D &MNP) override;
void setSamplePos(double samX, double samY, double samZ) override;
void setSamplePos(const Mantid::Kernel::V3D &XYZ) override;
......@@ -115,128 +88,25 @@ public:
setQLabFrame(const Mantid::Kernel::V3D &qLab,
boost::optional<double> detectorDistance = boost::none) override;
void setWavelength(double wavelength) override;
double getWavelength() const override;
double getScattering() const override;
double getAzimuthal() const override;
double getDSpacing() const override;
double getTOF() const override;
double getInitialEnergy() const override;
double getFinalEnergy() const override;
double getEnergyTransfer() const override;
void setInitialEnergy(double m_initialEnergy) override;
void setFinalEnergy(double m_finalEnergy) override;
double getIntensity() const override;
double getSigmaIntensity() const override;
double getIntensityOverSigma() const override;
void setIntensity(double m_intensity) override;
void setSigmaIntensity(double m_sigmaIntensity) override;
double getBinCount() const override;
void setBinCount(double m_binCount) override;
Mantid::Kernel::Matrix<double> getGoniometerMatrix() const override;
void setGoniometerMatrix(
const Mantid::Kernel::Matrix<double> &goniometerMatrix) override;
std::string getBankName() const override;
int getRow() const override;
int getCol() const override;
void setRow(int m_row);
void setCol(int m_col);
void setPeakNumber(int m_peakNumber) override;
int getPeakNumber() const override;
virtual Mantid::Kernel::V3D getDetPos() const override;
virtual Mantid::Kernel::V3D getSamplePos() const override;
double getL1() const override;
double getL2() const override;
double getValueByColName(std::string colName) const;
/// Get the peak shape.
const Mantid::Geometry::PeakShape &getPeakShape() const override;
/// Set the PeakShape
void setPeakShape(Mantid::Geometry::PeakShape *shape);
/// Set the PeakShape
void setPeakShape(Mantid::Geometry::PeakShape_const_sptr shape);
/// Assignment
LeanPeak &operator=(const LeanPeak &other);
void setAbsorptionWeightedPathLength(double pathLength) override;
double getAbsorptionWeightedPathLength() const override;
private:
/// Name of the parent bank
std::string m_bankName;
/// H of the peak
double m_H;
/// K of the peak
double m_K;
/// L of the peak
double m_L;
/// Integrated peak intensity
double m_intensity;
/// Error (sigma) on peak intensity
double m_sigmaIntensity;
/// Count in the bin at the peak
double m_binCount;
/// Initial energy of neutrons at the peak
double m_initialEnergy;
/// Final energy of the neutrons at peak (normally same as m_InitialEnergy)
double m_finalEnergy;
/// absorption weighted path length (aka t bar)
double m_absorptionWeightedPathLength;
/// Orientation matrix of the goniometer angles.
Mantid::Kernel::Matrix<double> m_GoniometerMatrix;
/// Inverse of the goniometer rotation matrix; used to go from Q in lab frame
/// to Q in sample frame
Mantid::Kernel::Matrix<double> m_InverseGoniometerMatrix;
/// Originating run number for this peak
int m_runNumber;
/// Integrated monitor count over TOF range for this run
double m_monitorCount;
/// Cached row in the detector
int m_row;
/// Cached column in the detector
int m_col;
/// Q_sample vector
Mantid::Kernel::V3D m_Qsample;
int m_peakNumber;
Mantid::Kernel::V3D m_intHKL;
Mantid::Kernel::V3D m_intMNP;
/// Peak shape
Mantid::Geometry::PeakShape_const_sptr m_peakShape;
/// Static logger
static Mantid::Kernel::Logger g_log;
// ki-kf for Inelastic convention; kf-ki for Crystallography convention
std::string convention;
};
} // namespace DataObjects
......
// 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/BasePeak.h"
#include "MantidDataObjects/NoShape.h"
#include "MantidGeometry/Instrument/RectangularDetector.h"
#include "MantidGeometry/Instrument/ReferenceFrame.h"
#include "MantidGeometry/Objects/InstrumentRayTracer.h"
#include "MantidGeometry/Surfaces/LineIntersectVisit.h"
#include "MantidKernel/ConfigService.h"
#include "MantidKernel/Exception.h"
#include "MantidKernel/Strings.h"
#include "boost/make_shared.hpp"
#include <algorithm>
#include <cctype>
#include <string>
#include <utility>
using namespace Mantid;
using namespace Mantid::Kernel;
using namespace Mantid::Geometry;
namespace Mantid {
namespace DataObjects {
//----------------------------------------------------------------------------------------------
/** Default constructor */
BasePeak::BasePeak()
: m_GoniometerMatrix(3, 3, true), m_InverseGoniometerMatrix(3, 3, true),
m_H(0), m_K(0), m_L(0), m_intensity(0), m_sigmaIntensity(0),
m_binCount(0), m_initialEnergy(0.), m_finalEnergy(0.),
m_absorptionWeightedPathLength(0), m_runNumber(0), m_monitorCount(0),
m_row(-1), m_col(-1), m_peakNumber(0), m_intHKL(V3D(0, 0, 0)),
m_intMNP(V3D(0, 0, 0)), m_peakShape(std::make_shared<NoShape>()) {}
//----------------------------------------------------------------------------------------------
/** Constructor including goniometer
*
* @param goniometer :: a 3x3 rotation matrix
*/
BasePeak::BasePeak(const Mantid::Kernel::Matrix<double> &goniometer)
: m_GoniometerMatrix(goniometer), m_InverseGoniometerMatrix(goniometer),
m_H(0), m_K(0), m_L(0), m_intensity(0), m_sigmaIntensity(0),
m_binCount(0), m_initialEnergy(0.), m_finalEnergy(0.),
m_absorptionWeightedPathLength(0), m_runNumber(0), m_monitorCount(0),
m_row(-1), m_col(-1), m_peakNumber(0), m_intHKL(V3D(0, 0, 0)),
m_intMNP(V3D(0, 0, 0)), m_peakShape(std::make_shared<NoShape>()) {
if (fabs(m_InverseGoniometerMatrix.Invert()) < 1e-8)
throw std::invalid_argument(
"BasePeak::ctor(): Goniometer matrix must non-singular.");
}
BasePeak::BasePeak(const BasePeak &other)
: m_GoniometerMatrix(other.m_GoniometerMatrix),
m_InverseGoniometerMatrix(other.m_InverseGoniometerMatrix),
m_bankName(other.m_bankName), m_H(other.m_H), m_K(other.m_K),
m_L(other.m_L), m_intensity(other.m_intensity),
m_sigmaIntensity(other.m_sigmaIntensity), m_binCount(other.m_binCount),
m_initialEnergy(other.m_initialEnergy),
m_finalEnergy(other.m_finalEnergy),
m_absorptionWeightedPathLength(other.m_absorptionWeightedPathLength),
m_runNumber(other.m_runNumber), m_monitorCount(other.m_monitorCount),
m_row(other.m_row), m_col(other.m_col), m_peakNumber(other.m_peakNumber),
m_intHKL(other.m_intHKL), m_intMNP(other.m_intMNP),
m_peakShape(other.m_peakShape->clone()) {}
//----------------------------------------------------------------------------------------------
/** Constructor making a LeanPeak from IPeak interface
*
* @param ipeak :: const reference to an IPeak object
* @return
*/
BasePeak::BasePeak(const Geometry::IPeak &ipeak)
: IPeak(ipeak), m_GoniometerMatrix(ipeak.getGoniometerMatrix()),
m_InverseGoniometerMatrix(ipeak.getGoniometerMatrix()), m_H(ipeak.getH()),
m_K(ipeak.getK()), m_L(ipeak.getL()), m_intensity(ipeak.getIntensity()),
m_sigmaIntensity(ipeak.getSigmaIntensity()),
m_binCount(ipeak.getBinCount()),
m_initialEnergy(ipeak.getInitialEnergy()),
m_finalEnergy(ipeak.getFinalEnergy()),
m_absorptionWeightedPathLength(ipeak.getAbsorptionWeightedPathLength()),
m_runNumber(ipeak.getRunNumber()),
m_monitorCount(ipeak.getMonitorCount()), m_row(ipeak.getRow()),
m_col(ipeak.getCol()), m_peakNumber(ipeak.getPeakNumber()),
m_intHKL(ipeak.getIntHKL()), m_intMNP(ipeak.getIntMNP()),
m_peakShape(std::make_shared<NoShape>()) {
if (fabs(m_InverseGoniometerMatrix.Invert()) < 1e-8)
throw std::invalid_argument(
"Peak::ctor(): Goniometer matrix must non-singular.");
}
//----------------------------------------------------------------------------------------------
/** Set the incident wavelength of the neutron. Calculates the energy from this.
* Assumes elastic scattering.
*
* @param wavelength :: wavelength in Angstroms.
*/
void BasePeak::setWavelength(double wavelength) {
// Velocity of the neutron (non-relativistic)
double velocity = PhysicalConstants::h /
(wavelength * 1e-10 * PhysicalConstants::NeutronMass);
// Energy in J of the neutron
double energy = PhysicalConstants::NeutronMass * velocity * velocity / 2.0;
// Convert to meV
m_initialEnergy = energy / PhysicalConstants::meV;
m_finalEnergy = m_initialEnergy;
}
// -------------------------------------------------------------------------------------
/** Calculate the neutron wavelength (in angstroms) at the peak
* (Note for inelastic scattering - it is the wavelength corresponding to the
* final energy)*/
double BasePeak::getWavelength() const {
// Energy in J of the neutron
double energy = PhysicalConstants::meV * m_finalEnergy;
// v = sqrt(2.0 * E / m)
double velocity = sqrt(2.0 * energy / PhysicalConstants::NeutronMass);
// wavelength = h / mv
double wavelength =
PhysicalConstants::h / (PhysicalConstants::NeutronMass * velocity);
// Return it in angstroms
return wavelength * 1e10;
}
//----------------------------------------------------------------------------------------------
/** Return the run number this peak was measured at. */
int BasePeak::getRunNumber() const { return m_runNumber; }
/** Set the run number that measured this peak
* @param m_runNumber :: the run number */
void BasePeak::setRunNumber(int m_runNumber) {
this->m_runNumber = m_runNumber;
}
//----------------------------------------------------------------------------------------------
/** Return the monitor count stored in this peak. */
double BasePeak::getMonitorCount() const { return m_monitorCount; }
/** Set the monitor count for this peak
* @param m_monitorCount :: the monitor count */
void BasePeak::setMonitorCount(double m_monitorCount) {
this->m_monitorCount = m_monitorCount;
}
//----------------------------------------------------------------------------------------------
/** Get the final neutron energy in meV */
double BasePeak::getFinalEnergy() const { return m_finalEnergy; }
/** Get the initial (incident) neutron energy in meV */
double BasePeak::getInitialEnergy() const { return m_initialEnergy; }
/** Get the difference between the initial and final neutron energy in meV */
double BasePeak::getEnergyTransfer() const {
return getInitialEnergy() - getFinalEnergy();
}
//----------------------------------------------------------------------------------------------
/** Get the H index of the peak */
double BasePeak::getH() const { return m_H; }
/** Get the K index of the peak */
double BasePeak::getK() const { return m_K; }
/** Get the L index of the peak */
double BasePeak::getL() const { return m_L; }
/** Return the HKL vector */
Mantid::Kernel::V3D BasePeak::getHKL() const { return V3D(m_H, m_K, m_L); }
/** Return True if the peak has been indexed */
bool BasePeak::isIndexed() const {
if (m_H == 0. && m_K == 0. && m_L == 0.)
return false;
return true;
}
/** Return the int HKL vector */
Mantid::Kernel::V3D BasePeak::getIntHKL() const { return m_intHKL; }
/** Return the int MNP vector */
V3D BasePeak::getIntMNP() const { return m_intMNP; }
//----------------------------------------------------------------------------------------------
/** Set the H index of this peak
* @param m_H :: index to set */
void BasePeak::setH(double m_H) { this->m_H = m_H; }
/** Set the K index of this peak
* @param m_K :: index to set */