26using Types::Core::DateAndTime;
30Logger
g_log(
"LogParser");
39 std::ifstream file(logFName.c_str());
41 g_log.
warning() <<
"Cannot open log file " << logFName <<
"\n";
46 std::multimap<std::string, std::string> change_times;
49 std::string str, old_data;
50 bool isNumeric(
false);
51 std::string stime, sdata;
58 if (str.empty() || str[0] ==
'#') {
65 if (change_times.empty() || isNumeric) {
66 std::string mess = std::string(
"Cannot parse log file ").append(logFName).append(
". Line:").append(str);
68 throw std::logic_error(mess);
70 auto range = change_times.equal_range(stime);
71 if (range.first != range.second) {
72 auto last = range.first;
73 for (
auto it = last; it != range.second; ++it) {
76 last->second += std::string(
" ") + str;
77 old_data = last->second;
81 stime = str.substr(0, 19);
82 sdata = str.substr(19);
84 if (sdata == old_data)
88 std::istringstream istr(sdata);
91 isNumeric = !istr.fail();
94 change_times.emplace(stime, sdata);
97 if (change_times.empty())
102 auto it = change_times.begin();
103 for (; it != change_times.end(); ++it) {
104 std::istringstream istr(it->second);
107 logv->addValue(it->first,
d);
112 auto it = change_times.begin();
113 for (; it != change_times.end(); ++it) {
114 logv->addValue(it->first, it->second);
161 bool shouldAddPeriod =
false;
163 if (scom ==
"CHANGE") {
166 if (ip > 0 && s ==
"PERIOD") {
167 shouldAddPeriod =
true;
171 else if (scom ==
"CHANGE_PERIOD") {
174 shouldAddPeriod =
true;
178 if (shouldAddPeriod) {
196 if (!icpLog || icpLog->size() == 0) {
197 periods->
addValue(Types::Core::DateAndTime(), 1);
198 status->
addValue(Types::Core::DateAndTime(),
true);
199 g_log.
information() <<
"Cannot process ICPevent log. Period 1 assumed for all data.\n";
203 std::multimap<Types::Core::DateAndTime, std::string> logm = icpLog->valueAsMultiMap();
208 auto it = logm.begin();
210 for (; it != logm.end(); ++it) {
212 std::istringstream idata(it->second);
224 const std::vector<bool> values(times.size(),
false);
231 if (periods->
size() == 0)
232 periods->
addValue(icpLog->firstTime(), 1);
233 if (status->
size() == 0)
234 status->
addValue(icpLog->firstTime(),
true);
245 throw std::logic_error(
"Failed to cast periods to TimeSeriesProperty");
248 std::map<Types::Core::DateAndTime, int> pMap = periods->valueAsMap();
249 auto it = pMap.begin();
250 if (it->second != period)
252 for (; it != pMap.end(); ++it)
253 p->
addValue(it->first, (it->second == period));
259 std::ostringstream ostr;
261 return "period " + ostr.str();
271 return currentPeriodProperty;
282struct hasNewStyleCommands {
283 bool operator()(
const std::pair<Mantid::Types::Core::DateAndTime, std::string> &p) {
296 hasNewStyleCommands checker;
298 return std::find_if(logm.begin(), logm.end(), checker) != logm.end();
315 throw std::runtime_error(
"Property of a wrong type. Cannot be cast to a "
316 "TimeSeriesProperty<double>.");
320 if (dp->size() == 1) {
321 return dp->nthValue(1);
324 Types::Core::time_duration total(0, 0, 0, 0);
325 size_t dp_size = dp->size();
326 for (
size_t i = 0; i < dp_size; i++) {
328 Types::Core::time_duration dt = t.
length();
330 res += dp->nthValue(
static_cast<int>(i)) * Types::Core::DateAndTime::secondsFromDuration(dt);
333 double total_seconds = Types::Core::DateAndTime::secondsFromDuration(total);
336 if (total_seconds == 0.0)
337 res = dp->nthValue(1);
339 if (total_seconds > 0)
340 res /= total_seconds;
constexpr const char * STOP_COLLECTION
constexpr const char * START_COLLECTION
static Kernel::Property * createLogProperty(const std::string &logFName, const std::string &name)
Creates a TimeSeriesProperty of either double or string type depending on the log data Returns a poin...
std::shared_ptr< Kernel::TimeSeriesProperty< bool > > m_status
TimeSeriesProperty<bool> containing running status. Created by LogParser.
LogParser(const Kernel::Property *log)
Create given the icpevent log property.
static const std::string statusLogName()
Returns the name of the log created that defines the status during a run.
Kernel::Property * createAllPeriodsLog() const
Creates a TimeSeriesProperty<int> with all data periods.
static bool isICPEventLogNewStyle(const std::multimap< Types::Core::DateAndTime, std::string > &logm)
Check if the icp log commands are in the new style.
std::map< std::string, commands > CommandMap
Typedef for a map of string commands to an enum of strongly typed commands.
std::shared_ptr< Kernel::Property > m_periods
TimeSeriesProperty<int> containing data periods. Created by LogParser.
static const std::string currentPeriodLogName()
Returns the name of the log that contains the current period number.
Kernel::TimeSeriesProperty< bool > * createRunningLog() const
Creates a TimeSeriesProperty<bool> with running status.
commands
Available commands.
void tryParsePeriod(const std::string &scom, const Types::Core::DateAndTime &time, std::istringstream &idata, Kernel::TimeSeriesProperty< int > *const periods)
Try to parse period data.
static const std::string periodsLogName()
Returns the name of the log that contains all of the periods.
Kernel::Property * createCurrentPeriodLog(const int &period) const
Creates a log value for the current period.
Kernel::TimeSeriesProperty< bool > * createPeriodLog(int period) const
Creates a TimeSeriesProperty<bool> showing times when a particular period was active.
CommandMap createCommandMap(bool newStyle) const
Creates a map of all available old-style commands.
int m_nOfPeriods
Number of periods.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
void information(const std::string &msg)
Logs at information level.
The concrete, templated class for properties.
Base class for properties.
Represents a time interval.
Types::Core::time_duration length() const
Interval length (in seconds?)
A specialised Property class for holding a series of time-value pairs.
void replaceValues(const std::vector< Types::Core::DateAndTime > ×, const std::vector< TYPE > &values)
Replaces the time series with new values time series values.
int size() const override
Returns the number of values at UNIQUE time intervals in the time series.
void addValue(const Types::Core::DateAndTime &time, const TYPE &value)
Add a value to the map using a DateAndTime object.
std::vector< Types::Core::DateAndTime > timesAsVector() const override
Return the time series's times as a vector<DateAndTime>
Logger g_log("DateAndTime")
MANTID_KERNEL_DLL std::istream & extractToEOL(std::istream &is, std::string &str)
Extract a line from input stream, discarding any EOL characters encountered.
MANTID_KERNEL_DLL double timeMean(const Kernel::Property *p)
Returns the mean value if the property is TimeSeriesProperty<double>
Helper class which provides the Collimation Length for SANS instruments.