Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use common track-TP association in track and vertex validation #8888

Merged
143 changes: 143 additions & 0 deletions CommonTools/Utils/interface/associationMapFilterValues.h
@@ -0,0 +1,143 @@
#ifndef CommonTools_Utils_associationMapFilterValues_h
#define CommonTools_Utils_associationMapFilterValues_h

#include "DataFormats/Common/interface/Ref.h"
#include "DataFormats/Common/interface/RefVector.h"
#include "DataFormats/Common/interface/View.h"
#include "DataFormats/Common/interface/AssociationMapHelpers.h"

#include <unordered_set>

namespace associationMapFilterValuesHelpers {
// Common implementation
template <typename T_AssociationMap, typename T_Key,
typename T_ValueIndex, typename T_Value,
typename T_ValueIndices>
void findInsert(T_AssociationMap& ret, const T_Key& key,
const T_ValueIndex& valueIndex, const T_Value& value,
const T_ValueIndices& value_indices) {
if(value_indices.find(valueIndex) != value_indices.end()) {
ret.insert(key, value);
}
}

// By default no implementation, as it turns out to be very specific for the types
template <typename ValueTag>
struct IfFound;

// Specialize for Ref and RefToBase, implementation is the same
template <typename C, typename T, typename F>
struct IfFound<edm::Ref<C, T, F>> {
template <typename T_AssociationMap, typename T_KeyValue, typename T_ValueIndices>
static void insert(T_AssociationMap& ret, const T_KeyValue& keyValue, const T_ValueIndices& value_indices) {
findInsert(ret, keyValue.key, keyValue.val.key(), keyValue.val, value_indices);
}
};

template <typename T>
struct IfFound<edm::RefToBase<T>> {
template <typename T_AssociationMap, typename T_KeyValue, typename T_ValueIndices>
static void insert(T_AssociationMap& ret, const T_KeyValue& keyValue, const T_ValueIndices& value_indices) {
findInsert(ret, keyValue.key, keyValue.val.key(), keyValue.val, value_indices);
}
};

// Specialize for RefVector
template <typename C, typename T, typename F>
struct IfFound<edm::RefVector<C, T, F>> {
template <typename T_AssociationMap, typename T_KeyValue, typename T_ValueIndices>
static void insert(T_AssociationMap& ret, const T_KeyValue& keyValue, const T_ValueIndices& value_indices) {
for(const auto& value: keyValue.val) {
findInsert(ret, keyValue.key, value.key(), value, value_indices);
}
}
};

// Specialize for vector<pair<Ref, Q>> for OneToManyWithQuality
template <typename C, typename T, typename F, typename Q>
struct IfFound<std::vector<std::pair<edm::Ref<C, T, F>, Q> > > {
template <typename T_AssociationMap, typename T_KeyValue, typename T_ValueIndices>
static void insert(T_AssociationMap& ret, const T_KeyValue& keyValue, const T_ValueIndices& value_indices) {
for(const auto& value: keyValue.val) {
findInsert(ret, keyValue.key, value.first.key(), value, value_indices);
}
}
};

// Specialize for vector<pair<RefToBase, Q>> for OneToManyWithQuality
template <typename T, typename Q>
struct IfFound<std::vector<std::pair<edm::RefToBase<T>, Q> > > {
template <typename T_AssociationMap, typename T_KeyValue, typename T_ValueIndices>
static void insert(T_AssociationMap& ret, const T_KeyValue& keyValue, const T_ValueIndices& value_indices) {
for(const auto& value: keyValue.val) {
findInsert(ret, keyValue.key, value.first.key(), value, value_indices);
}
}
};

// Default implementation for RefVector or vector<Ref>
template <typename T_RefVector>
struct FillIndices {
template <typename T_Set, typename T_RefProd>
static
void fill(T_Set& set, const T_RefVector& valueRefs, const T_RefProd& refProd) {
for(const auto& ref: valueRefs) {
edm::helpers::checkRef(refProd.val, ref);
set.insert(ref.key());
}
}
};

// Specialize for View
template <typename T>
struct FillIndices<edm::View<T> > {
template <typename T_Set, typename T_RefProd>
static
void fill(T_Set& set, const edm::View<T>& valueView, const T_RefProd& refProd) {
for(size_t i=0; i<valueView.size(); ++i) {
const auto& ref = valueView.refAt(i);
edm::helpers::checkRef(refProd.val, ref);
set.insert(ref.key());
}
}
};
}

/**
* Filters entries of AssociationMap by keeping only those
* associations that have a value in a given collection
*
* @param map AssociationMap to filter
* @param valueRefs Collection of Refs to values.
*
* @tparam T_AssociationMap Type of the AssociationMap
* @tparam T_RefVector Type of the Ref collection.
*
* For AssociationMap<Tag<CKey, CVal>>, the collection of Refs can be
* RefVector<CVal>, vector<Ref<CVal>>, vector<RefToBase<CVal>>, or
* View<T>. More can be supported if needed.
*
* @return A filtered copy of the AssociationMap
*
* Throws if the values of AssociationMap and valueRefs point to
* different collections (similar check as in
* AssociationMap::operator[] for the keys).
*/
template <typename T_AssociationMap, typename T_RefVector>
T_AssociationMap associationMapFilterValues(const T_AssociationMap& map, const T_RefVector& valueRefs) {
T_AssociationMap ret(map.refProd());

// First copy the keys of values to a set for faster lookup of their existence in the map
std::unordered_set<typename T_AssociationMap::index_type> value_indices;
associationMapFilterValuesHelpers::FillIndices<T_RefVector>::fill(value_indices, valueRefs, map.refProd());

for(const auto& keyValue: map) {
associationMapFilterValuesHelpers::IfFound<typename T_AssociationMap::value_type::value_type>::insert(ret, keyValue, value_indices);
}


return ret;
}

#endif

2 changes: 1 addition & 1 deletion CommonTools/Utils/test/BuildFile.xml
@@ -1,4 +1,4 @@
<bin name="testCommonToolsUtil" file="testSelectors.cc,testSelectIterator.cc,testComparators.cc,testCutParser.cc,testExpressionParser.cc,testRunner.cpp">
<bin name="testCommonToolsUtil" file="testSelectors.cc,testSelectIterator.cc,testComparators.cc,testCutParser.cc,testExpressionParser.cc,testAssociationMapFilterValues.cc,testRunner.cpp">
<use name="Geometry/CommonDetUnit"/>
<use name="DataFormats/TrackReco"/>
<use name="DataFormats/TrackerRecHit2D"/>
Expand Down