Commit 04670177 authored by Danny Hindson's avatar Danny Hindson Committed by Zhang, Chen
Browse files

Various changes

The ParameterMap::diff method has been updated to take an extra
parameter representing a tolerance to be used when comparing double
values between two parameter maps
The overloaded == operator has been modified to call diff with a
zero tolerance to avoid duplicating code
CompareWorkspaces also updated to pass the value of CheckAllData
into diff so diff can stop after first change rather than going
through the whole map
The diff logic has also been speeded up to cope with larger parameter
maps now that diff constants stored (esp for GEM)
Various updates to doc test and system test files
Shorten UnitConversionParameters enum class name
Remove use of EMPTY_DBL() from ConvertUnits::getDetectorValues in
preparation for moving into ExperimentInfo class and also fix
RemoveSpectraTest unit test that relied on this
parent a2501a24
......@@ -1228,11 +1228,10 @@ void IFunction::convertValue(std::vector<double> &values, Kernel::Unit_sptr &out
auto [difa, difc, tzero] = spectrumInfo.diffractometerConstants(wsIndex);
std::vector<double> emptyVec;
Kernel::ExtraParametersMap pmap{
{Kernel::UnitConversionParameters::efixed, efixed},
{Kernel::UnitConversionParameters::difa, difa},
{Kernel::UnitConversionParameters::difc, difc},
{Kernel::UnitConversionParameters::tzero, tzero}};
Kernel::ExtraParametersMap pmap{{Kernel::UnitParams::efixed, efixed},
{Kernel::UnitParams::difa, difa},
{Kernel::UnitParams::difc, difc},
{Kernel::UnitParams::tzero, tzero}};
wsUnit->toTOF(values, emptyVec, l1, l2, twoTheta, emode, pmap);
outUnit->fromTOF(values, emptyVec, l1, l2, twoTheta, emode, pmap);
}
......
......@@ -7,6 +7,7 @@
#pragma once
#include "MantidAPI/Algorithm.h"
#include "MantidAPI/DeprecatedAlgorithm.h"
#include "MantidAPI/ITableWorkspace_fwd.h"
#include "MantidAlgorithms/DllConfig.h"
#include "MantidDataObjects/OffsetsWorkspace.h"
......@@ -39,7 +40,8 @@ class ConversionFactors;
@author Russell Taylor, Tessella Support Services plc
@date 18/08/2008
*/
class MANTID_ALGORITHMS_DLL AlignDetectors : public API::Algorithm {
class MANTID_ALGORITHMS_DLL AlignDetectors : public API::Algorithm,
public API::DeprecatedAlgorithm {
public:
AlignDetectors();
......
......@@ -111,10 +111,10 @@ void AddPeak::exec() {
std::vector<double> xdata(1, tof);
std::vector<double> ydata;
unit->toTOF(xdata, ydata, l1, l2, theta2, emode,
{{Kernel::UnitConversionParameters::efixed, efixed},
{Kernel::UnitConversionParameters::difa, difa},
{Kernel::UnitConversionParameters::difc, difc},
{Kernel::UnitConversionParameters::tzero, tzero}});
{{Kernel::UnitParams::efixed, efixed},
{Kernel::UnitParams::difa, difa},
{Kernel::UnitParams::difc, difc},
{Kernel::UnitParams::tzero, tzero}});
tof = xdata[0];
}
......
......@@ -116,8 +116,11 @@ const std::string AlignDetectors::summary() const {
"values to account for small errors in the detector positions.";
}
/// (Empty) Constructor
AlignDetectors::AlignDetectors() : m_numberOfSpectra(0) {}
/// Constructor
AlignDetectors::AlignDetectors() : m_numberOfSpectra(0) {
useAlgorithm("ConvertUnits");
deprecatedDate("2021-01-04");
}
void AlignDetectors::init() {
auto wsValidator = std::make_shared<CompositeValidator>();
......@@ -281,9 +284,9 @@ void AlignDetectors::align(const ConversionFactors &converter,
std::vector<double> yunused;
dSpacingUnit.fromTOF(
x, yunused, -1., -1., -1., 0,
ExtraParametersMap{{Kernel::UnitConversionParameters::difa, difa},
{Kernel::UnitConversionParameters::difc, difc},
{Kernel::UnitConversionParameters::tzero, tzero}});
ExtraParametersMap{{Kernel::UnitParams::difa, difa},
{Kernel::UnitParams::difc, difc},
{Kernel::UnitParams::tzero, tzero}});
if (eventW) {
Kernel::Units::TOF tofUnit;
......
......@@ -825,10 +825,14 @@ bool CompareWorkspaces::checkInstrument(const API::MatrixWorkspace_const_sptr &w
const Geometry::ParameterMap &ws1_parmap = ws1->constInstrumentParameters();
const Geometry::ParameterMap &ws2_parmap = ws2->constInstrumentParameters();
if (ws1_parmap != ws2_parmap) {
g_log.debug() << "Here information to help understand parameter map differences:\n";
g_log.debug() << ws1_parmap.diff(ws2_parmap);
recordMismatch("Instrument ParameterMap mismatch (differences in ordering ignored)");
const bool checkAllData = getProperty("CheckAllData");
auto errorStr = ws1_parmap.diff(ws2_parmap, !checkAllData);
if (!errorStr.empty()) {
g_log.debug()
<< "Here information to help understand parameter map differences:\n";
g_log.debug() << errorStr;
recordMismatch(
"Instrument ParameterMap mismatch (differences in ordering ignored)");
return false;
}
......
......@@ -106,10 +106,10 @@ void ConvertSpectrumAxis::exec() {
efixed =
getEfixed(spectrumInfo.detector(i), inputWS, emode); // get efixed
auto [difa, difc, tzero] = spectrumInfo.diffractometerConstants(i);
pmap = {{UnitConversionParameters::efixed, efixed},
{UnitConversionParameters::difa, difa},
{UnitConversionParameters::difc, difc},
{UnitConversionParameters::tzero, tzero}};
pmap = {{UnitParams::efixed, efixed},
{UnitParams::difa, difa},
{UnitParams::difc, difc},
{UnitParams::tzero, tzero}};
} else {
twoTheta = 0.0;
l2 = l1;
......
......@@ -420,49 +420,47 @@ bool ConvertUnits::getDetectorValues(const API::SpectrumInfo &spectrumInfo,
twoTheta = std::numeric_limits<double>::quiet_NaN();
}
// If an indirect instrument, try getting Efixed from the geometry
if (emode == 2 &&
pmap[UnitConversionParameters::efixed] == EMPTY_DBL()) // indirect
if (emode == 2 && pmap.find(UnitParams::efixed) == pmap.end()) // indirect
{
if (spectrumInfo.hasUniqueDetector(wsIndex)) {
const auto &det = spectrumInfo.detector(wsIndex);
auto par = ws.constInstrumentParameters().getRecursive(&det, "Efixed");
if (par) {
pmap[UnitConversionParameters::efixed] = par->value<double>();
pmap[UnitParams::efixed] = par->value<double>();
g_log.debug() << "Detector: " << det.getID()
<< " EFixed: " << pmap[UnitConversionParameters::efixed]
<< "\n";
<< " EFixed: " << pmap[UnitParams::efixed] << "\n";
} else {
return false;
}
}
// Non-unique detector (i.e., DetectorGroup): use single provided value
}
auto detids = ws.getSpectrum(wsIndex).getDetectorIDs();
if (detids.size() > 0) {
std::vector<detid_t> warnDetIds;
try {
auto [difa, difc, tzero] =
spectrumInfo.diffractometerConstants(wsIndex, warnDetIds);
pmap[UnitConversionParameters::difa] = difa;
pmap[UnitConversionParameters::difc] = difc;
pmap[UnitConversionParameters::tzero] = tzero;
if (warnDetIds.size() > 0) {
createDetectorIdLogMessages(warnDetIds, wsIndex);
}
if ((outputUnit.unitID().find("dSpacing") != std::string::npos) &&
(difa == 0) && (difc == 0)) {
return false;
}
} catch (const std::runtime_error &e) {
g_log.warning(e.what());
std::vector<detid_t> warnDetIds;
try {
auto [difa, difc, tzero] =
spectrumInfo.diffractometerConstants(wsIndex, warnDetIds);
pmap[UnitParams::difa] = difa;
pmap[UnitParams::difc] = difc;
pmap[UnitParams::tzero] = tzero;
if (warnDetIds.size() > 0) {
createDetectorIdLogMessages(warnDetIds, wsIndex);
}
if ((outputUnit.unitID().find("dSpacing") != std::string::npos) &&
(difa == 0) && (difc == 0)) {
return false;
}
} catch (const std::runtime_error &e) {
g_log.warning(e.what());
}
} else {
twoTheta = 0.0;
pmap[UnitConversionParameters::efixed] = DBL_MIN;
pmap[UnitParams::efixed] = DBL_MIN;
// Energy transfer is meaningless for a monitor, so set l2 to 0.
if (outputUnit.unitID().find("DeltaE") != std::string::npos) {
l2 = 0.0;
}
pmap[UnitConversionParameters::difc] = 0;
pmap[UnitParams::difc] = 0;
// can't do a conversion to d spacing with theta=0
if (outputUnit.unitID().find("dSpacing") != std::string::npos) {
return false;
......@@ -540,12 +538,13 @@ MatrixWorkspace_sptr ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUni
auto localOutputUnit = std::unique_ptr<Unit>(outputUnit->clone());
// Perform Sanity Validation before creating workspace
double checkefixed = efixedProp;
double checkl2;
double checktwoTheta;
const double checkdelta = 0.0;
ExtraParametersMap pmap = {{UnitConversionParameters::efixed, checkefixed},
{UnitConversionParameters::delta, checkdelta}};
ExtraParametersMap pmap = {{UnitParams::delta, checkdelta}};
if (efixedProp != EMPTY_DBL()) {
pmap[UnitParams::efixed] = efixedProp;
}
size_t checkIndex = 0;
if (getDetectorValues(spectrumInfo, *outputUnit, emode, *inputWS, signedTheta,
checkIndex, checkl2, checktwoTheta, pmap)) {
......@@ -576,8 +575,10 @@ MatrixWorkspace_sptr ConvertUnits::convertViaTOF(Kernel::Unit_const_sptr fromUni
const double delta = 0.0;
// TODO toTOF and fromTOF need to be reimplemented outside of kernel
ExtraParametersMap pmap = {{UnitConversionParameters::efixed, efixed},
{UnitConversionParameters::delta, delta}};
ExtraParametersMap pmap = {{UnitParams::delta, delta}};
if (efixedProp != EMPTY_DBL()) {
pmap[UnitParams::efixed] = efixed;
}
if (getDetectorValues(outSpectrumInfo, *outputUnit, emode, *outputWS,
signedTheta, i, l2, twoTheta, pmap)) {
localFromUnit->toTOF(outputWS->dataX(i), emptyVec, l1, l2, twoTheta,
......
......@@ -149,8 +149,7 @@ MatrixWorkspace_sptr ConvertUnitsUsingDetectorTable::convertViaTOF(Kernel::Unit_
// Convert the input unit to time-of-flight
auto checkFromUnit = std::unique_ptr<Unit>(fromUnit->clone());
auto checkOutputUnit = std::unique_ptr<Unit>(outputUnit->clone());
ExtraParametersMap pmap{
{UnitConversionParameters::efixed, efixedColumn[detectorRow]}};
ExtraParametersMap pmap{{UnitParams::efixed, efixedColumn[detectorRow]}};
checkFromUnit->toTOF(checkXValues, emptyVec, l1Column[detectorRow],
l2Column[detectorRow], twoThetaColumn[detectorRow],
emodeColumn[detectorRow], pmap);
......@@ -213,7 +212,7 @@ MatrixWorkspace_sptr ConvertUnitsUsingDetectorTable::convertViaTOF(Kernel::Unit_
std::vector<double> values(outputWS->x(wsid).begin(),
outputWS->x(wsid).end());
ExtraParametersMap pmap{{UnitConversionParameters::efixed, efixed}};
ExtraParametersMap pmap{{UnitParams::efixed, efixed}};
// Convert the input unit to time-of-flight
localFromUnit->toTOF(values, emptyVec, l1, l2, twoTheta, emode, pmap);
// Convert from time-of-flight to the desired unit
......
......@@ -137,13 +137,13 @@ public:
Kernel::Units::dSpacing dSpacingUnit;
std::vector<double> yunused;
dSpacingUnit.toTOF(inTofPos, yunused, -1, -1, -1, 0,
{{Kernel::UnitConversionParameters::difa, difa},
{Kernel::UnitConversionParameters::difc, difc},
{Kernel::UnitConversionParameters::tzero, tzero}});
{{Kernel::UnitParams::difa, difa},
{Kernel::UnitParams::difc, difc},
{Kernel::UnitParams::tzero, tzero}});
dSpacingUnit.toTOF(inTofWindows, yunused, -1, -1, -1, 0,
{{Kernel::UnitConversionParameters::difa, difa},
{Kernel::UnitConversionParameters::difc, difc},
{Kernel::UnitConversionParameters::tzero, tzero}});
{{Kernel::UnitParams::difa, difa},
{Kernel::UnitParams::difc, difc},
{Kernel::UnitParams::tzero, tzero}});
}
std::size_t wkspIndex;
......@@ -634,10 +634,9 @@ void PDCalibration::exec() {
Mantid::Kernel::Units::dSpacing dSpacingUnit;
dSpacingUnit.initialize(
-1., -1., -1., 0,
Kernel::ExtraParametersMap{
{Kernel::UnitConversionParameters::difa, difa},
{Kernel::UnitConversionParameters::difc, difc},
{Kernel::UnitConversionParameters::tzero, t0}});
Kernel::ExtraParametersMap{{Kernel::UnitParams::difa, difa},
{Kernel::UnitParams::difc, difc},
{Kernel::UnitParams::tzero, t0}});
for (std::size_t i = 0; i < numPeaks; ++i) {
if (std::isnan(tof_vec_full[i]))
continue;
......@@ -742,10 +741,9 @@ double gsl_costFunction(const gsl_vector *v, void *peaks) {
Mantid::Kernel::Units::dSpacing dSpacingUnit;
dSpacingUnit.initialize(
-1., -1., -1., 0,
Kernel::ExtraParametersMap{
{Kernel::UnitConversionParameters::difa, difa},
{Kernel::UnitConversionParameters::difc, difc},
{Kernel::UnitConversionParameters::tzero, tzero}});
Kernel::ExtraParametersMap{{Kernel::UnitParams::difa, difa},
{Kernel::UnitParams::difc, difc},
{Kernel::UnitParams::tzero, tzero}});
// calculate the sum of the residuals from observed peaks
double errsum = 0.0;
......
......@@ -257,10 +257,10 @@ void BackgroundHelper::removeBackground(int nHist, HistogramX &x_data, Histogram
// use thread-specific unit conversion class to avoid multithreading issues
Kernel::Unit *unitConv = m_WSUnit[threadNum].get();
unitConv->initialize(L1, L2, twoTheta, m_Emode,
{{UnitConversionParameters::efixed, m_Efix},
{UnitConversionParameters::difa, difa},
{UnitConversionParameters::difc, difc},
{UnitConversionParameters::tzero, tzero}});
{{UnitParams::efixed, m_Efix},
{UnitParams::difa, difa},
{UnitParams::difc, difc},
{UnitParams::tzero, tzero}});
x_data[0] = XValues[0];
double tof1 = unitConv->singleToTOF(x_data[0]);
......
......@@ -255,9 +255,9 @@ void RemoveBins::transformRangeUnit(const int index, double &startX, double &end
std::vector<double> endPoints;
endPoints.emplace_back(startX);
endPoints.emplace_back(endX);
ExtraParametersMap pmap = {{UnitConversionParameters::difa, difa},
{UnitConversionParameters::difc, difc},
{UnitConversionParameters::tzero, tzero}};
ExtraParametersMap pmap = {{UnitParams::difa, difa},
{UnitParams::difc, difc},
{UnitParams::tzero, tzero}};
std::vector<double> emptyVec;
// assume elastic
m_rangeUnit->toTOF(endPoints, emptyVec, l1, l2, theta, 0, pmap);
......
......@@ -151,13 +151,13 @@ public:
void test_exec_difc() {
// setup the peak postions based on transformation from detID=155
using Mantid::Kernel::UnitConversionParameters;
using Mantid::Kernel::UnitParams;
std::vector<double> dValues(PEAK_TOFS);
Mantid::Kernel::Units::dSpacing dSpacingUnit;
std::vector<double> unusedy;
dSpacingUnit.fromTOF(dValues, unusedy, -1., -1., -1., 0,
Mantid::Kernel::ExtraParametersMap{
{UnitConversionParameters::difc, DIFC_155}});
dSpacingUnit.fromTOF(
dValues, unusedy, -1., -1., -1., 0,
Mantid::Kernel::ExtraParametersMap{{UnitParams::difc, DIFC_155}});
const std::string prefix{"PDCalibration_difc"};
......@@ -204,16 +204,16 @@ public:
}
void test_exec_difc_tzero() {
using Mantid::Kernel::UnitConversionParameters;
using Mantid::Kernel::UnitParams;
// setup the peak postions based on transformation from detID=155
const double TZERO = 20.;
std::vector<double> dValues(PEAK_TOFS);
Mantid::Kernel::Units::dSpacing dSpacingUnit;
std::vector<double> unusedy;
dSpacingUnit.fromTOF(dValues, unusedy, -1., -1., -1., 0,
Mantid::Kernel::ExtraParametersMap{
{UnitConversionParameters::difc, DIFC_155},
{UnitConversionParameters::tzero, TZERO}});
dSpacingUnit.fromTOF(
dValues, unusedy, -1., -1., -1., 0,
Mantid::Kernel::ExtraParametersMap{{UnitParams::difc, DIFC_155},
{UnitParams::tzero, TZERO}});
const std::string prefix{"PDCalibration_difc_tzero"};
......@@ -262,17 +262,17 @@ public:
}
void test_exec_difc_tzero_difa() {
using Mantid::Kernel::UnitConversionParameters;
using Mantid::Kernel::UnitParams;
// setup the peak postions based on transformation from detID=155
// allow refining DIFA, but don't set the transformation to require it
const double TZERO = 20.;
std::vector<double> dValues(PEAK_TOFS);
Mantid::Kernel::Units::dSpacing dSpacingUnit;
std::vector<double> unusedy;
dSpacingUnit.fromTOF(dValues, unusedy, -1., -1., -1., 0,
Mantid::Kernel::ExtraParametersMap{
{UnitConversionParameters::difc, DIFC_155},
{UnitConversionParameters::tzero, TZERO}});
dSpacingUnit.fromTOF(
dValues, unusedy, -1., -1., -1., 0,
Mantid::Kernel::ExtraParametersMap{{UnitParams::difc, DIFC_155},
{UnitParams::tzero, TZERO}});
const std::string prefix{"PDCalibration_difc_tzero_difa"};
......@@ -431,14 +431,14 @@ public:
PDCalibrationTestPerformance() { FrameworkManager::Instance(); }
void setUp() override {
using Mantid::Kernel::UnitConversionParameters;
using Mantid::Kernel::UnitParams;
// setup the peak postions based on transformation from detID=155
std::vector<double> dValues(PEAK_TOFS.size());
Mantid::Kernel::Units::dSpacing dSpacingUnit;
std::vector<double> unusedy;
dSpacingUnit.fromTOF(dValues, unusedy, -1., -1., -1., 0,
Mantid::Kernel::ExtraParametersMap{
{UnitConversionParameters::difc, DIFC_155}});
dSpacingUnit.fromTOF(
dValues, unusedy, -1., -1., -1., 0,
Mantid::Kernel::ExtraParametersMap{{UnitParams::difc, DIFC_155}});
createSampleWS();
pdc.initialize();
pdc.setProperty("InputWorkspace", "PDCalibrationTest_WS");
......
......@@ -11,6 +11,7 @@
#include "MantidAPI/AlgorithmManager.h"
#include "MantidAPI/AnalysisDataService.h"
#include "MantidAPI/MatrixWorkspace.h"
#include "MantidAPI/SpectrumInfo.h"
#include "MantidAPI/WorkspaceFactory.h"
#include "MantidAlgorithms/RemoveSpectra.h"
#include "MantidHistogramData/LinearGenerator.h"
......@@ -82,6 +83,7 @@ public:
MatrixWorkspace_sptr inputWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(wsName);
TS_ASSERT_EQUALS(inputWS->x(94).front(), 19900.0);
TS_ASSERT_EQUALS(inputWS->x(144).front(), 19900.0);
TS_ASSERT(!inputWS->spectrumInfo().hasDetectors(144));
RemoveSpectra alg;
alg.initialize();
......@@ -90,14 +92,16 @@ public:
TS_ASSERT_THROWS_NOTHING(alg.setPropertyValue("OutputWorkspace", ouputWsName));
TS_ASSERT_THROWS_NOTHING(alg.execute());
MatrixWorkspace_sptr outputWS = AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(ouputWsName);
// Removed specs are workspace indices 140 and 144/specNum 141 and 145
MatrixWorkspace_sptr outputWS =
AnalysisDataService::Instance().retrieveWS<MatrixWorkspace>(
ouputWsName);
// Removed specs are workspace indices 94 and 144/specNum 95 and 145
TS_ASSERT_EQUALS(outputWS->getNumberHistograms(), 147);
TS_ASSERT_DELTA(outputWS->x(93).front(), 0.41157, 0.0001); // was 93
TS_ASSERT_DELTA(outputWS->x(94).front(), 0.05484, 0.0001); // was 95
TS_ASSERT_DELTA(outputWS->x(95).front(), -0.15111, 0.0001); // was 96
TS_ASSERT_DIFFERS(outputWS->x(143).front(),
19900.0); // Would be 144 if 94 wasn't also removed
TS_ASSERT(outputWS->spectrumInfo().hasDetectors(
143)); // Would be 144 if 144 wasn't also removed
}
private:
......
......@@ -93,10 +93,14 @@ SXPeak::SXPeak(double t, double phi, double intensity, const std::vector<int> &s
const auto unit = Mantid::Kernel::UnitFactory::Instance().create("dSpacing");
unit->initialize(l1, l2, m_twoTheta, 0,
{{Kernel::UnitConversionParameters::difa, difa},
{Kernel::UnitConversionParameters::difc, difc},
{Kernel::UnitConversionParameters::tzero, tzero}});
m_dSpacing = unit->singleFromTOF(m_tof);
{{Kernel::UnitParams::difa, difa},
{Kernel::UnitParams::difc, difc},
{Kernel::UnitParams::tzero, tzero}});
try {
m_dSpacing = unit->singleFromTOF(m_tof);
} catch (std::exception &) {
m_dSpacing = 0;
}
const auto samplePos = spectrumInfo.samplePosition();
const auto sourcePos = spectrumInfo.sourcePosition();
......@@ -352,9 +356,9 @@ double PeakFindingStrategy::convertToTOF(const double xValue, const size_t works
// we're using d-spacing, convert the point to TOF
unit->initialize(m_spectrumInfo.l1(), m_spectrumInfo.l2(workspaceIndex),
m_spectrumInfo.twoTheta(workspaceIndex), 0,
{{Kernel::UnitConversionParameters::difa, difa},
{Kernel::UnitConversionParameters::difc, difc},
{Kernel::UnitConversionParameters::tzero, tzero}});
{{Kernel::UnitParams::difa, difa},
{Kernel::UnitParams::difc, difc},
{Kernel::UnitParams::tzero, tzero}});
return unit->singleToTOF(xValue);
}
}
......
......@@ -616,9 +616,8 @@ Peak PeakHKLErrors::createNewPeak(const DataObjects::Peak &peak_old, const Geome
Wavelength wl;
wl.initialize(
L0, peak.getL2(), peak.getScattering(), 0,
{{UnitConversionParameters::efixed, peak_old.getInitialEnergy()}});
wl.initialize(L0, peak.getL2(), peak.getScattering(), 0,
{{UnitParams::efixed, peak_old.getInitialEnergy()}});
peak.setWavelength(wl.singleFromTOF(T));
peak.setIntensity(peak_old.getIntensity());
......
......@@ -328,7 +328,9 @@ void SaveGSS::generateBankHeader(std::stringstream &out, const API::SpectrumInfo
const auto l1 = spectrumInfo.l1();
const auto l2 = spectrumInfo.l2(specIndex);
const auto twoTheta = spectrumInfo.twoTheta(specIndex);
auto [difa, difc, tzero] = spectrumInfo.diffractometerConstants(specIndex);
double difc;
std::tie(std::ignore, difc, std::ignore) =
spectrumInfo.diffractometerConstants(specIndex);
out << "# Total flight path " << (l1 + l2) << "m, tth "
<< (twoTheta * 180. / M_PI) << "deg, DIFC " << difc << "\n";
}
......
......@@ -75,7 +75,10 @@ public:
static const std::string &pQuat();
static const std::string &scale();
const std::string diff(const ParameterMap &rhs, const bool &firstDiffOnly = false) const;
const std::string
diff(const ParameterMap &rhs, const bool &firstDiffOnly = false,
const bool relative = false,
const double doubleTolerance = Kernel::Tolerance) const;
/// Inquality comparison operator
bool operator!=(const ParameterMap &rhs) const;
......@@ -301,7 +304,10 @@ private:
component_map_it positionOf(const IComponent *comp, const char *name, const char *type);
/// const version of the internal function to get position of the parameter in
/// the parameter map
component_map_cit positionOf(const IComponent *comp, const char *name, const char *type) const;
component_map_cit positionOf(const IComponent *comp, const char *name,
const char *type) const;
/// calculate relative error for use in diff
bool relErr(double x1, double x2, double errorVal) const;
/// internal list of parameter files loaded
std::vector<std::string> m_parameterFileNames;
......
......@@ -129,36 +129,7 @@ bool ParameterMap::operator!=(const ParameterMap &rhs) const { return !(this->op
* @return true if the objects are considered equal, false otherwise
*/
bool ParameterMap::operator==(const ParameterMap &rhs) const {
if (this == &rhs)
return true; // True for the same object
// Quick size check
if (this->size() != rhs.size())
return false;
// The map is unordered and the key is only valid at runtime. The
// asString method turns the ComponentIDs to full-qualified name identifiers
// so we will use the same approach to compare them
auto thisEnd = this->m_map.cend();
auto rhsEnd = rhs.m_map.cend();
for (auto thisIt = this->m_map.begin(); thisIt != thisEnd; ++thisIt) {
const IComponent *comp = static_cast<IComponent *>(thisIt->first);
const std::string fullName = comp->getFullName();
const auto &param = thisIt->second;
bool match(false);
for (auto rhsIt = rhs.m_map.cbegin(); rhsIt != rhsEnd; ++rhsIt) {
const IComponent *rhsComp = static_cast<IComponent *>(rhsIt->first);
const std::string rhsFullName = rhsComp->getFullName();
if (fullName == rhsFullName && (*param) == (*rhsIt->second)) {
match = true;
break;
}
}
if (!match)
return false;
}
return true;
return diff(rhs, true, false, 0.).empty();
}
/** Get the component description by name
......@@ -205,6 +176,31 @@ const std::string ParameterMap::getShortDescription(const std::string &compName,
}
return result;
}
//------------------------------------------------------------------------------------------------
/** Function which calculates relative error between two values and analyses if
this error is within the limits
* requested. When the absolute value of the difference is smaller then the value
of the error requested,
* absolute error is used instead of relative error.
@param x1 -- first value to check difference
@param x2 -- second value to check difference
@param errorVal -- the value of the error, to check against. Should be large
then 0
@returns true if error or false if the value is within the limits requested