_GTestTrdClusterizer.cxx 17.76 KiB
/* Copyright (C) 2024 Facility for Anti-Proton and Ion Research in Europe, Darmstadt
SPDX-License-Identifier: GPL-3.0-only
Authors: Axel Puntke [committer] */
#include "CbmTrdDigi.h"
#include "gtest/gtest-spi.h"
#include "gtest/gtest.h"
#include "trd/Clusterizer.h"
#include "trd/HitFinderPars.h"
//Charge values to be used for self- and neighbor-triggers
double CHARGE_ST = 1000;
double CHARGE_NT = 500;
//Value to be used for module address
int MADDR = 21;
cbm::algo::trd::Clusterizer* CreateTestModule()
{
//create type 5 module for testing
cbm::algo::trd::HitFinderModPar modPar;
modPar.padSizeX = 0.666667;
modPar.padSizeY = 12.0;
modPar.padSizeErrX = 0.0;
modPar.padSizeErrY = 0.0;
modPar.padSizeErrY = 0.0;
modPar.address = MADDR;
modPar.orientation = 0;
int nCols = 144;
int nRows = 24;
for (int iRow = 0; iRow < nRows; ++iRow) {
cbm::algo::trd::HitFinderRowPar rowPar;
for (int iCol = 0; iCol < nCols; ++iCol) {
cbm::algo::trd::HitFinderPadPar padPar;
rowPar.padPar.push_back(padPar);
}
modPar.rowPar.push_back(rowPar);
}
return new cbm::algo::trd::Clusterizer(modPar);
}
//returns all possible combinations of the digis, each combination separated in time by timeSeparation
std::vector<CbmTrdDigi*> PermutateDigis(std::vector<CbmTrdDigi*> digis, double timeSeparation = 3000)
{
std::vector<CbmTrdDigi*> digisPermutated;
std::vector<int> v;
for (size_t i = 0; i < digis.size(); ++i)
v.push_back(i);
double timeAdd = 0;
do {
for (auto e : v) {
digisPermutated.push_back(digis.at(e));
digisPermutated.back()->SetTime(digis.at(e)->GetTime() + timeAdd);
}
timeAdd += timeSeparation;
} while (std::next_permutation(v.begin(), v.end()));
std::sort(digisPermutated.begin(), digisPermutated.end(),
[](const CbmTrdDigi* lhs, const CbmTrdDigi* rhs) { return lhs->GetTime() < rhs->GetTime(); });
return digisPermutated;
}
//returns digi vector in corrent format to pass to the clusterizer
const std::vector<std::pair<CbmTrdDigi, int32_t>> CreateClusterizerInputVector(std::vector<CbmTrdDigi*> digis)
{
std::vector<std::pair<CbmTrdDigi, int32_t>> inVec;
int32_t idx = 0;
for (auto digi : digis)
inVec.push_back(std::make_pair<CbmTrdDigi, int32_t>(std::move(*digi), idx++));
return inVec;
}
std::vector<uint16_t> GetClusterSizes(std::vector<cbm::algo::trd::Cluster> clusters)
{
std::vector<uint16_t> clusterSizes;
for (auto cluster : clusters)
clusterSizes.push_back(cluster.GetNofDigis());
return clusterSizes;
}
TEST(_GTestTrdClusterizer, Check3PadCluster)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
digis.push_back(new CbmTrdDigi(15, MADDR, CHARGE_NT, 100, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(16, MADDR, CHARGE_ST, 100, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(17, MADDR, CHARGE_NT, 100, CbmTrdDigi::eTriggerType::kNeighbor, 0));
std::vector<CbmTrdDigi*> digisPermutated = PermutateDigis(digis);
int nPermutations = digisPermutated.size() / digis.size();
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digisPermutated));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusters.size(), nPermutations);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 3), nPermutations);
}
TEST(_GTestTrdClusterizer, Check1PadSTCluster)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
digis.push_back(new CbmTrdDigi(16, MADDR, CHARGE_ST, 100, CbmTrdDigi::eTriggerType::kSelf, 0));
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digis));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusterSizes, (std::vector<uint16_t>){1});
//EXPECT_FALSE(module->IsClusterComplete( (CbmTrdCluster*)(clusters->At(0)) ));
}
TEST(_GTestTrdClusterizer, Check1PadNTCluster)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
digis.push_back(new CbmTrdDigi(16, MADDR, CHARGE_NT, 100, CbmTrdDigi::eTriggerType::kNeighbor, 0));
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digis));
EXPECT_EQ(clusters.size(), 0);
//EXPECT_FALSE(module->IsClusterComplete( (CbmTrdCluster*)(clusters->At(0)) ));
}
TEST(_GTestTrdClusterizer, Check2PadLeftNTCluster)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
digis.push_back(new CbmTrdDigi(15, MADDR, CHARGE_NT, 100, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(16, MADDR, CHARGE_ST, 100, CbmTrdDigi::eTriggerType::kSelf, 0));
std::vector<CbmTrdDigi*> digisPermutated = PermutateDigis(digis);
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digisPermutated));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusters.size(), 2);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 2), 2);
//EXPECT_FALSE(module->IsClusterComplete( (CbmTrdCluster*)(clusters->At(0)) ));
}
TEST(_GTestTrdClusterizer, Check2PadRightNTCluster)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
digis.push_back(new CbmTrdDigi(16, MADDR, CHARGE_ST, 100, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(17, MADDR, CHARGE_NT, 100, CbmTrdDigi::eTriggerType::kNeighbor, 0));
std::vector<CbmTrdDigi*> digisPermutated = PermutateDigis(digis);
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digisPermutated));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusters.size(), 2);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 2), 2);
//EXPECT_FALSE(module->IsClusterComplete( (CbmTrdCluster*)(clusters->At(0)) ));
}
/* currently fails at permutation 3 (digi order 143, 144, 142) */
TEST(_GTestTrdClusterizer, Check2PadWithSTOnNextRowCluster)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
digis.push_back(new CbmTrdDigi(142, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(143, MADDR, CHARGE_ST, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(144, MADDR, CHARGE_ST, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
std::vector<CbmTrdDigi*> digisPermutated = PermutateDigis(digis);
int nPermutations = digisPermutated.size() / digis.size();
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digisPermutated));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusters.size(), nPermutations * 2);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 2), nPermutations);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 1), nPermutations);
}
TEST(_GTestTrdClusterizer, Check2PadWithNTOnNextRowCluster)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
digis.push_back(new CbmTrdDigi(142, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(143, MADDR, CHARGE_ST, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(144, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
std::vector<CbmTrdDigi*> digisPermutated = PermutateDigis(digis);
int nPermutations = digisPermutated.size() / digis.size();
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digisPermutated));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusters.size(), nPermutations);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 2), nPermutations);
}
TEST(_GTestTrdClusterizer, Check2PadWithSTOnPrevRowCluster)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
digis.push_back(new CbmTrdDigi(143, MADDR, CHARGE_ST, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(144, MADDR, CHARGE_ST, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(145, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
std::vector<CbmTrdDigi*> digisPermutated = PermutateDigis(digis);
int nPermutations = digisPermutated.size() / digis.size();
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digisPermutated));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusters.size(), nPermutations * 2);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 2), nPermutations);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 1), nPermutations);
}
TEST(_GTestTrdClusterizer, Check2PadWithNTOnPrevRowCluster)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
digis.push_back(new CbmTrdDigi(143, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(144, MADDR, CHARGE_ST, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(145, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
std::vector<CbmTrdDigi*> digisPermutated = PermutateDigis(digis);
int nPermutations = digisPermutated.size() / digis.size();
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digisPermutated));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusters.size(), nPermutations);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 2), nPermutations);
}
TEST(_GTestTrdClusterizer, CheckAdjacent3PadClusters)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
digis.push_back(new CbmTrdDigi(149, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(150, MADDR, CHARGE_ST, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(151, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(152, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(153, MADDR, CHARGE_ST, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(154, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
std::vector<CbmTrdDigi*> digisPermutated = PermutateDigis(digis);
int nPermutations = digisPermutated.size() / digis.size();
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digisPermutated));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusters.size(), nPermutations * 2);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 3), nPermutations * 2);
}
TEST(_GTestTrdClusterizer, Check3PadWithSingleNTCluster)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
digis.push_back(new CbmTrdDigi(149, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(150, MADDR, CHARGE_ST, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(151, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(152, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
std::vector<CbmTrdDigi*> digisPermutated = PermutateDigis(digis);
int nPermutations = digisPermutated.size() / digis.size();
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digisPermutated));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusters.size(), nPermutations);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 3), nPermutations);
}
TEST(_GTestTrdClusterizer, CheckLeftAndRightBordersFullyTriggered)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
for (int row = 0; row < 24; ++row) {
digis.push_back(new CbmTrdDigi(row * 144, MADDR, CHARGE_ST, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi((row + 1) * 144 - 1, MADDR, CHARGE_ST, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
}
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digis));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
//no row merging expected because rows only get merged when they have at least 3 digis
EXPECT_EQ(clusters.size(), 48);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 1), 48);
}
/*
// 2-row clusters currently not supported by the new clusterizer
TEST(_GTestTrdClusterizer, Check2Row6PadCluster)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
// clusters need to have approximately same COG, but displacement of 0 is not supported yet (should be though)
// the order has to be the one below for the current clusterizer (Mar 17 2024)
// it is e.g. important, that the selftriggers come first and the left NTs have lower charge than the right ones (also not good)
digis.push_back(new CbmTrdDigi(503, MADDR, 1.0, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(502, MADDR, 0.5, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(504, MADDR, 0.9, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(647, MADDR, 1.0, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(646, MADDR, 0.5, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(648, MADDR, 0.9, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
std::vector<CbmTrdDigi*> digisPermutated = PermutateDigis(digis);
int nPermutations = digisPermutated.size() / digis.size();
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digisPermutated));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusters.size(), nPermutations);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 6), nPermutations);
}
// 2-row clusters currently not supported by the new clusterizer
TEST(_GTestTrdClusterizer, Check2Row4Plus3PadCluster)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
digis.push_back(new CbmTrdDigi(503, MADDR, 1.0, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(504, MADDR, 1.0, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(502, MADDR, 0.5, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(505, MADDR, 0.9, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(647, MADDR, 1.0, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(646, MADDR, 0.5, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(648, MADDR, 0.9, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
std::vector<CbmTrdDigi*> digisPermutated = PermutateDigis(digis);
int nPermutations = digisPermutated.size() / digis.size();
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digisPermutated));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusters.size(), nPermutations);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 7), nPermutations);
}
*/
TEST(_GTestTrdClusterizer, CheckTimeDistanceSmallEnough)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
//digis with time distance <= 1 Spadic clock cycle (62.5 ns) should be in same cluster
digis.push_back(new CbmTrdDigi(503, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(504, MADDR, CHARGE_ST, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(505, MADDR, CHARGE_ST, 562, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(506, MADDR, CHARGE_NT, 562, CbmTrdDigi::eTriggerType::kNeighbor, 0));
std::vector<CbmTrdDigi*> digisPermutated = PermutateDigis(digis);
int nPermutations = digisPermutated.size() / digis.size();
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digisPermutated));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusters.size(), nPermutations);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 4), nPermutations);
}
TEST(_GTestTrdClusterizer, CheckTimeDistanceTooHigh)
{
cbm::algo::trd::Clusterizer* module = CreateTestModule();
std::vector<CbmTrdDigi*> digis;
//digis with time distance > 1 Spadic clock cycle (62.5 ns) should not be in same cluster
digis.push_back(new CbmTrdDigi(503, MADDR, CHARGE_NT, 500, CbmTrdDigi::eTriggerType::kNeighbor, 0));
digis.push_back(new CbmTrdDigi(504, MADDR, CHARGE_ST, 500, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(505, MADDR, CHARGE_ST, 563, CbmTrdDigi::eTriggerType::kSelf, 0));
digis.push_back(new CbmTrdDigi(506, MADDR, CHARGE_NT, 563, CbmTrdDigi::eTriggerType::kNeighbor, 0));
std::vector<CbmTrdDigi*> digisPermutated = PermutateDigis(digis);
int nPermutations = digisPermutated.size() / digis.size();
std::vector<cbm::algo::trd::Cluster> clusters = (*module)(CreateClusterizerInputVector(digisPermutated));
std::vector<uint16_t> clusterSizes = GetClusterSizes(clusters);
EXPECT_EQ(clusters.size(), nPermutations * 2);
EXPECT_EQ(std::count(clusterSizes.begin(), clusterSizes.end(), 2), nPermutations * 2);
}