12 std::pair<const T*, const T*>
clusters;
13 size_t commonRDOs = 0;
15 ClusterPair(
const T* cluster1,
const T* cluster2,
size_t commonRDOsCount)
16 :
clusters(cluster1, cluster2), commonRDOs(commonRDOsCount) {};
27 size_t compareClusters(
const T* cluster1,
const T* cluster2,
size_t* nonCommonRdo1 =
nullptr,
size_t* nonCommonRdo2 =
nullptr) {
28 const auto& rdoList1 = cluster1->rdoList();
29 const auto& rdoList2 = cluster2->rdoList();
30 std::unordered_set<Identifier> rdoSet1(rdoList1.begin(), rdoList1.end());
31 std::unordered_set<Identifier> rdoSet2(rdoList2.begin(), rdoList2.end());
33 size_t nCommonRdo = 0;
34 for (
const auto& rdo : rdoList1) {
35 if (rdoSet2.count(rdo)) {
39 if (nonCommonRdo1) *nonCommonRdo1 = rdoList1.size() - nCommonRdo;
40 if (nonCommonRdo2) *nonCommonRdo2 = rdoList2.size() - nCommonRdo;
55 std::vector<const T*> findMatchingCluster(
const T* cluster0,
56 const std::unordered_multimap<xAOD::DetectorIdentType, const T*>& clusterMap,
57 const std::unordered_multimap<xAOD::DetectorIDHashType, const T*>& clusterMapHashIdMap,
58 bool matchByID,
const size_t& allowedMisses) {
59 std::vector<const T*> matchedClusters{};
61 std::unordered_set<Identifier> rdoSet0{};
62 for (
const auto& rdo : cluster0->rdoList()) {
65 const size_t rdoToMiss = (allowedMisses < rdoSet0.size()) ? allowedMisses : (rdoSet0.size()-1);
67 auto range = clusterMap.equal_range(cluster0->identifier());
69 size_t nCommonRdo = compareClusters(cluster0,
it->second);
70 if (nCommonRdo >= rdoSet0.size() - rdoToMiss) {
71 matchedClusters.push_back(
it->second);
75 auto range = clusterMapHashIdMap.equal_range(cluster0->identifierHash());
77 const auto& cluster1 =
it->second;
78 size_t nCommonRdo = compareClusters(cluster0, cluster1);
79 if (nCommonRdo >= rdoSet0.size() - rdoToMiss) {
80 matchedClusters.push_back(cluster1);
84 return matchedClusters;
100 std::vector<ClusterPair<T>> findNonMergedClusters(
const std::unordered_multimap<xAOD::DetectorIDHashType, const T*>& clusterMap) {
101 std::vector<ClusterPair<T>> clusterPairs;
102 std::unordered_set<xAOD::DetectorIDHashType> uniqueKeys;
103 for (
const auto& pair : clusterMap) {
104 uniqueKeys.insert(pair.first);
106 for (
const auto&
key : uniqueKeys) {
107 auto range = clusterMap.equal_range(
key);
108 for (
auto it1 =
range.first; it1 !=
range.second; ++it1) {
110 size_t nonCommonRdo1 = 0, nonCommonRdo2 = 0;
111 size_t nCommonRdo = compareClusters(it1->second, it2->second, &nonCommonRdo1, &nonCommonRdo2);
112 if (nCommonRdo > 0) {
113 clusterPairs.emplace_back(it1->second, it2->second, nCommonRdo);
121 template <
typename T>
122 std::string logMultipleClusterMatches(
const std::vector<const T*>& matchedClusters) {
127 out +=
" clusters matching to the same offline cluster:\n";
128 for (
const auto& cluster : matchedClusters) {
131 for (
const auto& rdo : cluster->rdoList()) {
141 const std::string&
name,
142 ISvcLocator* pSvcLocator
161 return StatusCode::SUCCESS;
166 m_chrono->chronoStart(
"FPGAOutputValidationAlg::pixel diff");
175 const auto& pixelClusters0 = *handle0;
176 std::unordered_multimap<xAOD::DetectorIDHashType, const xAOD::PixelCluster*> pixelClustersHashIdMap0;
177 for (
const auto* cluster0 : pixelClusters0) {
179 pixelClustersHashIdMap0.insert(std::make_pair(hashId0, cluster0));
181 const std::vector<ClusterPair<xAOD::PixelCluster>> pixelClusterPairsWithCommonRdos = findNonMergedClusters(pixelClustersHashIdMap0);
182 if (pixelClusterPairsWithCommonRdos.size() > 0) {
183 std::stringstream
ss;
184 for (
const auto& pair : pixelClusterPairsWithCommonRdos) {
185 ss <<
"Found " << pair.commonRDOs <<
" common RDOs between clusters with hash "
186 << pair.clusters.first->identifierHash() <<
": "
187 << pair.clusters.first->identifier() <<
" and "
188 << pair.clusters.second->identifier() <<
"\n";
195 std::unordered_multimap<xAOD::DetectorIdentType, const xAOD::PixelCluster*> pixelClustersMap1;
196 std::unordered_multimap<xAOD::DetectorIDHashType, const xAOD::PixelCluster*> pixelClustersHashIdMap1;
197 for (
const auto* cluster1 : pixelClusters1) {
200 pixelClustersMap1.insert(std::make_pair(id1, cluster1));
201 pixelClustersHashIdMap1.insert(std::make_pair(hashId1, cluster1));
204 for (
auto cluster0 : *handle0) {
205 const std::vector<const xAOD::PixelCluster*> matchedClusters = findMatchingCluster(cluster0, pixelClustersMap1, pixelClustersHashIdMap1,
209 if (matchedClusters.size() == 0) {
210 std::vector<std::string> regions {
"all"};
212 else regions.push_back(
"endcap");
213 for (
const auto& region : regions) {
217 Monitored::Scalar<float>(handle0.key() +
"_UNMATCHED_GLOBALPOSITION_R_" + region, sqrt(cluster0->globalPosition()[0]*cluster0->globalPosition()[0] +
218 cluster0->globalPosition()[1]*cluster0->globalPosition()[1])),
224 if (matchedClusters.size() > 1) {
226 return StatusCode::FAILURE;
231 std::vector<std::string> regions {
"all"};
233 else regions.push_back(
"endcap");
235 for(
auto const& region: regions)
261 cluster0->localPosition<2>()[0] - cluster1->
localPosition<2>()[0]),
263 cluster0->localPosition<2>()[1] - cluster1->
localPosition<2>()[1]),
265 cluster0->localCovariance<2>()(0, 0) - cluster1->
localCovariance<2>()(0, 0)),
267 cluster0->localCovariance<2>()(1, 1) - cluster1->
localCovariance<2>()(1, 1)),
279 m_chrono->chronoStop(
"FPGAOutputValidationAlg::pixel diff");
283 m_chrono->chronoStart(
"FPGAOutputValidationAlg::strip diff");
293 std::unordered_multimap<xAOD::DetectorIDHashType, const xAOD::StripCluster*> stripClustersHashIdMap0;
294 for (
const auto* cluster0 : stripClusters0) {
296 stripClustersHashIdMap0.insert(std::make_pair(hashId0, cluster0));
300 const std::vector<ClusterPair<xAOD::StripCluster>> stripPairsWithCommonRdos = findNonMergedClusters(stripClustersHashIdMap0);
303 if (stripPairsWithCommonRdos.size() > 0) {
304 std::stringstream
ss;
305 for (
const auto& pair : stripPairsWithCommonRdos) {
306 ss <<
"Found " << pair.commonRDOs <<
" common RDOs between clusters with hash "
307 << pair.clusters.first->identifierHash() <<
": "
308 << pair.clusters.first->identifier() <<
" and "
309 << pair.clusters.second->identifier() <<
"\n";
315 std::unordered_multimap<xAOD::DetectorIdentType, const xAOD::StripCluster*> stripClustersMap1;
316 std::unordered_multimap<xAOD::DetectorIDHashType, const xAOD::StripCluster*> stripClustersHashIdMap1;
317 for (
const auto *cluster1 : stripClusters1) {
320 stripClustersMap1.insert(std::make_pair(id1, cluster1));
321 stripClustersHashIdMap1.insert(std::make_pair(hashId1, cluster1));
325 for (
auto cluster0 : *handle0) {
326 const std::vector<const xAOD::StripCluster*> matchedClusters = findMatchingCluster(cluster0, stripClustersMap1, stripClustersHashIdMap1,
330 if (matchedClusters.size() == 0 && handle1->size() > 0) {
331 std::vector<std::string> regions {
"all"};
333 else regions.push_back(
"endcap");
334 for (
const auto& region : regions) {
338 Monitored::Scalar<float>(handle0.key() +
"_UNMATCHED_GLOBALPOSITION_R_" + region, sqrt(cluster0->globalPosition()[0]*cluster0->globalPosition()[0] +
339 cluster0->globalPosition()[1]*cluster0->globalPosition()[1])),
345 if (matchedClusters.size() > 1) {
347 return StatusCode::FAILURE;
352 std::vector<std::string> regions {
"all"};
354 else regions.push_back(
"endcap");
356 for(
auto const& region: regions)
378 cluster0->localPosition<1>()[0] - cluster1->
localPosition<1>()[0]),
380 cluster0->localPosition<1>()[0] - cluster1->
localPosition<1>()[0]),
382 cluster0->localCovariance<1>()(0, 0) - cluster1->
localCovariance<1>()(0, 0)),
394 m_chrono->chronoStop(
"FPGAOutputValidationAlg::strip diff");
403 for(
auto cluster : *handle)
405 std::vector<std::string> regions {
"all"};
407 else regions.push_back(
"endcap");
409 for(
auto const& region: regions)
434 for(
auto cluster : *handle)
436 std::vector<std::string> regions {
"all"};
438 else regions.push_back(
"endcap");
440 for(
auto const& region: regions)
456 return StatusCode::SUCCESS;