-
Tom Perkins authored
Test that, if a run is aborted and restarted, "running" is set to false for times during the aborted run - as this data isn't in the file. re #17924
Tom Perkins authoredTest that, if a run is aborted and restarted, "running" is set to false for times during the aborted run - as this data isn't in the file. re #17924
Code owners
Assign users and groups as approvers for specific file changes. Learn more.
LogParserTest.h 32.80 KiB
#ifndef LOGPARSERTEST_H_
#define LOGPARSERTEST_H_
#include <cxxtest/TestSuite.h>
#include <fstream>
#include "MantidKernel/LogParser.h"
#include "MantidKernel/make_unique.h"
#include "MantidKernel/PropertyWithValue.h"
#include "MantidKernel/TimeSeriesProperty.h"
#include <boost/scoped_ptr.hpp>
#include <Poco/File.h>
using namespace Mantid::Kernel;
class LogParserTest : public CxxTest::TestSuite {
public:
static LogParserTest *createSuite() { return new LogParserTest(); }
static void destroySuite(LogParserTest *suite) { delete suite; }
class TmpFile {
Poco::File m_file;
public:
TmpFile(const std::string &fname) : m_file(fname) {}
~TmpFile() { remove(); }
const std::string &path() const { return m_file.path(); }
bool exists() const { return m_file.exists(); }
void remove() {
if (m_file.exists())
m_file.remove();
}
};
LogParserTest()
: log_num_good("TST000000_good.txt"), log_num_late("TST000000_late.txt"),
log_num_early("TST000000_early.txt"),
log_num_single("TST000000_single.txt"), log_str("TST000000_str.txt"),
icp_file("TST000000_icpevent.txt"),
log_str_repeat("TST000000_repeat.txt"),
log_num_repeat("TST000000_num_repeat.txt"),
log_str_continuations("TST000000_str_continue.txt") {}
void testGood() {
mkICP();
mkGood();
Property *icp_log =
LogParser::createLogProperty(icp_file.path(), "icpevent");
LogParser lp(icp_log);
Property *p1 = lp.createLogProperty(log_num_good.path(), "good");
TS_ASSERT(p1);
TimeSeriesProperty<double> *tp1 =
dynamic_cast<TimeSeriesProperty<double> *>(p1);
std::map<DateAndTime, double> vmap = tp1->valueAsMap();
std::map<DateAndTime, double>::iterator v = vmap.begin();
// time 1
TS_ASSERT_EQUALS(vmap.size(), 9);
TS_ASSERT_EQUALS(v->second, 1);
ti_data = v->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 12);
TS_ASSERT_EQUALS(ti->tm_min, 22);
v++;
v++;
v++;
v++;
// time 5
// TS_ASSERT(isNaN(v->second));
ti_data = v->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 12);
TS_ASSERT_EQUALS(ti->tm_min, 22);
// last time
std::map<DateAndTime, double>::reverse_iterator rv = vmap.rbegin();
TS_ASSERT_EQUALS(rv->second, 9);
ti_data = rv->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 14);
TS_ASSERT_EQUALS(ti->tm_min, 3);
TS_ASSERT_DELTA(timeMean(p1), 8.4904, 0.001);
TS_ASSERT_EQUALS(tp1->nthValue(0), 1);
TS_ASSERT_EQUALS(tp1->nthValue(1), 2);
TS_ASSERT_EQUALS(tp1->nthValue(2), 3);
TS_ASSERT_EQUALS(tp1->nthValue(3), 4);
TS_ASSERT_EQUALS(tp1->nthValue(4), 5);
TS_ASSERT_EQUALS(tp1->nthValue(5), 6);
TS_ASSERT_EQUALS(tp1->nthValue(6), 7);
TS_ASSERT_EQUALS(tp1->nthValue(7), 8);
TS_ASSERT_EQUALS(tp1->firstValue(), 1);
// TS_ASSERT_EQUALS(secondValue(p1),2);
TS_ASSERT_EQUALS(tp1->lastValue(), 9);
delete p1;
delete icp_log;
}
void testLate() {
mkICP();
mkLate();
Property *icp_log =
LogParser::createLogProperty(icp_file.path(), "icpevent");
LogParser lp(icp_log);
Property *p1 = lp.createLogProperty(log_num_late.path(), "late");
TS_ASSERT(p1);
TimeSeriesProperty<double> *tp1 =
dynamic_cast<TimeSeriesProperty<double> *>(p1);
std::map<DateAndTime, double> vmap = tp1->valueAsMap();
std::map<DateAndTime, double>::iterator v = vmap.begin();
// time 1
TS_ASSERT_EQUALS(vmap.size(), 8);
TS_ASSERT_EQUALS(v->second, 2);
ti_data = v->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 12);
TS_ASSERT_EQUALS(ti->tm_min, 22);
v++;
v++;
v++;
v++;
// time 5
// TS_ASSERT(isNaN(v->second));
ti_data = v->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 12);
TS_ASSERT_EQUALS(ti->tm_min, 22);
// last time
std::map<DateAndTime, double>::reverse_iterator rv = vmap.rbegin();
TS_ASSERT_EQUALS(rv->second, 9);
ti_data = rv->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 14);
TS_ASSERT_EQUALS(ti->tm_min, 3);
TS_ASSERT_DELTA(timeMean(p1), 8.4941, 0.001);
delete p1;
delete icp_log;
}
void testEarly() {
mkICP();
mkEarly();
Property *icp_log =
LogParser::createLogProperty(icp_file.path(), "icpevent");
LogParser lp(icp_log);
Property *p1 = lp.createLogProperty(log_num_early.path(), "early");
TS_ASSERT(p1);
TimeSeriesProperty<double> *tp1 =
dynamic_cast<TimeSeriesProperty<double> *>(p1);
std::map<DateAndTime, double> vmap = tp1->valueAsMap();
std::map<DateAndTime, double>::iterator v = vmap.begin();
// time 1
TS_ASSERT_EQUALS(vmap.size(), 8);
TS_ASSERT_EQUALS(v->second, 1);
ti_data = v->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 12);
TS_ASSERT_EQUALS(ti->tm_min, 22);
v++;
v++;
v++;
v++;
// time 5
// TS_ASSERT(isNaN(v->second));
ti_data = v->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 12);
TS_ASSERT_EQUALS(ti->tm_min, 22);
// last time
std::map<DateAndTime, double>::reverse_iterator rv = vmap.rbegin();
TS_ASSERT_EQUALS(rv->second, 8);
ti_data = rv->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 12);
TS_ASSERT_EQUALS(ti->tm_min, 23);
TS_ASSERT_DELTA(timeMean(p1), 4.9090, 0.001);
delete p1;
delete icp_log;
}
void testSingle() {
mkICP();
mkSingle();
Property *icp_log =
LogParser::createLogProperty(icp_file.path(), "icpevent");
LogParser lp(icp_log);
Property *p1 = lp.createLogProperty(log_num_single.path(), "single");
TS_ASSERT(p1);
TimeSeriesProperty<double> *tp1 =
dynamic_cast<TimeSeriesProperty<double> *>(p1);
std::map<DateAndTime, double> vmap = tp1->valueAsMap();
std::map<DateAndTime, double>::iterator v = vmap.begin();
// time 1
TS_ASSERT_EQUALS(vmap.size(), 1);
TS_ASSERT_EQUALS(v->second, 4);
ti_data = v->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 12);
TS_ASSERT_EQUALS(ti->tm_min, 22);
// Can't get a valid mean with a single time and no intervals in it.
// TS_ASSERT_DELTA(timeMean(p1),4., 0.001);
delete p1;
delete icp_log;
}
void testStr() {
mkICP();
mkStr();
Property *icp_log =
LogParser::createLogProperty(icp_file.path(), "icpevent");
LogParser lp(icp_log);
Property *p1 = lp.createLogProperty(log_str.path(), "str");
TS_ASSERT(p1);
TimeSeriesProperty<std::string> *tp1 =
dynamic_cast<TimeSeriesProperty<std::string> *>(p1);
std::map<DateAndTime, std::string> vmap = tp1->valueAsMap();
std::map<DateAndTime, std::string>::iterator v = vmap.begin();
// time 1
TS_ASSERT_EQUALS(vmap.size(), 9);
TS_ASSERT_EQUALS(v->second, " line 1");
ti_data = v->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 12);
TS_ASSERT_EQUALS(ti->tm_min, 22);
v++;
v++;
v++;
// time 4
TS_ASSERT_EQUALS(v->second, " line 4");
ti_data = v->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 12);
TS_ASSERT_EQUALS(ti->tm_min, 22);
// last time
std::map<DateAndTime, std::string>::reverse_iterator rv = vmap.rbegin();
TS_ASSERT_EQUALS(rv->second, " line 9");
ti_data = rv->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 14);
TS_ASSERT_EQUALS(ti->tm_min, 3);
// assert_throws(timeMean(p1));
delete p1;
delete icp_log;
}
// Test a variant of the log file containing CHANGE_PERIOD flags
void testConstructionFromFileUsingICPVariant_CHANGE_PERIOD() {
mkICPVariant();
Property *icp_log =
LogParser::createLogProperty(icp_file.path(), "icpevent");
LogParser lp(icp_log);
const Property *prop = lp.createAllPeriodsLog();
const auto *timeseriesprop =
dynamic_cast<const TimeSeriesProperty<int> *>(prop);
TS_ASSERT(timeseriesprop);
// Check the size
TS_ASSERT_EQUALS(4, timeseriesprop->size());
// Check the exact time stamps
TS_ASSERT_EQUALS(DateAndTime("2000-09-05T12:22:55").toSimpleString(),
timeseriesprop->nthTime(0).toSimpleString());
TS_ASSERT_EQUALS(DateAndTime("2000-09-05T12:23:08").toSimpleString(),
timeseriesprop->nthTime(1).toSimpleString());
TS_ASSERT_EQUALS(DateAndTime("2000-09-05T12:23:22").toSimpleString(),
timeseriesprop->nthTime(2).toSimpleString());
TS_ASSERT_EQUALS(DateAndTime("2000-09-05T12:23:37").toSimpleString(),
timeseriesprop->nthTime(3).toSimpleString());
delete prop;
delete icp_log;
}
void testConstructionFromPropertyUsingICPVariant_CHANGE_PERIOD() {
auto *log = new TimeSeriesProperty<std::string>("ICPLog");
// Notice we are using "CHANGE_PERIOD"
TS_ASSERT_THROWS_NOTHING(
log->addValue("2007-11-30T16:15:00", "CHANGE_PERIOD 1"));
TS_ASSERT_THROWS_NOTHING(
log->addValue("2007-11-30T16:16:00", "CHANGE_PERIOD 2"));
TS_ASSERT_THROWS_NOTHING(
log->addValue("2007-11-30T16:17:00", "CHANGE_PERIOD 3"));
TS_ASSERT_THROWS_NOTHING(
log->addValue("2007-11-30T16:18:00", "CHANGE_PERIOD 2"));
LogParser logparser(log);
const Property *prop = logparser.createAllPeriodsLog();
const auto *timeseriesprop =
dynamic_cast<const TimeSeriesProperty<int> *>(prop);
TS_ASSERT(timeseriesprop);
// Check the size
TS_ASSERT_EQUALS(4, timeseriesprop->size());
// Check the exact time stamps
TS_ASSERT_EQUALS(DateAndTime("2007-11-30T16:15:00").toSimpleString(),
timeseriesprop->nthTime(0).toSimpleString());
TS_ASSERT_EQUALS(DateAndTime("2007-11-30T16:16:00").toSimpleString(),
timeseriesprop->nthTime(1).toSimpleString());
TS_ASSERT_EQUALS(DateAndTime("2007-11-30T16:17:00").toSimpleString(),
timeseriesprop->nthTime(2).toSimpleString());
TS_ASSERT_EQUALS(DateAndTime("2007-11-30T16:18:00").toSimpleString(),
timeseriesprop->nthTime(3).toSimpleString());
delete log;
delete prop;
}
void testConstructionFromPropertyUsingICPVariant_CHANGE_SPACE_PERIOD() {
auto *log = new TimeSeriesProperty<std::string>("ICPLog");
// Notice we are using "CHANGE PERIOD"
TS_ASSERT_THROWS_NOTHING(
log->addValue("2007-11-30T16:15:00", "CHANGE PERIOD 1"));
TS_ASSERT_THROWS_NOTHING(
log->addValue("2007-11-30T16:16:00", "CHANGE PERIOD 2"));
TS_ASSERT_THROWS_NOTHING(
log->addValue("2007-11-30T16:17:00", "CHANGE PERIOD 3"));
TS_ASSERT_THROWS_NOTHING(
log->addValue("2007-11-30T16:18:00", "CHANGE PERIOD 2"));
LogParser logparser(log);
const Property *prop = logparser.createAllPeriodsLog();
const auto *timeseriesprop =
dynamic_cast<const TimeSeriesProperty<int> *>(prop);
TS_ASSERT(timeseriesprop);
// Check the size
TS_ASSERT_EQUALS(4, timeseriesprop->size());
// Check the exact time stamps
TS_ASSERT_EQUALS(DateAndTime("2007-11-30T16:15:00").toSimpleString(),
timeseriesprop->nthTime(0).toSimpleString());
TS_ASSERT_EQUALS(DateAndTime("2007-11-30T16:16:00").toSimpleString(),
timeseriesprop->nthTime(1).toSimpleString());
TS_ASSERT_EQUALS(DateAndTime("2007-11-30T16:17:00").toSimpleString(),
timeseriesprop->nthTime(2).toSimpleString());
TS_ASSERT_EQUALS(DateAndTime("2007-11-30T16:18:00").toSimpleString(),
timeseriesprop->nthTime(3).toSimpleString());
delete log;
delete prop;
}
// Check that periods that don't have a full "CHANGE PERIOD" flag are not
// added.
void testWontAddPeriodWithoutPERIODpartOfCHANGE_SPACE_PERIOD() {
auto *log = new TimeSeriesProperty<std::string>("ICPLog");
// Notice we are using "CHANGE PERIOD"
TS_ASSERT_THROWS_NOTHING(
log->addValue("2007-11-30T16:15:00", "CHANGE PERIOD 1"));
TS_ASSERT_THROWS_NOTHING(
log->addValue("2007-11-30T16:16:00", "CHANGE PERIOD 2"));
TS_ASSERT_THROWS_NOTHING(
log->addValue("2007-11-30T16:17:00", "CHANGE PERIOD 3"));
TS_ASSERT_THROWS_NOTHING(log->addValue(
"2007-11-30T16:18:00",
"CHANGE 2")); // This is a duff entry. Shouldn't get added.
LogParser logparser(log);
const Property *prop = logparser.createAllPeriodsLog();
const auto *timeseriesprop =
dynamic_cast<const TimeSeriesProperty<int> *>(prop);
TS_ASSERT(timeseriesprop);
// Check the size
TS_ASSERT_EQUALS(3, timeseriesprop->size());
// Check the exact time stamps
TS_ASSERT_EQUALS(DateAndTime("2007-11-30T16:15:00").toSimpleString(),
timeseriesprop->nthTime(0).toSimpleString());
TS_ASSERT_EQUALS(DateAndTime("2007-11-30T16:16:00").toSimpleString(),
timeseriesprop->nthTime(1).toSimpleString());
TS_ASSERT_EQUALS(DateAndTime("2007-11-30T16:17:00").toSimpleString(),
timeseriesprop->nthTime(2).toSimpleString());
delete log;
delete prop;
}
void testCreatesCurrentPeriodLog() {
// Check it with a few expected period numbers.
doTestCurrentPeriodLog(1);
doTestCurrentPeriodLog(2);
doTestCurrentPeriodLog(3);
}
void testNoICPevent() {
if (icp_file.exists())
icp_file.remove();
mkGood();
Property *icp_log =
LogParser::createLogProperty(icp_file.path(), "icpevent");
LogParser lp(icp_log);
Property *p1 = lp.createLogProperty(log_num_good.path(), "good");
TS_ASSERT(p1);
TimeSeriesProperty<double> *tp1 =
dynamic_cast<TimeSeriesProperty<double> *>(p1);
std::map<DateAndTime, double> vmap = tp1->valueAsMap();
std::map<DateAndTime, double>::iterator v = vmap.begin();
// time 1
TS_ASSERT_EQUALS(vmap.size(), 9);
TS_ASSERT_EQUALS(v->second, 1);
ti_data = v->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 12);
TS_ASSERT_EQUALS(ti->tm_min, 22);
v++;
v++;
v++;
v++;
// time 5
// TS_ASSERT(!isNaN(v->second));
// last time
std::map<DateAndTime, double>::reverse_iterator rv = vmap.rbegin();
TS_ASSERT_EQUALS(rv->second, 9);
ti_data = rv->first.to_tm();
ti = &ti_data;
TS_ASSERT_EQUALS(ti->tm_hour, 14);
TS_ASSERT_EQUALS(ti->tm_min, 3);
TS_ASSERT_DELTA(timeMean(p1), 8.4904, 0.001);
delete p1;
}
//----------------------------------------------------------------------------
void test_timeMean() {
TimeSeriesProperty<double> *log =
new TimeSeriesProperty<double>("MydoubleLog");
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:00", 1));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:10", 2));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:20", 3));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:30", 4));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:40", 5));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:50", 6));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:18:00", 7));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:18:10", 8));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:18:20", 9));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:18:30", 10));
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:18:40", 11));
TS_ASSERT_EQUALS(log->realSize(), 11);
TS_ASSERT_DELTA(timeMean(log), 6.0, 1e-3);
delete log;
}
void test_timeMean_one_Value() {
TimeSeriesProperty<double> *log =
new TimeSeriesProperty<double>("MydoubleLog");
TS_ASSERT_THROWS_NOTHING(log->addValue("2007-11-30T16:17:00", 56));
TS_ASSERT_EQUALS(log->realSize(), 1);
TS_ASSERT_DELTA(timeMean(log), 56.0, 1e-3);
delete log;
}
/// Tests to see if we can cope with duplicate log values that have the same
/// time.
void test_timeMean_duplicate_values_with_same_timestamp() {
TimeSeriesProperty<double> *log =
new TimeSeriesProperty<double>("MydoubleLog");
// Add the same value twice
TS_ASSERT_THROWS_NOTHING(log->addValue("2012-07-19T20:00:00", 666));
TS_ASSERT_THROWS_NOTHING(log->addValue("2012-07-19T20:00:00", 666));
TS_ASSERT_EQUALS(log->realSize(), 2);
TS_ASSERT_DELTA(timeMean(log), 666, 1e-3);
delete log;
}
void test_isICPEventLogNewStyle_works() {
TimeSeriesProperty<std::string> *oldlog =
new TimeSeriesProperty<std::string>("MyOldICPevent");
TS_ASSERT_THROWS_NOTHING(oldlog->addValue("2012-07-19T20:00:00", "START"));
TS_ASSERT_THROWS_NOTHING(oldlog->addValue("2012-07-19T20:00:01", "BEGIN"));
TS_ASSERT_THROWS_NOTHING(oldlog->addValue("2012-07-19T20:00:02", "PAUSE"));
auto logm = oldlog->valueAsMultiMap();
TS_ASSERT(!LogParser::isICPEventLogNewStyle(logm));
delete oldlog;
TimeSeriesProperty<std::string> *newlog =
new TimeSeriesProperty<std::string>("MyNewICPevent");
TS_ASSERT_THROWS_NOTHING(newlog->addValue("2012-07-19T20:00:00", "START"));
TS_ASSERT_THROWS_NOTHING(
newlog->addValue("2012-07-19T20:00:01", "START_COLLECTION PERIOD 1"));
TS_ASSERT_THROWS_NOTHING(newlog->addValue("2012-07-19T20:00:02", "PAUSE"));
logm = newlog->valueAsMultiMap();
TS_ASSERT(LogParser::isICPEventLogNewStyle(logm));
delete newlog;
newlog = new TimeSeriesProperty<std::string>("MyNewICPevent1");
TS_ASSERT_THROWS_NOTHING(newlog->addValue("2012-07-19T20:00:00", "START"));
TS_ASSERT_THROWS_NOTHING(
newlog->addValue("2012-07-19T20:00:01", "STOP_COLLECTION PERIOD 1"));
TS_ASSERT_THROWS_NOTHING(newlog->addValue("2012-07-19T20:00:02", "PAUSE"));
logm = newlog->valueAsMultiMap();
TS_ASSERT(LogParser::isICPEventLogNewStyle(logm));
delete newlog;
}
void test_new_style_command_parsing() {
TimeSeriesProperty<std::string> *log =
new TimeSeriesProperty<std::string>("MyICPevent");
log->addValue("2013-10-16T19:04:47", "CHANGE_PERIOD 1");
log->addValue("2013-10-16T19:04:48", "RESUME");
log->addValue("2013-10-16T19:04:48",
"START_COLLECTION PERIOD 1 GF 60015 RF 75039 GUAH 69.875610");
log->addValue(
"2013-10-16T19:06:53",
"STOP_COLLECTION PERIOD 1 GF 65024 RF 81303 GUAH 75.712013 DUR 125");
log->addValue("2013-10-16T19:06:53", "PAUSE");
log->addValue("2013-10-16T19:06:53", "CHANGE_PERIOD 2");
log->addValue("2013-10-16T19:06:53", "RESUME");
log->addValue("2013-10-16T19:06:53",
"START_COLLECTION PERIOD 2 GF 65024 RF 81303 GUAH 75.712013");
log->addValue(
"2013-10-16T19:08:58",
"STOP_COLLECTION PERIOD 2 GF 70033 RF 87567 GUAH 81.547050 DUR 125");
log->addValue("2013-10-16T19:08:58", "PAUSE");
log->addValue("2013-10-16T19:08:58", "CHANGE_PERIOD 1");
log->addValue("2013-10-16T19:08:59", "RESUME");
log->addValue("2013-10-16T19:08:59",
"START_COLLECTION PERIOD 1 GF 70033 RF 87567 GUAH 81.547050");
log->addValue(
"2013-10-16T19:11:03",
"STOP_COLLECTION PERIOD 1 GF 75005 RF 93784 GUAH 87.339035 DUR 124");
log->addValue("2013-10-16T19:11:03", "PAUSE");
log->addValue("2013-10-16T19:11:03", "CHANGE_PERIOD 2");
log->addValue("2013-10-16T19:11:04", "RESUME");
log->addValue("2013-10-16T19:11:04",
"START_COLLECTION PERIOD 2 GF 75005 RF 93784 GUAH 87.339035");
log->addValue(
"2013-10-16T19:13:09",
"STOP_COLLECTION PERIOD 2 GF 80016 RF 100049 GUAH 93.174751 DUR 125");
log->addValue("2013-10-16T19:13:09", "PAUSE");
log->addValue("2013-10-16T19:13:09", "CHANGE_PERIOD 1");
log->addValue("2013-10-16T19:13:09", "RESUME");
std::vector<std::pair<std::string, int>> checkPeriod(5);
checkPeriod[0] = std::make_pair("2013-10-16T19:04:47", 1);
checkPeriod[1] = std::make_pair("2013-10-16T19:06:53", 2);
checkPeriod[2] = std::make_pair("2013-10-16T19:08:58", 1);
checkPeriod[3] = std::make_pair("2013-10-16T19:11:03", 2);
checkPeriod[4] = std::make_pair("2013-10-16T19:13:09", 1);
std::vector<std::pair<std::string, bool>> checkRunning(8);
checkRunning[0] = std::make_pair("2013-10-16T19:04:48", true);
checkRunning[1] = std::make_pair("2013-10-16T19:06:53", false);
checkRunning[2] = std::make_pair("2013-10-16T19:06:53", true);
checkRunning[3] = std::make_pair("2013-10-16T19:08:58", false);
checkRunning[4] = std::make_pair("2013-10-16T19:08:59", true);
checkRunning[5] = std::make_pair("2013-10-16T19:11:03", false);
checkRunning[6] = std::make_pair("2013-10-16T19:11:04", true);
checkRunning[7] = std::make_pair("2013-10-16T19:13:09", false);
LogParser logparser(log);
const Property *prop = logparser.createAllPeriodsLog();
const auto *allPeriodsProp =
dynamic_cast<const TimeSeriesProperty<int> *>(prop);
TS_ASSERT(allPeriodsProp);
TS_ASSERT_EQUALS(5, allPeriodsProp->size());
auto logm = allPeriodsProp->valueAsMultiMap();
size_t i = 0;
for (auto it = logm.begin(); it != logm.end(); ++it) {
TS_ASSERT_EQUALS(it->first.toISO8601String(), checkPeriod[i].first);
TS_ASSERT_EQUALS(it->second, checkPeriod[i].second);
++i;
}
delete prop;
prop = logparser.createRunningLog();
const auto *runningProp =
dynamic_cast<const TimeSeriesProperty<bool> *>(prop);
TS_ASSERT(runningProp);
TS_ASSERT_EQUALS(8, runningProp->size());
auto logm1 = runningProp->valueAsMultiMap();
i = 0;
for (auto it = logm1.begin(); it != logm1.end(); ++it) {
TS_ASSERT_EQUALS(it->first.toISO8601String(), checkRunning[i].first);
TS_ASSERT_EQUALS(it->second, checkRunning[i].second);
++i;
}
delete prop;
delete log;
}
void test_str_repeat() {
mkStrRepeat();
Property *prop = LogParser::createLogProperty(log_str_repeat.path(), "log");
const auto *log =
dynamic_cast<const TimeSeriesProperty<std::string> *>(prop);
TS_ASSERT(log);
auto logm = log->valueAsMultiMap();
auto it = logm.begin();
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:22:34");
TS_ASSERT_EQUALS(it->second, " First line");
++it;
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:22:34");
TS_ASSERT_EQUALS(it->second, " Second line");
++it;
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:23:33");
TS_ASSERT_EQUALS(it->second, " First line");
++it;
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:23:33");
TS_ASSERT_EQUALS(it->second, " Second line");
++it;
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:23:33");
TS_ASSERT_EQUALS(it->second, " Third line");
++it;
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:23:33");
TS_ASSERT_EQUALS(it->second, " Fourth line");
++it;
delete prop;
}
void test_num_repeat() {
mkNumRepeat();
Property *prop = LogParser::createLogProperty(log_str_repeat.path(), "log");
const auto *log = dynamic_cast<const TimeSeriesProperty<double> *>(prop);
TS_ASSERT(log);
auto logm = log->valueAsMultiMap();
auto it = logm.begin();
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:22:34");
TS_ASSERT_EQUALS(it->second, 1);
++it;
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:22:34");
TS_ASSERT_EQUALS(it->second, 2);
++it;
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:23:33");
TS_ASSERT_EQUALS(it->second, 3);
++it;
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:23:33");
TS_ASSERT_EQUALS(it->second, 4);
++it;
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:23:33");
TS_ASSERT_EQUALS(it->second, 5);
++it;
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:23:33");
TS_ASSERT_EQUALS(it->second, 6);
++it;
delete prop;
}
void test_str_continuation() {
mkStrContinuations();
Property *prop =
LogParser::createLogProperty(log_str_continuations.path(), "log");
const auto *log =
dynamic_cast<const TimeSeriesProperty<std::string> *>(prop);
TS_ASSERT(log);
auto logm = log->valueAsMultiMap();
auto it = logm.begin();
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:22:31");
TS_ASSERT_EQUALS(it->second, " First line Second line");
++it;
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:22:34");
TS_ASSERT_EQUALS(it->second, " First line");
++it;
TS_ASSERT_EQUALS(it->first.toISO8601String(), "2000-09-05T12:22:34");
TS_ASSERT_EQUALS(it->second, " Second line Third line");
++it;
delete prop;
}
/// If a run is aborted and then restarted, the "running" log should be set to
/// false at all times during the aborted run.
void test_abort_runningLogAlwaysFalseBeforeRestart() {
auto log = Mantid::Kernel::make_unique<TimeSeriesProperty<std::string>>(
"MyICPevent");
// (This is a cut-down version of EMU66122)
const DateAndTime timeZero{"2016-10-01T10:01:44"};
const std::vector<DateAndTime> times{
timeZero, timeZero + 3.0, timeZero + 3.0, timeZero + 3.0,
timeZero + 51.0, timeZero + 51.0, timeZero + 57.0, timeZero + 60.0,
timeZero + 60.0, timeZero + 60.0, timeZero + 111.0, timeZero + 111.0};
const std::vector<std::string> values{
"CHANGE_PERIOD 1",
"CHANGE_PERIOD 1",
"START_COLLECTION PERIOD 1 GF 0 RF 0 GUAH 0.000000",
"BEGIN",
"STOP_COLLECTION PERIOD 1 GF 1931 RF 1933 GUAH 0.000000 DUR 48",
"ABORT",
"CHANGE_PERIOD 1",
"CHANGE_PERIOD 1",
"START_COLLECTION PERIOD 1 GF 0 RF 0 GUAH 0.000000",
"BEGIN",
"STOP_COLLECTION PERIOD 1 GF 2062 RF 2064 GUAH 0.000000 DUR 51",
"END"};
log->addValues(times, values);
const std::multimap<DateAndTime, bool> expectedRunning{
{timeZero + 3.0, false}, // start - run later aborted
{timeZero + 51.0, false}, // stop
{timeZero + 51.0, false}, // abort
{timeZero + 60.0, true}, // start
{timeZero + 111.0, false}}; // stop
const LogParser logparser(log.get());
const auto prop = std::unique_ptr<Property>(logparser.createRunningLog());
const auto *runningProp =
dynamic_cast<const TimeSeriesProperty<bool> *>(prop.get());
TS_ASSERT(runningProp);
TS_ASSERT_EQUALS(expectedRunning.size(), runningProp->size());
const auto &runningMap = runningProp->valueAsMultiMap();
TS_ASSERT_EQUALS(expectedRunning, runningMap);
}
private:
/// Helper method to run common test code for checking period logs.
void doTestCurrentPeriodLog(const int &expected_period) {
auto *log = new TimeSeriesProperty<std::string>("ICPLog");
LogParser logparser(log);
Property *prop = logparser.createCurrentPeriodLog(expected_period);
PropertyWithValue<int> *prop_with_value =
dynamic_cast<PropertyWithValue<int> *>(prop);
int value;
TS_ASSERT(prop_with_value != NULL);
Mantid::Kernel::toValue<int>(prop_with_value->value(), value);
TS_ASSERT_EQUALS(expected_period, value);
delete prop;
delete log;
}
void mkICP() {
std::ofstream f(icp_file.path().c_str());
int dt = 0;
f << "2000-09-05T12:22:28 START_SE_WAIT\n";
f << "2000-09-05T12:22:33 BEGIN\n";
dt += 8;
f << "2000-09-05T12:22:41 PAUSE\n";
dt += 4;
f << "2000-09-05T12:22:55 CHANGE PERIOD 2\n";
dt += 3;
f << "2000-09-05T12:22:58 RESUME\n";
dt += 6;
f << "2000-09-05T12:23:04 PAUSE\n";
dt += 4;
f << "2000-09-05T12:23:08 CHANGE PERIOD 1\n";
dt += 2;
f << "2000-09-05T12:23:10 RESUME\n";
dt += 8;
f << "2000-09-05T12:23:18 START_SE_WAIT\n";
dt += 4;
f << "2000-09-05T12:23:22 CHANGE PERIOD 2\n";
dt += 5;
f << "2000-09-05T12:23:27 RESUME\n";
dt += 7;
f << "2000-09-05T12:23:34 ABORT\n";
dt += 3;
f << "2000-09-05T12:23:37 CHANGE PERIOD 1\n";
dt += 5;
f << "2000-09-05T12:23:42 END_SE_WAIT\n";
f << "2000-09-05T14:03:54 END\n";
f.close();
}
void mkICPVariant() {
std::ofstream f(icp_file.path().c_str());
int dt = 0;
f << "2000-09-05T12:22:28 START_SE_WAIT\n";
f << "2000-09-05T12:22:33 BEGIN\n";
dt += 8;
f << "2000-09-05T12:22:41 PAUSE\n";
dt += 4;
f << "2000-09-05T12:22:55 CHANGE_PERIOD 2\n";
dt += 3;
f << "2000-09-05T12:22:58 RESUME\n";
dt += 6;
f << "2000-09-05T12:23:04 PAUSE\n";
dt += 4;
f << "2000-09-05T12:23:08 CHANGE_PERIOD 1\n";
dt += 2;
f << "2000-09-05T12:23:10 RESUME\n";
dt += 8;
f << "2000-09-05T12:23:18 START_SE_WAIT\n";
dt += 4;
f << "2000-09-05T12:23:22 CHANGE_PERIOD 2\n";
dt += 5;
f << "2000-09-05T12:23:27 RESUME\n";
dt += 7;
f << "2000-09-05T12:23:34 ABORT\n";
dt += 3;
f << "2000-09-05T12:23:37 CHANGE_PERIOD 1\n";
dt += 5;
f << "2000-09-05T12:23:42 END_SE_WAIT\n";
f << "2000-09-05T14:03:54 END\n";
f.close();
}
void mkGood() {
std::ofstream f(log_num_good.path().c_str());
int dt = 4;
f << "2000-09-05T12:22:31 " << 1 << '\n';
f << "2000-09-05T12:22:37 " << 2 << '\n';
dt += 1;
f << "2000-09-05T12:22:38 " << 3 << '\n';
dt += 1;
f << "2000-09-05T12:22:39 " << 4 << '\n';
dt += 3;
f << "2000-09-05T12:22:42 " << 5 << '\n';
dt += 5;
f << "2000-09-05T12:22:47 " << 6 << '\n';
dt += 9;
f << "2000-09-05T12:22:56 " << 7 << '\n';
dt += 4;
f << "2000-09-05T12:23:00 " << 8 << '\n';
f << "2000-09-05T14:03:56 " << 9 << '\n';
f.close();
}
void mkLate() {
std::ofstream f(log_num_late.path().c_str());
int dt = 4;
f << "2000-09-05T12:22:37 " << 2 << '\n';
dt += 1;
f << "2000-09-05T12:22:38 " << 3 << '\n';
dt += 1;
f << "2000-09-05T12:22:39 " << 4 << '\n';
dt += 3;
f << "2000-09-05T12:22:42 " << 5 << '\n';
dt += 5;
f << "2000-09-05T12:22:47 " << 6 << '\n';
dt += 9;
f << "2000-09-05T12:22:56 " << 7 << '\n';
dt += 4;
f << "2000-09-05T12:23:00 " << 8 << '\n';
f << "2000-09-05T14:03:56 " << 9 << '\n';
f.close();
}
void mkEarly() {
std::ofstream f(log_num_early.path().c_str());
int dt = 4;
f << "2000-09-05T12:22:31 " << 1 << '\n';
f << "2000-09-05T12:22:37 " << 2 << '\n';
dt += 1;
f << "2000-09-05T12:22:38 " << 3 << '\n';
dt += 1;
f << "2000-09-05T12:22:39 " << 4 << '\n';
dt += 3;
f << "2000-09-05T12:22:42 " << 5 << '\n';
dt += 5;
f << "2000-09-05T12:22:47 " << 6 << '\n';
dt += 9;
f << "2000-09-05T12:22:56 " << 7 << '\n';
dt += 4;
f << "2000-09-05T12:23:00 " << 8 << '\n';
f.close();
}
void mkSingle() {
std::ofstream f(log_num_single.path().c_str());
f << "2000-09-05T12:22:51 " << 4 << '\n';
f.close();
}
void mkStr() {
std::ofstream f(log_str.path().c_str());
int dt = 4;
f << "2000-09-05T12:22:31 line " << 1 << '\n';
f << "2000-09-05T12:22:37 line " << 2 << '\n';
dt += 1;
f << "2000-09-05T12:22:38 line " << 3 << '\n';
dt += 1;
f << "2000-09-05T12:22:39 line " << 4 << '\n';
dt += 3;
f << "2000-09-05T12:22:42 line " << 5 << '\n';
dt += 5;
f << "2000-09-05T12:22:47 line " << 6 << '\n';
dt += 9;
f << "2000-09-05T12:22:56 line " << 7 << '\n';
dt += 4;
f << "2000-09-05T12:23:00 line " << 8 << '\n';
f << "2000-09-05T14:03:56 line " << 9 << '\n';
f.close();
}
void mkStrContinuations() {
std::ofstream f(log_str_continuations.path().c_str());
f << "2000-09-05T12:22:31 First line\n";
f << "Second line\n";
f << "2000-09-05T12:22:34 First line\n";
f << "2000-09-05T12:22:34 Second line\n";
f << "Third line\n";
f.close();
}
void mkStrRepeat() {
std::ofstream f(log_str_repeat.path().c_str());
f << "2000-09-05T12:22:34 First line\n";
f << "2000-09-05T12:22:34 Second line\n";
f << "2000-09-05T12:23:33 First line\n";
f << "2000-09-05T12:23:33 Second line\n";
f << "2000-09-05T12:23:33 Third line\n";
f << "2000-09-05T12:23:33 Fourth line\n";
f.close();
}
void mkNumRepeat() {
std::ofstream f(log_str_repeat.path().c_str());
f << "2000-09-05T12:22:34 1\n";
f << "2000-09-05T12:22:34 2\n";
f << "2000-09-05T12:23:33 3\n";
f << "2000-09-05T12:23:33 4\n";
f << "2000-09-05T12:23:33 5\n";
f << "2000-09-05T12:23:33 6\n";
f.close();
}
TmpFile
log_num_good; // run time interval is within first - last times of the log
TmpFile log_num_late; // first time is later than run start
TmpFile log_num_early; // last time is earlier than run ends
TmpFile log_num_single; // single value
TmpFile log_str; // file of strings
TmpFile icp_file; // icpevent file
TmpFile log_str_repeat; // string log with repeating lines
TmpFile log_num_repeat; // num log with repeating lines
TmpFile log_str_continuations; // string log with continuation lines
tm ti_data;
tm *ti;
};
#endif /*LOGPARSERTEST_H_*/