13#include <nexus/NeXusFile.hpp>
17using namespace Kernel;
18using namespace Types::Core;
22Logger
g_log(
"LogManager");
25template <
typename T>
bool convertSingleValue(
const Property *property,
double &
value) {
26 if (
auto log =
dynamic_cast<const PropertyWithValue<T> *
>(property)) {
27 value =
static_cast<double>(*log);
37 if (
const auto *log =
dynamic_cast<const TimeSeriesProperty<T> *
>(property)) {
40 value =
static_cast<double>(log->timeAverageValue());
43 value =
static_cast<double>(log->firstValue());
46 value =
static_cast<double>(log->lastValue());
49 value =
static_cast<double>(log->maxValue());
52 value =
static_cast<double>(log->minValue());
55 value =
static_cast<double>(log->mean());
58 value = log->getStatistics().median;
61 throw std::invalid_argument(
"Statistic type not recognised/supported");
72 return convertSingleValue<T>(property,
value) || convertTimeSeriesToDouble<T>(property,
value, function);
80 return convertPropertyToDouble<double>(property,
value, function) ||
81 convertPropertyToDouble<int32_t>(property,
value, function) ||
82 convertPropertyToDouble<int64_t>(property,
value, function) ||
83 convertPropertyToDouble<uint32_t>(property,
value, function) ||
84 convertPropertyToDouble<uint64_t>(property,
value, function) ||
85 convertPropertyToDouble<float>(property,
value, function);
99 std::make_unique<Kernel::
Cache<
std::pair<
std::string, Kernel::Math::StatisticType>, double>>()) {}
103 m_singleValueCache(
std::make_unique<Kernel::
Cache<
std::pair<
std::string, Kernel::Math::StatisticType>, double>>(
104 *other.m_singleValueCache)) {}
111 m_singleValueCache = std::make_unique<Kernel::Cache<std::pair<std::string, Kernel::Math::StatisticType>,
double>>(
112 *other.m_singleValueCache);
122 this->addProperty<std::string>(
"start_time", start.toISO8601String(),
true);
123 this->addProperty<std::string>(
"end_time", end.toISO8601String(),
true);
134 const std::string start_prop(
"start_time");
138 if (start_time != DateAndTime::GPS_EPOCH) {
141 }
catch (std::invalid_argument &) {
145 const std::string run_start_prop(
"run_start");
149 if (start_time != DateAndTime::GPS_EPOCH) {
152 }
catch (std::invalid_argument &) {
156 throw std::runtime_error(
"No valid start time has been set for this run.");
166 const std::string end_prop(
"end_time");
170 }
catch (std::invalid_argument &) {
174 const std::string run_end_prop(
"run_end");
178 }
catch (std::invalid_argument &) {
182 throw std::runtime_error(
"No valid end time has been set for this run.");
211 const size_t n = outputs.size();
212 std::vector<PropertyManager *> output_managers(outputs.size(),
nullptr);
213 for (
size_t i = 0; i <
n; i++) {
215 output_managers[i] = outputs[i]->m_manager.get();
220 m_manager->splitByTime(splitter, output_managers);
232 const std::vector<std::string> &excludedFromFiltering) {
235 m_manager->filterByProperty(filter, excludedFromFiltering);
252 std::string name = prop->name();
256 m_manager->declareProperty(std::move(prop),
"");
277 for (
unsigned int stat = 0; stat < 7; ++stat) {
280 m_manager->removeProperty(name, delProperty);
294 std::vector<Property *> props =
m_manager->getProperties();
295 for (
auto p : props) {
297 total += p->getMemorySize() +
sizeof(
Property *);
313 throw std::invalid_argument(
"Run::getTimeSeriesProperty - '" + name +
"' is not a TimeSeriesProperty");
323 return getTimeSeriesProperty<double>(name)->getStatistics().time_standard_deviation;
335 return (*valueProp)();
337 throw std::invalid_argument(
"Run::getPropertyValueAsType - '" + name +
"' is not of the requested type");
350 double singleValue(0.0);
351 const auto key = std::make_pair(name, statistic);
354 if (!convertPropertyToDouble(log, singleValue, statistic)) {
358 singleValue = std::stod(stringLog->value());
359 }
catch (
const std::invalid_argument &) {
360 throw std::invalid_argument(
"Run::getPropertyAsSingleValue - Property \"" + name +
361 "\" cannot be converted to a numeric value.");
364 throw std::invalid_argument(
"Run::getPropertyAsSingleValue - Property \"" + name +
365 "\" is not a single numeric value or numeric time series.");
387 if (convertSingleValue<int32_t>(prop, discard) || convertSingleValue<int64_t>(prop, discard) ||
388 convertSingleValue<uint32_t>(prop, discard) || convertSingleValue<uint64_t>(prop, discard)) {
389 singleValue = std::stoi(prop->
value());
391 throw std::invalid_argument(
"Run::getPropertyAsIntegerValue - Property \"" + name +
392 "\" cannot be converted to an integer value.");
418 for (
auto prop : props) {
431 for (
auto prop : props) {
433 tsp->clearOutdated();
446 file->makeGroup(group,
"NXgroup",
true);
447 file->putAttr(
"version", 1);
450 std::vector<Property *> props =
m_manager->getProperties();
451 for (
auto &prop : props) {
453 prop->saveProperty(file);
454 }
catch (std::invalid_argument &exc) {
485 if (!group.empty()) {
486 file->openGroup(group,
"NXgroup");
488 std::map<std::string, std::string> entries;
489 file->getEntries(entries);
492 if (!(group.empty() || keepOpen)) {
498 const std::string &prefix) {
502 auto itNxLogEntries = allEntries.find(
"NXlog");
503 const std::set<std::string> &nxLogEntries =
504 (itNxLogEntries != allEntries.end()) ? itNxLogEntries->second : std::set<std::string>{};
506 const auto levels = std::count(prefix.begin(), prefix.end(),
'/');
508 auto itLower = nxLogEntries.lower_bound(prefix);
510 if (itLower == nxLogEntries.end()) {
513 if (itLower->compare(0, prefix.size(), prefix) != 0) {
517 for (
auto it = itLower; it != nxLogEntries.end() && it->compare(0, prefix.size(), prefix) == 0; ++it) {
519 const std::string &absoluteEntryName = *it;
520 if (std::count(absoluteEntryName.begin(), absoluteEntryName.end(),
'/') != levels + 1) {
523 const std::string nameClass = absoluteEntryName.substr(absoluteEntryName.find_last_of(
'/') + 1);
527 if (m_manager->existsProperty(prop->name())) {
528 m_manager->removeProperty(prop->name());
530 m_manager->declareProperty(std::move(prop));
544 for (
const auto &name_class : entries) {
546 if (name_class.second ==
"NXlog") {
549 if (
m_manager->existsProperty(prop->name())) {
552 m_manager->declareProperty(std::move(prop));
598#define INSTANTIATE(TYPE) \
599 template MANTID_API_DLL Kernel::TimeSeriesProperty<TYPE> *LogManager::getTimeSeriesProperty(const std::string &) \
601 template MANTID_API_DLL TYPE LogManager::getPropertyValueAsType(const std::string &) const;
double value
The value of the point.
#define INSTANTIATE(TYPE)
This class contains the information about the log entries.
double getTimeAveragedStd(const std::string &name) const
Get the time averaged standard deviation for a log.
bool operator!=(const LogManager &other) const
virtual size_t getMemorySize() const
Return an approximate memory size for the object in bytes.
const Types::Core::DateAndTime endTime() const
Return the run end time.
bool hasProperty(const std::string &name) const
Does the property exist on the object.
const std::vector< Kernel::Property * > & getLogData() const
Access all log entries.
virtual void loadNexus(::NeXus::File *file, const std::string &group, const Mantid::Kernel::NexusHDF5Descriptor &fileInfo, const std::string &prefix, bool keepOpen=false)
Load the run from a NeXus file with a given group name.
std::unique_ptr< Kernel::PropertyManager > m_manager
A pointer to a property manager.
Kernel::TimeSeriesProperty< bool > * getInvalidValuesFilter(const std::string &logName) const
returns the invalid values log if the log has a matching invalid values log filter
void filterByLog(const Kernel::TimeSeriesProperty< bool > &filter, const std::vector< std::string > &excludedFromFiltering=std::vector< std::string >())
Filter the run by the given boolean log.
const Types::Core::DateAndTime startTime() const
Return the run start time.
void clearOutdatedTimeSeriesLogValues()
Empty all but the last value out of all TimeSeriesProperty logs.
virtual void saveNexus(::NeXus::File *file, const std::string &group, bool keepOpen=false) const
Save the run to a NeXus file with a given group name.
virtual ~LogManager()
Destructor.
static const char * PROTON_CHARGE_LOG_NAME
Name of the log entry containing the proton charge when retrieved using getProtonCharge.
int getPropertyAsIntegerValue(const std::string &name) const
Returns a property as an integer value.
std::unique_ptr< Kernel::Cache< std::pair< std::string, Kernel::Math::StatisticType >, double > > m_singleValueCache
Cache for the retrieved single values.
Kernel::Property * getProperty(const std::string &name) const
Returns the named property as a pointer.
void removeProperty(const std::string &name, bool delProperty=true)
Remove a named property.
virtual void filterByTime(const Types::Core::DateAndTime start, const Types::Core::DateAndTime stop)
Filter the logs by time.
const std::vector< Kernel::Property * > & getProperties() const
Return all of the current properties.
void addProperty(Kernel::Property *prop, bool overwrite=false)
Add data to the object in the form of a property.
double getPropertyAsSingleValue(const std::string &name, Kernel::Math::StatisticType statistic=Kernel::Math::Mean) const
Returns a property as a single double value from its name.
static std::string getInvalidValuesFilterLogName(const std::string &logName)
Gets the correct log name for the matching invalid values log for a given log name.
void clearTimeSeriesLogs()
Empty the values out of all TimeSeriesProperty logs.
LogManager & operator=(const LogManager &other)
bool operator==(const LogManager &other) const
HeldType getPropertyValueAsType(const std::string &name) const
Get the value of a property as the given TYPE.
void clearLogs()
Clear the logs.
Kernel::TimeSeriesProperty< T > * getTimeSeriesProperty(const std::string &name) const
Returns a property as a time series property.
bool hasInvalidValuesFilter(const std::string &logName) const
returns true if the log has a matching invalid values log filter
void setStartAndEndTime(const Types::Core::DateAndTime &start, const Types::Core::DateAndTime &end)
Set the run start and end.
virtual void splitByTime(Kernel::TimeSplitterType &splitter, std::vector< LogManager * > outputs) const
Split the logs based on the given intervals.
Cache is a generic caching storage class.
Exception for when an item is not found in a collection.
A non-templated interface to a TimeSeriesProperty.
void warning(const std::string &msg)
Logs at warning level.
const std::map< std::string, std::set< std::string > > & getAllEntries() const noexcept
Returns a const reference of the internal map holding all entries in the NeXus HDF5 file.
Property manager helper class.
static std::string getInvalidValuesFilterLogName(const std::string &logName)
Gets the correct log name for the matching invalid values log for a given log name.
The concrete, templated class for properties.
Base class for properties.
virtual std::string value() const =0
Returns the value of the property as a string.
A specialised Property class for holding a series of time-value pairs.
Kernel::Logger g_log("ExperimentInfo")
static logger object
StatisticType
Maps a "statistic" to a number.
DLLExport std::unique_ptr< Property > loadProperty(::NeXus::File *file, const std::string &group, const Mantid::Kernel::NexusHDF5Descriptor &fileInfo, const std::string &prefix)
Opens a NXlog group in a nexus file and creates the correct Property object from it.
std::vector< SplittingInterval > TimeSplitterType
A typedef for splitting events according their pulse time.