12#define BOOST_TEST_MODULE midSimulation
13#define BOOST_TEST_DYN_LINK
14#include <boost/test/unit_test.hpp>
16#include <boost/test/data/test_case.hpp>
46 std::vector<ColumnData>
v;
48 v.insert(
v.begin(),
ref.begin(),
ref.end());
69static SimBase simBase;
79static SimDigitizer simDigitizer;
95static SimClustering simClustering;
109static SimTracking simTracking;
120 std::vector<Hit> hits;
121 std::random_device
rd;
122 std::mt19937
mt(
rd());
123 std::uniform_real_distribution<double>
distX(-127.5, 127.5);
124 std::uniform_real_distribution<double>
distY(-40., 40.);
125 while (hits.size() < nHits) {
131 hits.emplace_back(hits.size(), deId, globalPoint, globalPoint);
146 std::vector<size_t>
ids;
147 auto& refHits = genTracks[igen].hits;
148 for (
auto itr = 0; itr < genTracks.size(); ++itr) {
150 ids.emplace_back(itr);
153 auto& hits = genTracks[itr].hits;
154 if (hits.size() == refHits.size()) {
156 for (
auto ihit = 0; ihit < refHits.size(); ++ihit) {
157 if (hits[ihit].GetDetectorID() == refHits[ihit].GetDetectorID() && std::abs(hits[ihit].GetX() - refHits[ihit].GetX()) < 8. && std::abs(hits[ihit].GetY() - refHits[ihit].GetY()) < 8.) {
163 if (nSame == refHits.size()) {
164 ids.emplace_back(itr);
174 std::vector<GenTrack> genTracks;
175 for (
auto trackIt = tracks.begin(),
end = tracks.end(); trackIt !=
end; ++trackIt) {
176 auto trackId = std::distance(tracks.begin(), trackIt);
178 genTrack.
track = *trackIt;
179 for (
int ich = 0; ich < 4; ++ich) {
181 bool isFired =
false;
184 if (!stripIndex.isValid()) {
188 genTrack.
hits.emplace_back(trackId, cl.deId,
pos,
pos);
195 genTracks.emplace_back(genTrack);
202 std::stringstream ss;
207 ss <<
"label deId " <<
label.getDEId() <<
" != " << digit.
deId <<
"\n";
211 ss <<
"label columnId " <<
label.getColumnId() <<
" != " << digit.
columnId <<
"\n";
213 int firstStrip =
label.getFirstStrip();
214 int lastStrip =
label.getLastStrip();
215 int cathode =
label.getCathode();
216 int nLines = (cathode == 0) ? 4 : 1;
217 for (
int iline = 0; iline < nLines; ++iline) {
218 for (
int istrip = 0; istrip < 16; ++istrip) {
220 bool isFired = digit.
isStripFired(istrip, cathode, iline);
221 if (isFired != (currStrip >= firstStrip && currStrip <= lastStrip)) {
223 ss <<
"Cathode: " << cathode <<
" firstStrip: " << firstStrip <<
" lastStrip: " << lastStrip;
224 ss <<
" line: " << iline <<
" strip: " << istrip <<
" fired: " << isFired <<
"\n";
228 errorMessage = ss.str();
234 std::vector<PreCluster> sortedPC;
242 std::sort(sortedPC.begin(), sortedPC.end(), [](
const PreCluster& pc1,
const PreCluster& pc2) { return (pc1.firstColumn <= pc2.firstColumn); });
248 int lastColumn = sortedPC.front().firstColumn;
249 for (
auto it = sortedPC.begin() + 1; it != sortedPC.end(); ++it) {
250 if (it->firstColumn - (it - 1)->firstColumn != 1) {
257bool isInside(
double localX,
double localY,
const std::vector<PreCluster>& sortedPC, std::string& errorMsg)
259 std::stringstream ss;
260 ss <<
"Point: (" << localX <<
", " << localY <<
") outside PC:";
261 for (
auto& pc : sortedPC) {
264 ss <<
" area: x (" << area.getXmin() <<
", " << area.getXmax() <<
")";
265 ss <<
" y (" << area.getYmin() <<
", " << area.getYmax() <<
")";
266 if (localX >= area.getXmin() && localX <= area.getXmax() &&
267 localY >= area.getYmin() && localY <= area.getYmax()) {
277 std::stringstream
debug;
278 for (
size_t igen = 0; igen < genTracks.size(); ++igen) {
279 debug <<
"Gen: " << genTracks[igen].track <<
"\n hits:\n";
280 for (
auto& hit : genTracks[igen].hits) {
281 debug <<
" " << hit <<
"\n";
283 debug <<
" clusters:\n";
285 bool matches =
false;
287 if (
label.getTrackID() == igen) {
300 debug <<
" clusters:\n";
301 for (
int ich = 0; ich < 4; ++ich) {
302 int icl = tracker.
getTracks()[itrack].getClusterMatched(ich);
303 debug <<
" icl: " << icl;
307 debug <<
" ID: " <<
label.getTrackID() <<
" fires: [" <<
label.isFiredBP() <<
", " <<
label.isFiredNBP() <<
"]";
323 std::vector<int> deList = {2, 3, 4, 5, 6, 20, 21, 22, 23, 24, 47, 48, 49, 50, 51, 65, 66, 67, 68, 69};
327BOOST_AUTO_TEST_SUITE(o2_mid_simulation)
333 std::vector<std::vector<ColumnData>> digitsCollection;
334 std::vector<o2::dataformats::MCTruthContainer<MCLabel>> mcContainerCollection;
335 std::vector<ColumnData>
digits;
337 std::vector<ROFRecord> rofRecords;
338 for (
size_t ievent = 0; ievent <
nEvents; ++ievent) {
341 digitsCollection.push_back({});
342 mcContainerCollection.push_back({});
343 simDigitizer.
digitizer.
process(hits, digitsCollection.back(), mcContainerCollection.back());
345 std::copy(digitsCollection.back().begin(), digitsCollection.back().end(), std::back_inserter(
digits));
346 mcContainer.
mergeAtBack(mcContainerCollection.back());
351 auto rofMCIt = rofRecords.begin();
355 BOOST_TEST(rofIt->interactionRecord == rofMCIt->interactionRecord);
356 BOOST_TEST(
static_cast<int>(rofIt->eventType) ==
static_cast<int>(rofMCIt->eventType));
358 BOOST_TEST(rofIt->nEntries <= rofMCIt->nEntries);
367 std::vector<ColumnData> digitStoreMC;
369 std::vector<ROFRecord> rofRecords;
374 for (
size_t idig = 0; idig <
digitLabelsMC.getIndexedSize(); ++idig) {
376 auto digit = digitStoreMC[idig];
378 for (
auto label : labels) {
379 std::string errorMessage;
393 for (
auto digit : digitStoreMC) {
394 bool isMergedDigit =
false;
396 if (digit.deId ==
col.deId && digit.columnId ==
col.columnId) {
398 isMergedDigit =
true;
400 for (
int iline = 0; iline < 4; ++iline) {
401 BOOST_TEST(((digit.getBendPattern(iline) &
col.getBendPattern(iline)) == digit.getBendPattern(iline)));
403 BOOST_TEST(((digit.getNonBendPattern() &
col.getNonBendPattern()) == digit.getNonBendPattern()));
423 std::vector<ColumnData> digitStoreMC;
425 std::vector<ROFRecord> rofRecords;
427 for (
int ievent = 0; ievent < 100; ++ievent) {
429 std::stringstream ss;
430 int nGenClusters = 1, nRecoClusters = 0;
438 ss <<
"nRecoClusters: " << nRecoClusters <<
" nGenClusters: " << nGenClusters <<
"\n";
442 ss <<
"\n Clusters:\n";
452 BOOST_TEST((nRecoClusters == nGenClusters), ss.str());
454 BOOST_TEST((nRecoClusters >= nGenClusters && nRecoClusters <= nColumns), ss.str());
464 std::vector<ColumnData> digitStoreMC, digitsAccum;
467 std::vector<std::vector<Hit>> hitsCollection;
469 for (
int ievent = 0; ievent < 100; ++ievent) {
471 hitsCollection.emplace_back(hits);
474 std::copy(digitStoreMC.begin(), digitStoreMC.end(), std::back_inserter(digitsAccum));
485 for (
size_t ievent = 0; ievent < hitsCollection.size(); ++ievent) {
486 for (
auto& hit : hitsCollection[ievent]) {
493 std::string errorMsg;
510 bool isInLabels =
false;
512 if (
label.compare(pcLabel) == 1) {
525BOOST_DATA_TEST_CASE(MID_SimTracks, boost::unit_test::data::make({1, 2, 3, 4, 5, 6, 7, 8, 9}), nTracks)
538 std::vector<ColumnData> digitStoreMC, digitsAccum;
554 for (
size_t ievent = 0; ievent < 100; ++ievent) {
556 std::vector<Hit> hits;
557 for (
auto& genTrack : genTracks) {
558 std::copy(genTrack.hits.begin(), genTrack.hits.end(), std::back_inserter(hits));
559 if (genTrack.isReconstructible()) {
567 std::copy(digitStoreMC.begin(), digitStoreMC.end(), std::back_inserter(digitsAccum));
590 std::string debugInfo =
"";
594 for (
size_t itrack = firstTrack; itrack < firstTrack + nTracks; ++itrack) {
596 bool checkReco =
false;
597 if (
label.isFake()) {
600 for (
auto&
id :
ids) {
601 if (
label.getTrackID() ==
id) {
613 std::stringstream ss;
614 ss <<
"Gen ID: " << igen <<
" isReconstructible: " <<
genTrackCollection[ievent][igen].isReconstructible() <<
" != isReco " << isReco;
615 if (debugInfo.empty()) {
624 for (
size_t itrack = firstTrack; itrack < firstTrack + nTracks; ++itrack) {
626 if (
label.isEmpty()) {
630 if (
label.isFake()) {
641 for (
int ich = 0; ich < 4; ++ich) {
642 int trClusIdx = simTracking.
tracker.
getTracks()[itrack].getClusterMatched(ich);
646 for (
auto& trClusterLabel : simTracking.trackLabeler.getTrackClustersLabels().
getLabels(trClusIdx)) {
647 if (trClusterLabel.getTrackID() ==
label.getTrackID()) {
661BOOST_AUTO_TEST_SUITE_END()
Parameters for MID RPC response.
Strip pattern (aka digits)
Header to collect LHC related constants.
Cluster reconstruction algorithm for MID.
Track reconstruction algorithm for MID.
Pre-clusters helper for MID.
PreClusterLabeler for MID.
Pre-cluster reconstruction algorithm for MID.
Fast track generator for MID.
double getParB(int cathode, int deId) const
void process(gsl::span< const PreCluster > preClusters, const o2::dataformats::MCTruthContainer< MCCompLabel > &inMCContainer, gsl::span< const Cluster > clusters, gsl::span< const std::array< size_t, 2 > > correlations)
const o2::dataformats::MCTruthContainer< MCClusterLabel > & getContainer()
Clusterizing algorithm for MID.
const std::vector< Cluster > & getClusters()
Gets the vector of reconstructed clusters.
const std::vector< ROFRecord > & getROFRecords()
Gets the vector of clusters RO frame records.
bool init(std::function< void(size_t, size_t)> func=[](size_t, size_t) {})
void process(gsl::span< const PreCluster > preClusters, bool accumulate=false)
void process(const std::vector< Hit > &hits, std::vector< ColumnData > &digitStore, o2::dataformats::MCTruthContainer< MCLabel > &mcContainer)
const std::vector< ColumnData > & getColumnData() const
Gets the merged column data.
void process(const std::vector< ColumnData > &inDigitStore, const o2::dataformats::MCTruthContainer< MCLabel > &inMCContainer, const std::vector< ROFRecord > &inROFRecords, bool mergeInBunchPileup=true)
Merges the MC digits that are provided per hit into the format that we expect from data.
const o2::dataformats::MCTruthContainer< MCLabel > & getMCContainer() const
Gets the merged MC labels.
const std::vector< ROFRecord > & getROFRecords() const
Gets the merged RO frame records.
Class to find the impact point of a track on the chamber.
std::vector< Cluster > getLocalPositions(const Track &track, int chamber, bool withUncertainties=false) const
static int getStrip(int strip, int line)
Gets the strip.
MpStripIndex stripByPosition(double xPos, double yPos, int cathode, int deId, bool warn=true) const
MpArea getArea(const PreCluster &pc) const
const o2::dataformats::MCTruthContainer< MCCompLabel > & getContainer()
void process(gsl::span< const PreCluster > preClusters, const o2::dataformats::MCTruthContainer< MCLabel > &inMCContainer, gsl::span< const ROFRecord > rofRecordsPC, gsl::span< const ROFRecord > rofRecordsData)
Pre-clustering algorithm for MID.
const std::vector< ROFRecord > & getROFRecords()
Gets the vector of pre-clusters RO frame records.
void process(gsl::span< const ColumnData > stripPatterns, bool accumulate=false)
const std::vector< PreCluster > & getPreClusters()
Gets the vector of reconstructed pre-clusters.
Class to generate tracks for MID.
std::vector< Track > generate()
void setSeed(unsigned int seed)
Sets the seed.
const o2::dataformats::MCTruthContainer< MCClusterLabel > & getTrackClustersLabels()
Returns the cluster labels.
void process(gsl::span< const Cluster > clusters, gsl::span< const Track > tracks, const o2::dataformats::MCTruthContainer< MCClusterLabel > &inMCContainer)
const std::vector< MCCompLabel > & getTracksLabels()
Returns the tracks labels.
This class defines the MID track.
Tracking algorithm for MID.
const std::vector< ROFRecord > & getClusterROFRecords()
Gets the vector of cluster RO frame records.
bool init(bool keepAll=false)
void process(gsl::span< const Cluster > clusters, bool accumulate=false)
const std::vector< Cluster > & getClusters()
Gets the array of associated clusters.
float getSigmaCut() const
Gets number of sigmas for cuts.
const std::vector< Track > & getTracks()
Gets the array of reconstructes tracks.
const std::vector< ROFRecord > & getTrackROFRecords()
Gets the vector of tracks RO frame records.
GLenum const GLfloat * params
GLuint GLsizei const GLchar * label
constexpr double LHCBunchSpacingNS
o2::track::TrackParCov Track
std::unique_ptr< const o2::dataformats::MCTruthContainer< MCLabel > > getLabels(framework::ProcessingContext &pc, std::string_view dataBind)
BOOST_TEST_MESSAGE("Fraction of fake tracks: "<<(double) nTotFakes/(double) nTotReconstructible)
std::vector< int > getDEList()
std::vector< std::vector< GenTrack > > genTrackCollection
unsigned long int nReconstructible
std::vector< ROFRecord > digitsROF
ChamberResponseParams createDefaultChamberResponseParams()
o2::dataformats::MCTruthContainer< MCLabel > digitLabelsAccum
bool checkLabel(const ColumnData &digit, MCLabel &label, std::string &errorMessage)
Digitizer createDefaultDigitizer()
ChamberEfficiencyResponse createDefaultChamberEfficiencyResponse()
std::vector< ColumnData > getColumnDataNonMC(const o2::mid::DigitsMerger &dm)
BOOST_DATA_TEST_CASE(MID_DigitMerger, boost::unit_test::data::make(getDEList()), deId)
std::string getDebugInfo(const std::vector< GenTrack > &genTracks, Tracker &tracker, TrackLabeler &trackLabeler, const ROFRecord &rofTrack, const ROFRecord &rofCluster)
std::vector< size_t > getCompatibleGenTrackIds(size_t igen, const std::vector< GenTrack > &genTracks)
bool isInside(double localX, double localY, const std::vector< PreCluster > &sortedPC, std::string &errorMsg)
ChamberHV createDefaultChamberHV()
Creates the default chamber voltages.
std::vector< Hit > generateHits(size_t nHits, int deId, const Mapping &mapping, const GeometryTransformer geoTrans)
std::uniform_real_distribution< float > distX(-127.5, 127.5)
o2::dataformats::MCTruthContainer< MCLabel > digitLabelsMC
unsigned long int nUntagged
std::uniform_real_distribution< float > distY(-68., 68.)
Digitizer createDigitizerNoClusterSize()
std::vector< GenTrack > generateTracks(int nTracks)
BOOST_TEST(clusters.size()==clusterizer.getClusters().size())
GeometryTransformer createDefaultTransformer()
std::vector< Cluster > clusters
bool isContiguous(const std::vector< PreCluster > &sortedPC)
gsl::span< const PreCluster > preClusters(preClusterizer.getPreClusters().data(), preClusterizer.getPreClusters().size())
unsigned long int nTaggedNonCompatible
std::vector< PreCluster > getRelatedPreClusters(const Hit &hit, int cathode, const std::vector< PreCluster > &preClusters, const o2::dataformats::MCTruthContainer< MCCompLabel > &labels, const ROFRecord &rofRecord)
a couple of static helper functions to create timestamp values for CCDB queries or override obsolete ...
Column data structure for MID.
uint8_t columnId
Column in DE.
bool isStripFired(int istrip, int cathode, int line) const
uint8_t deId
Index of the detection element.
bool isValid()
Check if Strip is Valid.
GeometryTransformer geoTrans
PreClusterHelper preClusterHelper
std::vector< std::array< size_t, 2 > > correlation
PreClusterLabeler preClusterLabeler
PreClusterizer preClusterizer
ClusterLabeler clusterLabeler
ChamberResponseParams params
Digitizer digitizerNoClusterSize
DigitsMerger digitsMerger
TrackLabeler trackLabeler
std::vector< Digit > digits