Commit c59d317b authored by Dominik Arominski's avatar Dominik Arominski
Browse files

Merge branch 'master' of https://github.com/mantidproject/mantid into d16_hotfixes

parents 5ef9ff60 2b37feda
......@@ -30,6 +30,7 @@ set(SRC_FILES
src/CostFunctionFactory.cpp
src/DataProcessorAlgorithm.cpp
src/DeprecatedAlgorithm.cpp
src/DeprecatedAlias.cpp
src/DetectorSearcher.cpp
src/DistributedAlgorithm.cpp
src/DomainCreatorFactory.cpp
......@@ -202,6 +203,7 @@ set(INC_FILES
inc/MantidAPI/DataProcessorAlgorithm.h
inc/MantidAPI/DeclareUserAlg.h
inc/MantidAPI/DeprecatedAlgorithm.h
inc/MantidAPI/DeprecatedAlias.h
inc/MantidAPI/DetectorSearcher.h
inc/MantidAPI/DistributedAlgorithm.h
inc/MantidAPI/DomainCreatorFactory.h
......
......@@ -171,8 +171,11 @@ public:
/// Function to return all of the seeAlso (these are not validated) algorithms
/// related to this algorithm.A default implementation is provided.
const std::vector<std::string> seeAlso() const override { return {}; };
/// function to return any aliases to the algorithm; A default implementation is provided
/// Function to return any aliases to the algorithm; A default implementation
/// is provided
const std::string alias() const override { return ""; }
/// Flag to indicate if the algorithm is called by its alias.
bool calledByAlias = false;
/// function to return URL for algorithm documentation; A default
/// implementation is provided.
......
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2021 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/Algorithm.h"
#include "MantidAPI/DllConfig.h"
#include "MantidAPI/IAlgorithm.h"
#include <string>
namespace Mantid {
namespace API {
/** DeprecatedAlias :
* Class for making algorithm with deprecated names (aliases).
*
* This class will ensure that if an algorithm is invoke with a deprecated name,
* - a warning will be throw to inform the users that
* - the algorithm name is deprecated
* - the deprecation date
* - the new algorithm name the user is recommended to use instead
*
* All algorithms with deprecated alias need to inherit from this class.
*
* The recommended algorithm naming pattern should be
* [Technique][Facility/Instrument]ActionTarget
* For example: the calibration routine of panel detector for single crystal diffraction
* beamline can be named as SCDCalibratePanels
*/
class MANTID_API_DLL DeprecatedAlias {
public:
DeprecatedAlias();
virtual ~DeprecatedAlias();
std::string deprecationMessage(const IAlgorithm *);
void setDeprecationDate(const std::string &date);
private:
/// Deprecation date
std::string m_deprecationDate;
};
} // namespace API
} // namespace Mantid
......@@ -10,6 +10,7 @@
#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/DeprecatedAlgorithm.h"
#include "MantidAPI/DeprecatedAlias.h"
#include "MantidAPI/IWorkspaceProperty.h"
#include "MantidAPI/WorkspaceGroup.h"
#include "MantidAPI/WorkspaceHistory.h"
......@@ -512,12 +513,21 @@ bool Algorithm::executeInternal() {
Timer timer;
bool algIsExecuted = false;
AlgorithmManager::Instance().notifyAlgorithmStarting(this->getAlgorithmID());
// runtime check for deprecation warning
{
auto *depo = dynamic_cast<DeprecatedAlgorithm *>(this);
if (depo != nullptr)
getLogger().error(depo->deprecationMsg(this));
}
// runtime check for deprecated alias warning
{
auto *da_alg = dynamic_cast<DeprecatedAlias *>(this);
if ((da_alg != nullptr) && (this->calledByAlias))
getLogger().warning(da_alg->deprecationMessage(this));
}
// Register clean up tasks that should happen regardless of the route
// out of the algorithm. These tasks will get run after this method
// finishes.
......
......@@ -34,8 +34,8 @@ AlgorithmFactoryImpl::AlgorithmFactoryImpl() : Kernel::DynamicFactory<Algorithm>
AlgorithmFactoryImpl::~AlgorithmFactoryImpl() = default;
/** Creates an instance of an algorithm
* @param name :: the name of the Algrorithm to create
* @param version :: the version of the algroithm to create
* @param name :: the name of the Algorithm to create
* @param version :: the version of the algorithm to create
* @returns a shared pointer to the created algorithm
*/
std::shared_ptr<Algorithm> AlgorithmFactoryImpl::create(const std::string &name, const int &version) const {
......@@ -57,7 +57,9 @@ std::shared_ptr<Algorithm> AlgorithmFactoryImpl::create(const std::string &name,
if (realName) {
// Try create algorithm again with real name
try {
return this->createAlgorithm(realName.get(), local_version);
auto alg = this->createAlgorithm(realName.get(), local_version);
alg->calledByAlias = true;
return alg;
} catch (Kernel::Exception::NotFoundError &) {
// Get highest registered version
const auto hVersion = highestVersion(realName.get()); // Throws if not found
......@@ -209,7 +211,7 @@ const std::vector<std::string> AlgorithmFactoryImpl::getKeys(bool includeHidden)
/**
* @param alias The name of the algorithm to look up in the alias map
* @return Real name of algroithm if found
* @return Real name of algorithm if found
*/
boost::optional<std::string> AlgorithmFactoryImpl::getRealNameFromAlias(const std::string &alias) const noexcept {
auto a_it = m_amap.find(alias);
......
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2021 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 "MantidAPI/DeprecatedAlias.h"
#include "MantidAPI/AlgorithmFactory.h"
#include "MantidKernel/Logger.h"
#include "MantidTypes/Core/DateAndTimeHelpers.h"
namespace Mantid {
namespace API {
namespace {
Kernel::Logger g_log("DeprecatedAlias");
} // namespace
/// Constructor to ensure the compiler is happy
DeprecatedAlias::DeprecatedAlias() : m_deprecationDate() {}
/// Destructor to ensure the compiler is happy
DeprecatedAlias::~DeprecatedAlias() = default;
/**
* @brief Set the deprecation date which will be used to inform the users
*
* @param date : deprecation date in ISO8601 format
*/
void DeprecatedAlias::setDeprecationDate(const std::string &date) {
m_deprecationDate = "";
if ((!date.empty()) && (Types::Core::DateAndTimeHelpers::stringIsISO8601(date))) {
m_deprecationDate = date;
} else {
throw std::invalid_argument("DeprecatedAlias::DeprecationDate(): deprecation date must follow ISO8601.");
}
}
/**
* @brief Construct and return a full deprecation message
*
* @param algo
* @return std::string
*/
std::string DeprecatedAlias::deprecationMessage(const IAlgorithm *algo) {
std::stringstream msg;
auto alias = algo->alias();
if (alias.empty()) {
throw std::runtime_error("Cannot find the deprecated alias for this algorithm.");
} else {
msg << "The algorithm '" << alias << "' is deprecated on " << m_deprecationDate << "."
<< "Please use '" << algo->name() << "' instead.";
}
return msg.str();
}
} // namespace API
} // namespace Mantid
......@@ -161,7 +161,6 @@ set(SRC_FILES
src/GeneratePythonFitScript.cpp
src/GeneratePythonScript.cpp
src/GetAllEi.cpp
src/GetDetOffsetsMultiPeaks.cpp
src/GetDetectorOffsets.cpp
src/GetEi.cpp
src/GetEi2.cpp
......@@ -505,7 +504,6 @@ set(INC_FILES
inc/MantidAlgorithms/GeneratePythonFitScript.h
inc/MantidAlgorithms/GeneratePythonScript.h
inc/MantidAlgorithms/GetAllEi.h
inc/MantidAlgorithms/GetDetOffsetsMultiPeaks.h
inc/MantidAlgorithms/GetDetectorOffsets.h
inc/MantidAlgorithms/GetEi.h
inc/MantidAlgorithms/GetEi2.h
......@@ -863,7 +861,6 @@ set(TEST_FILES
GeneratePythonFitScriptTest.h
GeneratePythonScriptTest.h
GetAllEiTest.h
GetDetOffsetsMultiPeaksTest.h
GetDetectorOffsetsTest.h
GetEiMonDet3Test.h
GetEiTest.h
......@@ -1091,4 +1088,4 @@ mtd_install_targets(TARGETS
INSTALL_DIRS
${PLUGINS_DIR}
${WORKBENCH_PLUGINS_DIR})
endif()
\ No newline at end of file
endif()
......@@ -36,7 +36,7 @@ public:
/// Algorithm's version for identification overriding a virtual method
int version() const override { return 1; }
const std::vector<std::string> seeAlso() const override { return {"AlignComponents", "GetDetOffsetsMultiPeaks"}; }
const std::vector<std::string> seeAlso() const override { return {"AlignComponents"}; }
/// Algorithm's category for identification overriding a virtual method
const std::string category() const override {
return "Diffraction\\Calibration;"
......
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2009 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/Algorithm.h"
#include "MantidAPI/DeprecatedAlgorithm.h"
#include "MantidAPI/MatrixWorkspace_fwd.h"
#include "MantidAlgorithms/DllConfig.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidDataObjects/OffsetsWorkspace.h"
#include "MantidDataObjects/TableWorkspace.h"
namespace Mantid {
namespace Algorithms {
struct FitPeakOffsetResult {
double mask;
double offset;
double chi2;
/// fit sum from GSL optimizer as offset's error
double fitSum;
/// summation of chi-square
double chisqSum;
/// Number of peaks with successful fitting
double peakPosFittedSize;
int numpeakstofit;
int numpeaksfitted;
int numpeaksindrange;
std::string fitoffsetstatus;
/// Highest peak position
double highestpeakpos;
/// Highest peak deviation after calibrated by offset
double highestpeakdev;
/// Average resolution delta(d)/d
double resolution;
/// Standard devation of the resolution
double dev_resolution;
};
/**
Find the offsets for each detector
@author Vickie Lynch, SNS
@date 12/12/2011
*/
class MANTID_ALGORITHMS_DLL GetDetOffsetsMultiPeaks : public API::Algorithm, public API::DeprecatedAlgorithm {
public:
/// Default constructorMatrix
GetDetOffsetsMultiPeaks();
/// Algorithm's name for identification overriding a virtual method
const std::string name() const override { return "GetDetOffsetsMultiPeaks"; }
/// Algorithm's version for identification overriding a virtual method
int version() const override { return 1; }
const std::vector<std::string> seeAlso() const override { return {"GetDetectorOffsets"}; }
/// Algorithm's category for identification overriding a virtual method
const std::string category() const override { return "Diffraction\\Calibration"; }
/// Summary of algorithms purpose
const std::string summary() const override {
return "Creates an OffsetsWorkspace containing offsets for each detector. "
"You can then save these to a .cal file using SaveCalFile.";
}
private:
// Overridden Algorithm methods
void init() override;
void exec() override;
void processProperties();
/// Create workspaces for fitting information
void createInformationWorkspaces();
/// Main function to calculate all detectors' offsets
void calculateDetectorsOffsets();
void importFitWindowTableWorkspace(const DataObjects::TableWorkspace_sptr &windowtablews);
/// Call Gaussian as a Child Algorithm to fit the peak in a spectrum
int fitSpectra(const int64_t wi, const API::MatrixWorkspace_sptr &inputW, const std::vector<double> &peakPositions,
const std::vector<double> &fitWindows, size_t &nparams, double &minD, double &maxD,
std::vector<double> &peakPosToFit, std::vector<double> &peakPosFitted, std::vector<double> &chisq,
std::vector<double> &peakHeights, int &i_highestpeak, double &resolution, double &dev_resolution);
/// Add peak fitting and offset calculation information to information table
/// workspaces per spectrum
void addInfoToReportWS(int wi, const FitPeakOffsetResult &offsetresult, const std::vector<double> &tofitpeakpositions,
const std::vector<double> &fittedpeakpositions);
/// Generate a list of peaks to calculate detectors' offset
void generatePeaksList(const API::ITableWorkspace_sptr &peakslist, int wi, const std::vector<double> &peakPositionRef,
std::vector<double> &peakPosToFit, std::vector<double> &peakPosFitted,
std::vector<double> &peakHeightFitted, std::vector<double> &chisq, bool useFitWindows,
const std::vector<double> &fitWindowsToUse, const double minD, const double maxD,
double &deltaDovD, double &dev_deltaDovD);
FitPeakOffsetResult calculatePeakOffset(const int wi, std::vector<double> &vec_peakPosFitted,
std::vector<double> &vec_peakPosRef);
/// Calculate a spectrum's offset by optimizing offset
void fitPeaksOffset(const size_t inpnparams, const double minD, const double maxD,
const std::vector<double> &vec_peakPosRef, const std::vector<double> &vec_peakPosFitted,
const std::vector<double> &vec_peakHeights, FitPeakOffsetResult &fitresult);
/// Make a summary on all fit
void makeFitSummary();
/// Remove rows without offset calculated from offset table workspace
void removeEmptyRowsFromPeakOffsetTable();
/// Input workspace
API::MatrixWorkspace_sptr m_inputWS;
/// Input EventWorkspace (from m_inputWS)
DataObjects::EventWorkspace_const_sptr m_eventW;
bool m_isEvent;
/// Background type
std::string m_backType;
/// Peak profile type
std::string m_peakType;
/// Criterias for fitting peak
std::string m_minimizer;
double m_maxChiSq;
double m_minPeakHeight;
double m_leastMaxObsY;
double m_maxOffset;
std::vector<double> m_peakPositions;
std::vector<double> m_fitWindows;
/// Input resolution
API::MatrixWorkspace_const_sptr m_inputResolutionWS;
/// Flag of use input resolution
bool m_hasInputResolution;
/// Lower boundary of allowed peak width as resolution
double m_minResFactor;
/// Upper boundary of allowed peak width as resolution
double m_maxResFactor;
DataObjects::OffsetsWorkspace_sptr m_outputW;
/// Output workspace for debugging purpose
DataObjects::OffsetsWorkspace_sptr m_outputNP;
/// Output Mask workspace
API::MatrixWorkspace_sptr m_maskWS;
DataObjects::TableWorkspace_sptr m_infoTableWS;
DataObjects::TableWorkspace_sptr m_peakOffsetTableWS;
/// Workspace for calculated detector resolution
API::MatrixWorkspace_sptr m_resolutionWS;
/// Flag to use fit window from TableWorkspace per spectrum
bool m_useFitWindowTable;
/// Vector of fit windows (also in vector)
std::vector<std::vector<double>> m_vecFitWindow;
};
} // namespace Algorithms
} // namespace Mantid
......@@ -34,9 +34,7 @@ public:
/// Algorithm's version for identification overriding a virtual method
int version() const override { return 1; }
const std::vector<std::string> seeAlso() const override {
return {"GetDetOffsetsMultiPeaks", "CalibrateRectangularDetectors", "AlignComponents"};
}
const std::vector<std::string> seeAlso() const override { return {"AlignComponents"}; }
/// Algorithm's category for identification overriding a virtual method
const std::string category() const override { return "Diffraction\\Calibration"; }
......
......@@ -26,7 +26,7 @@ public:
const std::string name() const override;
int version() const override;
const std::vector<std::string> seeAlso() const override { return {"CalibrateRectangularDetectors"}; }
const std::vector<std::string> seeAlso() const override { return {}; }
const std::string category() const override;
const std::string summary() const override;
......
// 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 "MantidAlgorithms/GetDetOffsetsMultiPeaks.h"
#include "MantidAPI/CompositeFunction.h"
#include "MantidAPI/FileProperty.h"
#include "MantidAPI/FuncMinimizerFactory.h"
#include "MantidAPI/FunctionFactory.h"
#include "MantidAPI/IBackgroundFunction.h"
#include "MantidAPI/IPeakFunction.h"
#include "MantidAPI/ITableWorkspace.h"
#include "MantidAPI/SpectrumInfo.h"
#include "MantidAPI/TableRow.h"
#include "MantidAPI/WorkspaceUnitValidator.h"
#include "MantidDataObjects/EventWorkspace.h"
#include "MantidDataObjects/MaskWorkspace.h"
#include "MantidDataObjects/OffsetsWorkspace.h"
#include "MantidDataObjects/WorkspaceCreation.h"
#include "MantidHistogramData/Histogram.h"
#include "MantidKernel/ArrayProperty.h"
#include "MantidKernel/ListValidator.h"
#include "MantidKernel/StartsWithValidator.h"
#include "MantidKernel/Statistics.h"
#include "MantidKernel/VectorHelper.h"
#include <gsl/gsl_multifit_nlin.h>
#include <gsl/gsl_multimin.h>
#include <sstream>
using namespace Mantid::DataObjects;
using namespace Mantid::HistogramData;
namespace Mantid::Algorithms {
namespace {
/// Factor to convert full width half max to sigma for calculations of I/sigma.
const double FWHM_TO_SIGMA = 2.0 * sqrt(2.0 * M_LN2);
const double BAD_OFFSET(1000.); // mark things that didn't work with this
//--------------------------------------------------------------------------------------------
/** Helper function for calculating costs in gsl.
* cost = \sum_{p}|d^0_p - (1+offset)*d^{(f)}_p|\cdot H^2_p, where d^{(f)} is
* within minD and maxD
* @param v Vector of offsets.
* @param params Array of input parameters.
* @returns Sum of the errors.
*/
double gsl_costFunction(const gsl_vector *v, void *params) {
// FIXME - there is no need to use vectors peakPosToFit, peakPosFitted and
// chisq
auto *p = reinterpret_cast<double *>(params);
auto n = static_cast<size_t>(p[0]);
std::vector<double> peakPosToFit(n);
std::vector<double> peakPosFitted(n);
std::vector<double> height2(n);
double minD = p[1];
double maxD = p[2];
for (size_t i = 0; i < n; i++) {
peakPosToFit[i] = p[i + 3];
}
for (size_t i = 0; i < n; i++) {
peakPosFitted[i] = p[i + n + 3];
}
for (size_t i = 0; i < n; i++) {
height2[i] = p[i + 2 * n + 3];
}
double offset = gsl_vector_get(v, 0);
double errsum = 0.0;
for (size_t i = 0; i < n; ++i) {
// Get references to the data
// See formula in AlignDetectors
double peakPosMeas = (1. + offset) * peakPosFitted[i];
if (peakPosFitted[i] > minD && peakPosFitted[i] < maxD)
errsum += std::fabs(peakPosToFit[i] - peakPosMeas) * height2[i];
}
return errsum;
}
} // namespace
//----------------------------------------------------------------------------------------------
/** The windows should be half of the distance between the peaks of maxWidth,
* whichever is smaller.
* @param dmin :: The minimum d-spacing for the workspace
* @param dmax :: The maximum d-spacing for the workspace
* @param vec_peakcentre :: The list of peaks to generate windows for
* @param maxWidth :: The maximum width of a window
* @return The list of windows for each peak
*/
std::vector<double> generateWindows(const double dmin, const double dmax, const std::vector<double> &vec_peakcentre,
const double maxWidth) {
if (maxWidth <= 0.) {
return std::vector<double>(); // empty vector because this is turned off
}
std::size_t numPeaks = vec_peakcentre.size();
std::vector<double> windows(2 * numPeaks);
double widthLeft;
double widthRight;
for (std::size_t i = 0; i < numPeaks; i++) {
if (i == 0)
widthLeft = vec_peakcentre[i] - dmin;
else
widthLeft = .5 * (vec_peakcentre[i] - vec_peakcentre[i - 1]);
if (i + 1 == numPeaks)
widthRight = dmax - vec_peakcentre[i];
else
widthRight = .5 * (vec_peakcentre[i + 1] - vec_peakcentre[i]);
if (maxWidth > 0) {
widthLeft = std::min(widthLeft, maxWidth);
widthRight = std::min(widthRight, maxWidth);
}
windows[2 * i] = vec_peakcentre[i] - widthLeft;
windows[2 * i + 1] = vec_peakcentre[i] + widthRight;
}
return windows;
}
using namespace Kernel;
using namespace API;
using std::size_t;
using namespace DataObjects;
// Register the class into the algorithm factory
DECLARE_ALGORITHM(GetDetOffsetsMultiPeaks)
//----------------------------------------------------------------------------------------------
/** Constructor
*/
GetDetOffsetsMultiPeaks::GetDetOffsetsMultiPeaks()
: API::Algorithm(), m_inputWS(), m_eventW(), m_isEvent(false), m_backType(), m_peakType(), m_minimizer(),
m_maxChiSq(0.), m_minPeakHeight(0.), m_leastMaxObsY(0.), m_maxOffset(0.), m_peakPositions(), m_fitWindows(),
m_inputResolutionWS(), m_hasInputResolution(false), m_minResFactor(0.), m_maxResFactor(0.), m_outputW(),
m_outputNP(), m_maskWS(), m_infoTableWS(), m_peakOffsetTableWS(), m_resolutionWS(), m_useFitWindowTable(false),
m_vecFitWindow() {}
//----------------------------------------------------------------------------------------------
/** Initialisation method. Declares properties to be used in algorithm.
*/
void GetDetOffsetsMultiPeaks::init() {
declareProperty(std::make_unique<WorkspaceProperty<>>("InputWorkspace", "", Direction::Input,
std::make_shared<WorkspaceUnitValidator>("dSpacing")),
"A 2D matrix workspace with X values of d-spacing");
declareProperty(std::make_unique<ArrayProperty<double>>("DReference"),
"Enter a comma-separated list of the expected X-position of "
"the centre of the peaks. Only peaks near these positions "
"will be fitted.");
declareProperty("FitWindowMaxWidth", 0.,
"Optional: The maximum width of the fitting window. If this "
"is <=0 the window is not specified to FindPeaks");
declareProperty(std::make_unique<WorkspaceProperty<TableWorkspace>>("FitwindowTableWorkspace", "", Direction::Input,
PropertyMode::Optional),
"Name of the input Tableworkspace containing peak fit window "
"information for each spectrum. ");
std::vector<std::string> peaktypes = FunctionFactory::Instance().getFunctionNames<API::IPeakFunction>();
declareProperty("PeakFunction", "Gaussian", std::make_shared<StringListValidator>(peaktypes), "Type of peak to fit");
std::vector<std::string> bkgdtypes{"Flat", "Linear", "Quadratic"};
declareProperty("BackgroundType", "Linear", std::make_shared<StringListValidator>(bkgdtypes),
"Type of Background. The choice can be either Linear or Quadratic");
declareProperty("HighBackground", true, "Relatively weak peak in high background");