Commit 3d037b52 authored by Walter Lampl's avatar Walter Lampl
Browse files

Merge branch 'allow-extractors-in-strings-monitoring-2' into 'master'

AthenaMonitring - allow strings extraction from collection of objects

See merge request !30449
parents 54825101 91ea980c
......@@ -15,7 +15,7 @@ namespace Monitored {
// Forward declares
template <class T> class ValuesCollection;
template <class T> class ObjectsCollection;
template <class T, class R> class ObjectsCollection;
/**
* Declare a monitored (double-convertable) collection
......@@ -53,14 +53,30 @@ namespace Monitored {
* auto phi = Monitored::Collection("Phi", tracks, [](const Track& t) {return t.phi();});
* \endcode
*/
template <class T> ObjectsCollection<T>
template <class T>
ObjectsCollection<T, double>
Collection(std::string name, const T& collection,
std::function<double(const typename ObjectsCollection<T>::const_value_type&)> converterToDouble) {
return ObjectsCollection<T>(std::move(name), collection, std::move(converterToDouble));
std::function<double(const typename ObjectsCollection<T, double>::const_value_type&)> converterToDouble) {
return ObjectsCollection<T, double>(std::move(name), collection, std::move(converterToDouble));
}
template <class T> ObjectsCollection<T>
template <class T>
ObjectsCollection<T, double>
Collection(std::string name, const T&& collection,
std::function<double(const typename ObjectsCollection<T, double>::const_value_type&)> converterToDouble) = delete;
template <class T>
ObjectsCollection<T, std::string>
Collection(std::string name, const T& collection,
std::function<std::string(const typename ObjectsCollection<T, std::string>::const_value_type&)> converterToDouble) {
return ObjectsCollection<T, std::string>(std::move(name), collection, std::move(converterToDouble));
}
template <class T>
ObjectsCollection<T, std::string>
Collection(std::string name, const T&& collection,
std::function<double(const typename ObjectsCollection<T>::const_value_type&)> converterToDouble) = delete;
std::function<std::string(const typename ObjectsCollection<T, std::string>::const_value_type&)> converterToDouble) = delete;
namespace detail {
......@@ -85,7 +101,6 @@ namespace Monitored {
static_assert(std::is_convertible<value_type, double>::value or std::is_constructible<std::string, value_type>::value, "Conversion of collection values to double or string is impossible");
/// @brief . \if empty doc string required due to doxygen bug 787131 \endif
friend ValuesCollection<T> Collection<T>(std::string name, const T& collection);
friend ValuesCollection<T> Collection<T>(std::string name, const T&& collection);
......@@ -108,7 +123,7 @@ namespace Monitored {
private:
const T& m_collection;
ValuesCollection(std::string vname, const T& collection)
: IMonitoredVariable(std::move(vname)), m_collection{collection} {
......@@ -141,55 +156,88 @@ namespace Monitored {
/**
* Monitoring of object collections
*
* Template types are: T - collection, R - result type of the converter function (either convertible to double or to string)
* This class is not supposed to be used by the end user.
*/
template <class T> class ObjectsCollection : public IMonitoredVariable {
template <class T, class R> class ObjectsCollection : public IMonitoredVariable {
public:
/// Type of the collection elements
using value_type = typename detail::get_value_type<T>::value_type;
using const_value_type = typename detail::make_pointer_const<value_type>::type;
static_assert(std::is_convertible<R, double>::value or std::is_constructible<std::string, R>::value, "Conversion from type returned by the converter/accessor to double or string is impossible");
/// @brief . \if empty doc string required due to doxygen bug 787131 \endif
// With a non-template friend declaration, clang 4.0.1
// fails to match the friend.
template <class U> friend ObjectsCollection<U>
template <class U> friend ObjectsCollection<U, double>
Collection(std::string name, const U& collection,
std::function<double(const typename ObjectsCollection<U>::const_value_type&)> converterToDouble);
std::function<double(const typename ObjectsCollection<U, double>::const_value_type&)> converterToDouble);
template <class U> friend ObjectsCollection<U, std::string>
Collection(std::string name, const U& collection,
std::function<std::string(const typename ObjectsCollection<U, std::string>::const_value_type&)> converterToString);
ObjectsCollection(ObjectsCollection&&) = default;
std::vector<double> getVectorRepresentation() const override {
// Reserve space and fill vector
std::vector<double> result;
result.reserve(std::size(m_collection));
for (auto value : m_collection) result.push_back(m_converterToDouble(value));
return result;
return convertToDouble<R>();
}
virtual std::vector<std::string> getStringVectorRepresentation() const override {
return std::vector<std::string>();
return convertToString<R>();
};
virtual bool hasStringRepresentation() const override {
return false;
return std::is_constructible<std::string, R>::value;
};
virtual size_t size() const override {
return std::size(m_collection);
}
private:
const T& m_collection;
std::function<double(const const_value_type&)> m_converterToDouble;
std::function<R(const const_value_type&)> m_converterToR;
ObjectsCollection(std::string name, const T& collection,
std::function<double(const const_value_type&)> converterToDouble)
std::function<R(const const_value_type&)> converterToR)
: IMonitoredVariable(std::move(name)),
m_collection(std::move(collection)),
m_converterToDouble(std::move(converterToDouble)) {}
m_collection(std::move(collection)),
m_converterToR(std::move(converterToR)) {}
ObjectsCollection(ObjectsCollection const&) = delete;
ObjectsCollection& operator=(ObjectsCollection const&) = delete;
template< typename U, std::enable_if_t< std::is_convertible<U, double>::value, int> = 0>
inline std::vector<double> convertToDouble() const {
// Reserve space and fill vector
std::vector<double> result;
result.reserve(std::size(m_collection));
for (const auto& value : m_collection) result.push_back(m_converterToR(value));
return result;
}
template< typename U, std::enable_if_t< !std::is_convertible<U, double>::value, int> = 0>
inline std::vector<double> convertToDouble() const {
return {};
}
template< typename U, std::enable_if_t< std::is_constructible<U, std::string>::value, int> = 0>
inline std::vector<std::string> convertToString() const {
// Reserve space and fill vector
std::vector<std::string> result;
result.reserve(std::size(m_collection));
for (const auto& value : m_collection) result.push_back(m_converterToR(value));
return result;
}
template< typename U, std::enable_if_t< !std::is_constructible<U, std::string>::value, int> = 0>
inline std::vector<std::string> convertToString() const {
return {};
}
};
......
......@@ -464,6 +464,44 @@ bool stringFillingWorked(ToolHandle<GenericMonitoringTool>& monTool, ITHistSvc*
return true;
}
bool stringFromCollectionWorked(ToolHandle<GenericMonitoringTool>& monTool, ITHistSvc* histSvc) {
auto fill = [&]() {
/**
* \code Monitored::Collection("name", colelction, converter_or_extractor );
* This example illustrates how to use functionality to monitor occurrences of strings from collection of some objects.
* The example StringInObject is just a test class that contains the string that we want to monitor.
* The "converter_or_extractor" is converting elements of the collection to a string.
* It can be either a member method or a lambda expression.
* The type returned by the functor can be anything from which the std::string can be constructed.
**/
struct StringInObject {
int layer;
std::string name;
const std::string& getName() const { return name; }
};
std::vector<StringInObject> testData({{0, "PIX"},{1, "PIX"},{3, "SCT"}, {1, "PIX"}});
auto name = Monitored::Collection("DetID", testData, [](const StringInObject& s){ return s.getName(); } ); // lambda as a converter
auto ignored1 = Monitored::Collection("ignored", testData, &StringInObject::getName ); // access via member function is supported
auto ignored2 = Monitored::Collection("ignored", testData, [](const StringInObject& s){ return s.getName().c_str(); } ); // converter returning const char* is supported
Monitored::Group(monTool, name);
return 4; // number of entries
};
auto check = [&](size_t N) {
const TH1* h = getHist( histSvc, "/EXPERT/TestGroup/DetID" );
VALUE( h->GetEntries() ) EXPECTED( N );
VALUE( h->GetXaxis()->GetLabels()->GetEntries() ) EXPECTED( 2 ); // two distinct strings used in input data
};
resetHists( histSvc ); check(fill());
resetHists( histSvc ); check(fill_mt(fill));
return true;
}
bool string2DFillingWorked(ToolHandle<GenericMonitoringTool>& monTool, ITHistSvc* histSvc) {
auto fill = [&]() {
......@@ -496,6 +534,7 @@ bool string2DFillingWorked(ToolHandle<GenericMonitoringTool>& monTool, ITHistSvc
}
return 1;
};
auto check = [&](size_t N) {
const TH1* h = getHist( histSvc, "/EXPERT/TestGroup/DetID_vs_DetCalo" );
int larBin = h->GetXaxis()->FindFixBin("LAr");
......@@ -580,8 +619,11 @@ int main() {
assert( stringFillingWorked( validMon, histSvc ) );
log << MSG::DEBUG << "string2DFillingWorked" << endmsg;
assert( string2DFillingWorked( validMon, histSvc ) );
log << MSG::DEBUG << "stringFromCollectionWorked" << endmsg;
assert( stringFromCollectionWorked( validMon, histSvc ) );
log << MSG::DEBUG << "All OK" << endmsg;
// Make sure that THistSvc gets finalized.
// Otherwise, the output file will get closed while global dtors are running,
// which can lead to crashes.
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment