Commit 90ff8954 authored by Mathieu Tillet's avatar Mathieu Tillet
Browse files

Merge branch '28352_instrument_view_extensions' of...

Merge branch '28352_instrument_view_extensions' of https://github.com/mantidproject/mantid into 28352_instrument_view_extensions
parents b2c76c86 c53dbbc6
......@@ -17,6 +17,8 @@ exclude =
qt/applications/workbench/workbench/app/resources.py,
qt/paraview_ext,
qt/python/mantidqt/resources.py,
qt/python/mantidqt/dialogs/errorreports/resources_qt4.py
qt/python/mantidqt/dialogs/errorreports/resources_qt5.py
qt/scientific_interfaces,
qt/widgets,
scripts/test,
......@@ -25,8 +27,6 @@ exclude =
Testing/SystemTests/scripts,
Testing/SystemTests/tests/analysis/reference,
Testing/Tools,
scripts/ErrorReporter/ui_errorreport.py,
scripts/Interface/ui/dataprocessorinterface,
max-complexity = 20
......
......@@ -39,6 +39,7 @@ set(SRC_FILES
src/Expression.cpp
src/FileBackedExperimentInfo.cpp
src/FileFinder.cpp
src/InstrumentFileFinder.cpp
src/FileLoaderRegistry.cpp
src/FileProperty.cpp
src/FrameworkManager.cpp
......@@ -68,7 +69,7 @@ set(SRC_FILES
src/IFunctionGeneral.cpp
src/IFunctionMD.cpp
src/IFunctionMW.cpp
src/IJournal.cpp
src/IJournal.cpp
src/ILatticeFunction.cpp
src/IMDEventWorkspace.cpp
src/IMDHistoWorkspace.cpp
......@@ -152,7 +153,8 @@ set(SRC_FILES
src/WorkspaceNearestNeighbours.cpp
src/WorkspaceOpOverloads.cpp
src/WorkspaceProperty.cpp
src/WorkspaceUnitValidator.cpp)
src/WorkspaceUnitValidator.cpp
)
set(SRC_UNITY_IGNORE_FILES
src/CompositeFunction.cpp
......@@ -161,7 +163,8 @@ set(SRC_UNITY_IGNORE_FILES
src/IEventWorkspace.cpp
src/IFunctionMD.cpp
src/IPeakFunction.cpp
src/IPowderDiffPeakFunction.cpp)
src/IPowderDiffPeakFunction.cpp
)
set(INC_FILES
inc/MantidAPI/ADSValidator.h
......@@ -208,6 +211,7 @@ set(INC_FILES
inc/MantidAPI/Expression.h
inc/MantidAPI/FileBackedExperimentInfo.h
inc/MantidAPI/FileFinder.h
inc/MantidAPI/InstrumentFileFinder.h
inc/MantidAPI/FileLoaderRegistry.h
inc/MantidAPI/FileProperty.h
inc/MantidAPI/FrameworkManager.h
......@@ -360,14 +364,14 @@ set(INC_FILES
inc/MantidAPI/WorkspaceProperty.h
inc/MantidAPI/WorkspaceProperty.tcc
inc/MantidAPI/WorkspaceUnitValidator.h
inc/MantidAPI/Workspace_fwd.h)
inc/MantidAPI/Workspace_fwd.h
)
option(PROFILE_ALGORITHM_LINUX "Profile algorithm execution on Linux" OFF)
if(PROFILE_ALGORITHM_LINUX)
set(SRC_FILES
"${SRC_FILES}"
"src/AlgorithmExecuteProfile.cpp"
"src/AlgoTimeRegister.cpp")
set(SRC_FILES "${SRC_FILES}" "src/AlgorithmExecuteProfile.cpp"
"src/AlgoTimeRegister.cpp"
)
set(INC_FILES "${INC_FILES}" "inc/MantidAPI/AlgoTimeRegister.h")
else()
set(SRC_FILES "${SRC_FILES}" "src/AlgorithmExecute.cpp")
......@@ -403,6 +407,7 @@ set(TEST_FILES
ExpressionTest.h
FileBackedExperimentInfoTest.h
FileFinderTest.h
InstrumentFileFinderTest.h
FilePropertyTest.h
FrameworkManagerTest.h
FuncMinimizerFactoryTest.h
......@@ -484,18 +489,20 @@ set(TEST_FILES
WorkspaceNearestNeighboursTest.h
WorkspaceOpOverloadsTest.h
WorkspacePropertyTest.h
WorkspaceUnitValidatorTest.h)
WorkspaceUnitValidatorTest.h
)
set(GMOCK_TEST_FILES
ImplicitFunctionFactoryTest.h
ImplicitFunctionParameterParserFactoryTest.h
MatrixWorkspaceTest.h)
ImplicitFunctionFactoryTest.h ImplicitFunctionParameterParserFactoryTest.h
MatrixWorkspaceTest.h
)
if(COVERALLS)
foreach(loop_var ${SRC_FILES} ${INC_FILES})
set_property(GLOBAL APPEND
PROPERTY COVERAGE_SRCS
"${CMAKE_CURRENT_SOURCE_DIR}/${loop_var}")
set_property(
GLOBAL APPEND PROPERTY COVERAGE_SRCS
"${CMAKE_CURRENT_SOURCE_DIR}/${loop_var}"
)
endforeach(loop_var)
endif()
......@@ -515,14 +522,15 @@ enable_precompiled_headers(inc/MantidAPI/PrecompiledHeader.h SRC_FILES)
# Add the target for this directory
add_library(API ${SRC_FILES} ${INC_FILES})
# Set the name of the generated library
set_target_properties(API
PROPERTIES OUTPUT_NAME
MantidAPI
COMPILE_DEFINITIONS
IN_MANTID_API)
set_target_properties(
API PROPERTIES OUTPUT_NAME MantidAPI COMPILE_DEFINITIONS IN_MANTID_API
)
if(${CMAKE_SYSTEM_NAME} MATCHES "Darwin")
set_target_properties(API PROPERTIES INSTALL_RPATH "@loader_path/../MacOS;@loader_path/../Frameworks")
set_target_properties(
API PROPERTIES INSTALL_RPATH
"@loader_path/../MacOS;@loader_path/../Frameworks"
)
elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
set_target_properties(API PROPERTIES INSTALL_RPATH "\$ORIGIN/../${LIB_DIR}")
endif()
......@@ -530,17 +538,19 @@ endif()
# Add to the 'Framework' group in VS
set_property(TARGET API PROPERTY FOLDER "MantidFramework")
target_include_directories (API SYSTEM PUBLIC ${NEXUS_INCLUDE_DIR} ${Boost_INCLUDE_DIRS})
target_link_libraries(API
LINK_PRIVATE
${TCMALLOC_LIBRARIES_LINKTIME}
${JSONCPP_LIBRARIES}
${MANTIDLIBS}
${GSL_LIBRARIES}
${NEXUS_LIBRARIES}
${WINSOCK}
${BCRYPT})
target_include_directories(
API SYSTEM PUBLIC ${NEXUS_INCLUDE_DIR} ${Boost_INCLUDE_DIRS}
)
target_link_libraries(
API
LINK_PRIVATE
${JSONCPP_LIBRARIES}
${MANTIDLIBS}
${GSL_LIBRARIES}
${NEXUS_LIBRARIES}
${WINSOCK}
${BCRYPT}
)
# Add the unit tests directory
add_subdirectory(test)
......
......@@ -12,8 +12,10 @@
#include "MantidAPI/DllConfig.h"
#include "MantidKernel/DynamicFactory.h"
#include "MantidKernel/SingletonHolder.h"
#include <boost/optional.hpp>
#include <memory>
#include <sstream>
#include <unordered_map>
#include <unordered_set>
#include <vector>
......@@ -73,9 +75,10 @@ public:
std::pair<std::string, int>
subscribe(std::unique_ptr<Kernel::AbstractInstantiator<T>> instantiator,
const SubscribeAction replaceExisting = ErrorIfExists) {
std::shared_ptr<IAlgorithm> tempAlg = instantiator->createInstance();
const auto tempAlg = instantiator->createInstance();
const int version = extractAlgVersion(tempAlg);
const std::string className = extractAlgName(tempAlg);
const std::string alias = extractAlgAlias(tempAlg);
typename VersionMap::const_iterator it = m_vmap.find(className);
if (!className.empty()) {
const std::string key = createName(className, version);
......@@ -97,6 +100,10 @@ public:
} else {
throw std::invalid_argument("Cannot register empty algorithm name");
}
if (!alias.empty())
m_amap[alias] = className;
return std::make_pair(className, version);
}
/// Unsubscribe the given algorithm
......@@ -108,6 +115,10 @@ public:
const std::vector<std::string> getKeys() const override;
const std::vector<std::string> getKeys(bool includeHidden) const;
/// Get an algorithms name from the alias map
boost::optional<std::string>
getRealNameFromAlias(const std::string &alias) const noexcept;
/// Returns the highest version of the algorithm currently registered
int highestVersion(const std::string &algorithmName) const;
......@@ -120,7 +131,7 @@ public:
/// Returns algorithm descriptors.
std::vector<AlgorithmDescriptor>
getDescriptors(bool includeHidden = false) const;
getDescriptors(bool includeHidden = false, bool includeAliases = false) const;
/// unmangles the names used as keys into the name and version
std::pair<std::string, int> decodeName(const std::string &mangledName) const;
......@@ -133,6 +144,9 @@ private:
extractAlgName(const std::shared_ptr<IAlgorithm> &alg) const;
/// Extract the version of an algorithm
int extractAlgVersion(const std::shared_ptr<IAlgorithm> &alg) const;
/// Extract the alias of an algorithm
const std::string
extractAlgAlias(const std::shared_ptr<IAlgorithm> &alg) const;
/// Create an algorithm object with the specified name
std::shared_ptr<Algorithm> createAlgorithm(const std::string &name,
......@@ -151,6 +165,10 @@ private:
using VersionMap = std::map<std::string, int>;
/// The map holding the registered class names and their highest versions
VersionMap m_vmap;
/// A typedef for the map of algorithm aliases
using AliasMap = std::unordered_map<std::string, std::string>;
/// The map holding the alias names of registered algorithms
AliasMap m_amap;
};
using AlgorithmFactory = Mantid::Kernel::SingletonHolder<AlgorithmFactoryImpl>;
......
......@@ -147,17 +147,6 @@ public:
// run end time if available, empty otherwise
std::string getAvailableWorkspaceEndDate() const;
/// Utility to retrieve the validity dates for the given IDF
static void getValidFromTo(const std::string &IDFfilename,
std::string &outValidFrom,
std::string &outValidTo);
/// Utility to retrieve a resource file (IDF, Parameters, ..)
static std::vector<std::string> getResourceFilenames(
const std::string &prefix, const std::vector<std::string> &fileFormats,
const std::vector<std::string> &directoryNames, const std::string &date);
/// Get the IDF using the instrument name and date
static std::string getInstrumentFilename(const std::string &instrumentName,
const std::string &date = "");
const Geometry::DetectorInfo &detectorInfo() const;
Geometry::DetectorInfo &mutableDetectorInfo();
......
// Mantid Repository : https://github.com/mantidproject/mantid
//
// Copyright &copy; 2020 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/DllConfig.h"
#include <string>
#include <vector>
namespace Mantid::API {
class MANTID_API_DLL InstrumentFileFinder {
public:
/// Search instrument directories for Parameter file,
/// return full path name if found, else "".
static std::string getParameterPath(const std::string &instName,
const std::string &dirHint = "");
/// Get the IDF using the instrument name and date
static std::string getInstrumentFilename(const std::string &instrumentName,
const std::string &date = "");
/// Utility to retrieve a resource file (IDF, Parameters, ..)
static std::vector<std::string> getResourceFilenames(
const std::string &prefix, const std::vector<std::string> &fileFormats,
const std::vector<std::string> &directoryNames, const std::string &date);
/// Utility to retrieve the validity dates for the given IDF
static void getValidFromTo(const std::string &IDFfilename,
std::string &outValidFrom,
std::string &outValidTo);
private:
static std::string lookupIPF(const std::string &dir, std::string filename);
};
} // Namespace Mantid::API
......@@ -68,6 +68,7 @@ public:
double twoTheta(const size_t index) const;
double signedTwoTheta(const size_t index) const;
double azimuthal(const size_t index) const;
std::pair<double, double> geographicalAngles(const size_t index) const;
Kernel::V3D position(const size_t index) const;
bool hasDetectors(const size_t index) const;
bool hasUniqueDetector(const size_t index) const;
......
......@@ -25,7 +25,7 @@ Kernel::Logger g_log("AlgorithmFactory");
} // namespace
AlgorithmFactoryImpl::AlgorithmFactoryImpl()
: Kernel::DynamicFactory<Algorithm>(), m_vmap() {
: Kernel::DynamicFactory<Algorithm>(), m_vmap(), m_amap() {
// we need to make sure the library manager has been loaded before we
// are constructed so that it is destroyed after us and thus does
// not close any loaded DLLs with loaded algorithms in them
......@@ -44,34 +44,38 @@ std::shared_ptr<Algorithm>
AlgorithmFactoryImpl::create(const std::string &name,
const int &version) const {
int local_version = version;
if (version < 0) {
if (version == -1) // get latest version since not supplied
{
auto it = m_vmap.find(name);
if (!name.empty()) {
if (it == m_vmap.end())
throw std::runtime_error("Algorithm not registered " + name);
else
local_version = it->second;
} else
throw std::runtime_error(
"Algorithm not registered (empty algorithm name)");
}
// Version not supplied
if (version == -1) {
local_version = highestVersion(name); // throws if not found
}
// Try create from given name
try {
return this->createAlgorithm(name, local_version);
} catch (Kernel::Exception::NotFoundError &) {
auto it = m_vmap.find(name);
if (it == m_vmap.end())
throw std::runtime_error("algorithm not registered " + name);
else {
}
// Fallback, name might be an alias
// Try get real name and create from that instead
const auto realName = getRealNameFromAlias(name);
if (realName) {
// Try create algorithm again with real name
try {
return this->createAlgorithm(realName.get(), local_version);
} catch (Kernel::Exception::NotFoundError &) {
// Get highest registered version
const auto hVersion =
highestVersion(realName.get()); // Throws if not found
// The version registered does not match version supplied
g_log.error() << "algorithm " << name << " version " << version
<< " is not registered \n";
g_log.error() << "the latest registered version is " << it->second
<< '\n';
g_log.error() << "the latest registered version is " << hVersion << '\n';
throw std::runtime_error("algorithm not registered " +
createName(name, local_version));
}
} else {
throw std::runtime_error("algorithm not registered " + name);
}
}
......@@ -154,10 +158,9 @@ AlgorithmFactoryImpl::decodeName(const std::string &mangledName) const {
return std::pair<std::string, int>(name, version);
}
/** Return the keys used for identifying algorithms. This includes those within
* the Factory itself and
* any cleanly constructed algorithms stored here.
* Hidden algorithms are excluded.
/** Return the keys used for identifying algorithms. This includes those
* within the Factory itself and any cleanly constructed algorithms stored
* here. Hidden algorithms are excluded.
* @returns The strings used to identify individual algorithms
*/
const std::vector<std::string> AlgorithmFactoryImpl::getKeys() const {
......@@ -172,8 +175,8 @@ const std::vector<std::string> AlgorithmFactoryImpl::getKeys() const {
* Return the keys used for identifying algorithms. This includes those within
* the Factory itself and
* any cleanly constructed algorithms stored here.
* @param includeHidden true includes the hidden algorithm names and is faster,
* the default is false
* @param includeHidden true includes the hidden algorithm names and is
* faster, the default is false
* @returns The strings used to identify individual algorithms
*/
const std::vector<std::string>
......@@ -214,8 +217,8 @@ AlgorithmFactoryImpl::getKeys(bool includeHidden) const {
}
if (!toBeRemoved) {
// just mark them to be removed as we are iterating around the vector at
// the moment
// just mark them to be removed as we are iterating around the vector
// at the moment
validNames.emplace_back(name);
}
}
......@@ -223,6 +226,20 @@ AlgorithmFactoryImpl::getKeys(bool includeHidden) const {
}
}
/**
* @param alias The name of the algorithm to look up in the alias map
* @return Real name of algroithm if found
*/
boost::optional<std::string>
AlgorithmFactoryImpl::getRealNameFromAlias(const std::string &alias) const
noexcept {
auto a_it = m_amap.find(alias);
if (a_it == m_amap.end())
return boost::none;
else
return a_it->second;
}
/**
* @param algorithmName The name of an algorithm registered with the factory
* @return An integer corresponding to the highest version registered
......@@ -234,9 +251,19 @@ int AlgorithmFactoryImpl::highestVersion(
if (viter != m_vmap.end())
return viter->second;
else {
throw std::invalid_argument(
"AlgorithmFactory::highestVersion() - Unknown algorithm '" +
algorithmName + "'");
// Fall back, algorithmName might be an alias
// Check alias map, then find version from real name
const auto realName = getRealNameFromAlias(algorithmName);
if (realName != boost::none) {
viter = m_vmap.find(realName.get());
}
if (viter != m_vmap.end())
return viter->second;
else {
throw std::runtime_error(
"AlgorithmFactory::highestVersion() - Unknown algorithm '" +
algorithmName + "'");
}
}
}
......@@ -255,8 +282,8 @@ AlgorithmFactoryImpl::getCategoriesWithState() const {
std::unordered_set<std::string> hiddenCategories;
fillHiddenCategories(&hiddenCategories);
// get all of the algorithm keys, including the hidden ones for speed purposes
// we will filter later if required
// get all of the algorithm keys, including the hidden ones for speed
// purposes we will filter later if required
std::vector<std::string> names = getKeys(true);
std::vector<std::string>::const_iterator itr_end = names.end();
......@@ -290,8 +317,8 @@ AlgorithmFactoryImpl::getCategoriesWithState() const {
* Return the categories of the algorithms. This includes those within the
* Factory itself and
* any cleanly constructed algorithms stored here.
* @param includeHidden true includes the hidden algorithm names and is faster,
* the default is false
* @param includeHidden true includes the hidden algorithm names and is
* faster, the default is false
* @returns The category strings
*/
const std::unordered_set<std::string>
......@@ -317,12 +344,15 @@ AlgorithmFactoryImpl::getCategories(bool includeHidden) const {
* map
* where an algorithm has multiple categories it will be represented using
* multiple descriptors.
* @param includeHidden true includes the hidden algorithm names and is faster,
* the default is false
* @param includeHidden true includes the hidden algorithm names and is
* faster, the default is false
* @param includeAliases true includes alias names of algorithms which aren't
* empty to the vector of descriptors, the default is true
* @returns A vector of descriptor objects
*/
std::vector<AlgorithmDescriptor>
AlgorithmFactoryImpl::getDescriptors(bool includeHidden) const {
AlgorithmFactoryImpl::getDescriptors(bool includeHidden,
bool includeAliases) const {
// algorithm names
auto sv = getKeys(true);
......@@ -382,8 +412,19 @@ AlgorithmFactoryImpl::getDescriptors(bool includeHidden) const {
currentLayer.append("\\");
}
if (!categoryIsHidden)
if (!categoryIsHidden) {
res.emplace_back(desc);
// Add alias to results if included
if (!desc.alias.empty() && includeAliases) {
/*AlgorithmDescriptor aliasDesc;
aliasDesc.name = desc.alias;
aliasDesc.category = desc.category;
aliasDesc.version = desc.version;
res.emplace_back(aliasDesc);*/
res.emplace_back(
AlgorithmDescriptor{desc.alias, desc.version, desc.category, ""});
}
}
}
}
return res;
......@@ -419,10 +460,19 @@ int AlgorithmFactoryImpl::extractAlgVersion(
return alg->version();
}
/** Extract the alias of an algorithm
* @param alg :: the Algorithm to use
* @returns the alias of the algorithm
*/
const std::string AlgorithmFactoryImpl::extractAlgAlias(
const std::shared_ptr<IAlgorithm> &alg) const {
return alg->alias();
}
/**
* Create a shared pointer to an algorithm object with the given name and
* version. If the algorithm is one registered with a clean pointer rather than
* an instantiator then a clone is returned.
* version. If the algorithm is one registered with a clean pointer rather
* than an instantiator then a clone is returned.
* @param name :: Algorithm name
* @param version :: Algorithm version
* @returns A shared pointer to the algorithm object
......
......@@ -6,6 +6,7 @@
// SPDX - License - Identifier: GPL - 3.0 +
#include "MantidAPI/ExperimentInfo.h"
#include "MantidAPI/InstrumentDataService.h"
#include "MantidAPI/InstrumentFileFinder.h"
#include "MantidAPI/ResizeRectangularDetectorHelper.h"
#include "MantidAPI/Run.h"
#include "MantidAPI/Sample.h"
......@@ -43,20 +44,17 @@
#include <boost/algorithm/string.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/regex.hpp>
#include <memory>
#include <Poco/DirectoryIterator.h>
#include <Poco/Path.h>
#include <Poco/SAX/Attributes.h>
#include <Poco/SAX/ContentHandler.h>
#include <Poco/SAX/SAXParser.h>
#include <nexus/NeXusException.hpp>
#include <algorithm>
#include <memory>
#include <tuple>
using namespace Mantid::Geometry;
using namespace Mantid::Kernel;
using namespace Mantid::Types::Core;
using namespace Poco::XML;
namespace Mantid {
......@@ -65,42 +63,6 @@ namespace {
/// static logger object
Kernel::Logger g_log("ExperimentInfo");
// used to terminate SAX process
class DummyException {
public:
std::string m_validFrom;
std::string m_validTo;
DummyException(const std::string &validFrom, const std::string &validTo)
: m_validFrom(validFrom), m_validTo(validTo) {}
};
// SAX content handler for grapping stuff quickly from IDF
class myContentHandler : public Poco::XML::ContentHandler {
void startElement(const XMLString & /*uri*/, const XMLString &localName,
const XMLString & /*qname*/,
const Attributes &attrList) override {
if (localName == "instrument" || localName == "parameter-file") {
throw DummyException(
static_cast<std::string>(attrList.getValue("", "valid-from")),
static_cast<std::string>(attrList.getValue("", "valid-to")));
}
}
void endElement(const XMLString & /*uri*/, const XMLString & /*localName*/,
const XMLString & /*qname*/) override {}
void startDocument() override {}
void endDocument() override {}
void characters(const XMLChar /*ch*/[], int /*start*/,
int /*length*/) override {}
void endPrefixMapping(const XMLString & /*prefix*/) override {}
void ignorableWhitespace(const XMLChar /*ch*/[], int /*start*/,
int /*length*/) override {}
void processingInstruction(const XMLString & /*target*/,
const XMLString & /*data*/) override {}
void setDocumentLocator(const Locator * /*loc*/) override {}
void skippedEntity(const XMLString & /*name*/) override {}
void startPrefixMapping(const XMLString & /*prefix*/,
const XMLString & /*uri*/) override {}
};
} // namespace
/** Constructor
......@@ -815,194 +777,7 @@ std::string ExperimentInfo::getAvailableWorkspaceEndDate() const {
return date;
}
/** Return from an IDF the values of the valid-from and valid-to attributes
*
* @param IDFfilename :: Full path of an IDF
* @param[out] outValidFrom :: Used to return valid-from date
* @param[out] outValidTo :: Used to return valid-to date
*/