22
22
#include " MantidGeometry/Crystal/IPeak.h"
23
23
#include " MantidGeometry/Instrument/ComponentInfo.h"
24
24
#include " MantidGeometry/Instrument/DetectorInfo.h"
25
+ #include " MantidKernel/FloatingPointComparison.h"
25
26
#include " MantidKernel/Unit.h"
26
27
27
28
namespace Mantid ::Algorithms {
@@ -71,23 +72,18 @@ int compareEventLists(Kernel::Logger &logger, const EventList &el1, const EventL
71
72
const auto &e1 = events1[i];
72
73
const auto &e2 = events2[i];
73
74
74
- bool diffpulse = false ;
75
- bool difftof = false ;
76
- bool diffweight = false ;
77
- if (std::abs (e1 .pulseTime ().totalNanoseconds () - e2 .pulseTime ().totalNanoseconds ()) > tolPulse) {
78
- diffpulse = true ;
79
- ++numdiffpulse;
80
- }
81
- if (std::abs (e1 .tof () - e2 .tof ()) > tolTof) {
82
- difftof = true ;
83
- ++numdifftof;
84
- }
75
+ bool diffpulse =
76
+ !withinAbsoluteDifference (e1 .pulseTime ().totalNanoseconds (), e2 .pulseTime ().totalNanoseconds (), tolPulse);
77
+ bool difftof = !withinAbsoluteDifference (e1 .tof (), e2 .tof (), tolTof);
78
+ bool diffweight = !withinAbsoluteDifference (e1 .weight (), e2 .weight (), tolWeight);
85
79
if (diffpulse && difftof)
86
- ++numdiffboth;
87
- if (std::abs (e1 .weight () - e2 .weight ()) > tolWeight) {
88
- diffweight = true ;
89
- ++numdiffweight;
90
- }
80
+ numdiffboth++;
81
+ if (diffpulse)
82
+ numdiffpulse++;
83
+ if (difftof)
84
+ numdifftof++;
85
+ if (diffweight)
86
+ numdiffweight++;
91
87
92
88
bool same = (!diffpulse) && (!difftof) && (!diffweight);
93
89
if (!same) {
@@ -148,6 +144,8 @@ void CompareWorkspaces::init() {
148
144
" Very often such logs are huge so making it true should be "
149
145
" the last option." );
150
146
147
+ declareProperty (" NaNsEqual" , false , " Whether NaN values should compare as equal with other NaN values." );
148
+
151
149
declareProperty (" NumberMismatchedSpectraToPrint" , 1 , " Number of mismatched spectra from lowest to be listed. " );
152
150
153
151
declareProperty (" DetailedPrintIndex" , EMPTY_INT (), " Mismatched spectra that will be printed out in details. " );
@@ -172,13 +170,14 @@ void CompareWorkspaces::exec() {
172
170
m_parallelComparison = false ;
173
171
174
172
double const tolerance = getProperty (" Tolerance" );
173
+ bool const nanEqual = getProperty (" NaNsEqual" );
175
174
if (getProperty (" ToleranceRelErr" )) {
176
- this ->m_compare = [tolerance](double const x1, double const x2) -> bool {
177
- return CompareWorkspaces::withinRelativeTolerance (x1, x2, tolerance);
175
+ this ->m_compare = [tolerance, nanEqual ](double const x1, double const x2) -> bool {
176
+ return CompareWorkspaces::withinRelativeTolerance (x1, x2, tolerance, nanEqual );
178
177
};
179
178
} else {
180
- this ->m_compare = [tolerance](double const x1, double const x2) -> bool {
181
- return CompareWorkspaces::withinAbsoluteTolerance (x1, x2, tolerance);
179
+ this ->m_compare = [tolerance, nanEqual ](double const x1, double const x2) -> bool {
180
+ return CompareWorkspaces::withinAbsoluteTolerance (x1, x2, tolerance, nanEqual );
182
181
};
183
182
}
184
183
@@ -1049,10 +1048,11 @@ void CompareWorkspaces::doPeaksComparison(PeaksWorkspace_sptr tws1, PeaksWorkspa
1049
1048
}
1050
1049
1051
1050
const bool isRelErr = getProperty (" ToleranceRelErr" );
1051
+ const bool checkAllData = getProperty (" CheckAllData" );
1052
1052
for (int i = 0 ; i < tws1->getNumberPeaks (); i++) {
1053
1053
const Peak &peak1 = tws1->getPeak (i);
1054
1054
const Peak &peak2 = tws2->getPeak (i);
1055
- for (size_t j = 0 ; j < tws1->columnCount (); j++) {
1055
+ for (std:: size_t j = 0 ; j < tws1->columnCount (); j++) {
1056
1056
std::shared_ptr<const API::Column> col = tws1->getColumn (j);
1057
1057
std::string name = col->name ();
1058
1058
double s1 = 0.0 ;
@@ -1127,7 +1127,8 @@ void CompareWorkspaces::doPeaksComparison(PeaksWorkspace_sptr tws1, PeaksWorkspa
1127
1127
<< " value1 = " << s1 << " \n "
1128
1128
<< " value2 = " << s2 << " \n " ;
1129
1129
recordMismatch (" Data mismatch" );
1130
- return ;
1130
+ if (!checkAllData)
1131
+ return ;
1131
1132
}
1132
1133
}
1133
1134
}
@@ -1163,8 +1164,10 @@ void CompareWorkspaces::doLeanElasticPeaksComparison(const LeanElasticPeaksWorks
1163
1164
1164
1165
const double tolerance = getProperty (" Tolerance" );
1165
1166
const bool isRelErr = getProperty (" ToleranceRelErr" );
1167
+ const bool checkAllData = getProperty (" CheckAllData" );
1168
+ const bool nanEqual = getProperty (" NaNsEqual" );
1166
1169
for (int peakIndex = 0 ; peakIndex < ipws1->getNumberPeaks (); peakIndex++) {
1167
- for (size_t j = 0 ; j < ipws1->columnCount (); j++) {
1170
+ for (std:: size_t j = 0 ; j < ipws1->columnCount (); j++) {
1168
1171
std::shared_ptr<const API::Column> col = ipws1->getColumn (j);
1169
1172
const std::string name = col->name ();
1170
1173
double s1 = 0.0 ;
@@ -1229,10 +1232,10 @@ void CompareWorkspaces::doLeanElasticPeaksComparison(const LeanElasticPeaksWorks
1229
1232
// bool mismatch = !m_compare(s1, s2)
1230
1233
// can replace this if/else, and isRelErr and tolerance can be deleted
1231
1234
if (isRelErr && name != " QLab" && name != " QSample" ) {
1232
- if (!withinRelativeTolerance (s1, s2, tolerance)) {
1235
+ if (!withinRelativeTolerance (s1, s2, tolerance, nanEqual )) {
1233
1236
mismatch = true ;
1234
1237
}
1235
- } else if (!withinAbsoluteTolerance (s1, s2, tolerance)) {
1238
+ } else if (!withinAbsoluteTolerance (s1, s2, tolerance, nanEqual )) {
1236
1239
mismatch = true ;
1237
1240
}
1238
1241
if (mismatch) {
@@ -1242,7 +1245,8 @@ void CompareWorkspaces::doLeanElasticPeaksComparison(const LeanElasticPeaksWorks
1242
1245
<< " value1 = " << s1 << " \n "
1243
1246
<< " value2 = " << s2 << " \n " ;
1244
1247
recordMismatch (" Data mismatch" );
1245
- return ;
1248
+ if (!checkAllData)
1249
+ return ;
1246
1250
}
1247
1251
}
1248
1252
}
@@ -1283,19 +1287,23 @@ void CompareWorkspaces::doTableComparison(const API::ITableWorkspace_const_sptr
1283
1287
1284
1288
const bool checkAllData = getProperty (" CheckAllData" );
1285
1289
const bool isRelErr = getProperty (" ToleranceRelErr" );
1290
+ const bool nanEqual = getProperty (" NaNsEqual" );
1286
1291
const double tolerance = getProperty (" Tolerance" );
1287
1292
bool mismatch;
1288
- for (size_t i = 0 ; i < numCols; ++i) {
1293
+ for (std:: size_t i = 0 ; i < numCols; ++i) {
1289
1294
const auto c1 = tws1->getColumn (i);
1290
1295
const auto c2 = tws2->getColumn (i);
1291
1296
1292
1297
if (isRelErr) {
1293
- mismatch = !c1->equalsRelErr (*c2, tolerance);
1298
+ mismatch = !c1->equalsRelErr (*c2, tolerance, nanEqual );
1294
1299
} else {
1295
- mismatch = !c1->equals (*c2, tolerance);
1300
+ mismatch = !c1->equals (*c2, tolerance, nanEqual );
1296
1301
}
1297
1302
if (mismatch) {
1298
1303
g_log.debug () << " Table data mismatch at column " << i << " \n " ;
1304
+ for (std::size_t j = 0 ; j < c1->size (); j++) {
1305
+ g_log.debug () << " \t " << j << " | " << c1->cell <double >(j) << " , " << c2->cell <double >(j) << " \n " ;
1306
+ }
1299
1307
recordMismatch (" Table data mismatch" );
1300
1308
if (!checkAllData) {
1301
1309
return ;
@@ -1356,12 +1364,15 @@ this error is within the limits requested.
1356
1364
@param x1 -- first value to check difference
1357
1365
@param x2 -- second value to check difference
1358
1366
@param atol -- the tolerance of the comparison. Must be nonnegative
1367
+ @param nanEqual -- whether two NaNs compare as equal
1359
1368
1360
1369
@returns true if absolute difference is within the tolerance; false otherwise
1361
1370
*/
1362
- bool CompareWorkspaces::withinAbsoluteTolerance (double const x1, double const x2, double const atol) {
1363
- // NOTE !(|x1-x2| > atol) is not the same as |x1-x2| <= atol
1364
- return !(std::abs (x1 - x2) > atol);
1371
+ bool CompareWorkspaces::withinAbsoluteTolerance (double const x1, double const x2, double const atol,
1372
+ bool const nanEqual) {
1373
+ if (nanEqual && std::isnan (x1) && std::isnan (x2))
1374
+ return true ;
1375
+ return Kernel::withinAbsoluteDifference (x1, x2, atol);
1365
1376
}
1366
1377
1367
1378
// ------------------------------------------------------------------------------------------------
@@ -1371,24 +1382,15 @@ this error is within the limits requested.
1371
1382
@param x1 -- first value to check difference
1372
1383
@param x2 -- second value to check difference
1373
1384
@param rtol -- the tolerance of the comparison. Must be nonnegative
1385
+ @param nanEqual -- whether two NaNs compare as equal
1374
1386
1375
1387
@returns true if relative difference is within the tolerance; false otherwise
1376
1388
@returns true if error or false if the relative value is within the limits requested
1377
1389
*/
1378
- bool CompareWorkspaces::withinRelativeTolerance (double const x1, double const x2, double const rtol) {
1379
- // calculate difference
1380
- double const num = std::abs (x1 - x2);
1381
- // return early if the values are equal
1382
- if (num == 0.0 )
1390
+ bool CompareWorkspaces::withinRelativeTolerance (double const x1, double const x2, double const rtol,
1391
+ bool const nanEqual) {
1392
+ if (nanEqual && std::isnan (x1) && std::isnan (x2))
1383
1393
return true ;
1384
- // create the average magnitude for comparison
1385
- double const den = 0.5 * (std::abs (x1) + std::abs (x2));
1386
- // return early, possibly avoids a multiplication
1387
- // NOTE if den<1, then divsion will only make num larger
1388
- // NOTE if den<1 but num<=rtol, we cannot conclude anything
1389
- if (den <= 1.0 && num > rtol)
1390
- return false ;
1391
- // NOTE !(num > rtol*den) is not the same as (num <= rtol*den)
1392
- return !(num > (rtol * den));
1394
+ return Kernel::withinRelativeDifference (x1, x2, rtol);
1393
1395
}
1394
1396
} // namespace Mantid::Algorithms
0 commit comments