Skip to content

Commit feb58fa

Browse files
committed
Changes in ITS/MFT CreateDictionaries macros
Set default unique patternID threshold to 1e-6 Can process multiple TFs (not in MC mode) Can process data encoded with previous dictionary, in this case the dict. file must be providec.
1 parent 7f0f877 commit feb58fa

File tree

2 files changed

+197
-149
lines changed

2 files changed

+197
-149
lines changed

Detectors/ITSMFT/ITS/macros/test/CreateDictionaries.C

Lines changed: 97 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@
3333
#endif
3434

3535
void CreateDictionaries(bool saveDeltas = false,
36+
float probThreshold = 1e-6,
37+
std::string clusDictFile = "",
3638
std::string clusfile = "o2clus_its.root",
3739
std::string hitfile = "o2sim_HitsITS.root",
3840
std::string collContextfile = "collisioncontext.root",
@@ -57,6 +59,11 @@ void CreateDictionaries(bool saveDeltas = false,
5759
std::unordered_map<int, int> hadronicMCMap; // mapping from MC event entry to hadronic event ID
5860
std::vector<HitVec*> hitVecPool;
5961
std::vector<MC2HITS_map> mc2hitVec;
62+
o2::itsmft::TopologyDictionary clusDictOld;
63+
if (!clusDictFile.empty()) {
64+
clusDictOld.readFromFile(clusDictFile);
65+
LOGP(info, "Loaded external cluster dictionary with {} entries from {}", clusDictOld.getSize(), clusDictFile);
66+
}
6067

6168
TFile* fout = nullptr;
6269
TNtuple* nt = nullptr;
@@ -132,6 +139,10 @@ void CreateDictionaries(bool saveDeltas = false,
132139
clusTree->SetBranchAddress("ITSClustersMC2ROF", &mc2rofVecP);
133140
}
134141
clusTree->GetEntry(0);
142+
if (clusTree->GetEntries() > 1 && !hitfile.empty()) {
143+
LOGP(error, "Hits are provided but the cluster tree containes {} entries, looks like real data");
144+
return;
145+
}
135146

136147
// Topologies dictionaries: 1) all clusters 2) signal clusters only 3) noise clusters only
137148
BuildTopologyDictionary completeDictionary;
@@ -165,99 +176,112 @@ void CreateDictionaries(bool saveDeltas = false,
165176
}
166177
} // << build min and max MC events used by each ROF
167178

168-
auto pattIdx = patternsPtr->cbegin();
169-
for (int irof = 0; irof < nROFRec; irof++) {
170-
const auto& rofRec = rofRecVec[irof];
179+
for (Long64_t ient = 0; ient < clusTree->GetEntries(); ient++) {
180+
clusTree->GetEntry(ient);
181+
nROFRec = (int)rofRecVec.size();
182+
LOGP(info, "Processing TF {} with {} ROFs and {} clusters", ient, nROFRec, clusArr->size());
183+
auto pattIdx = patternsPtr->cbegin();
184+
for (int irof = 0; irof < nROFRec; irof++) {
185+
const auto& rofRec = rofRecVec[irof];
171186

172-
rofRec.print();
187+
// rofRec.print();
173188

174-
if (clusLabArr) { // >> read and map MC events contributing to this ROF
175-
for (int im = mcEvMin[irof]; im <= mcEvMax[irof]; im++) {
176-
if (!hitVecPool[im]) {
177-
hitTree->SetBranchAddress("ITSHit", &hitVecPool[im]);
178-
hitTree->GetEntry(im);
179-
auto& mc2hit = mc2hitVec[im];
180-
const auto* hitArray = hitVecPool[im];
181-
for (int ih = hitArray->size(); ih--;) {
182-
const auto& hit = (*hitArray)[ih];
183-
uint64_t key = (uint64_t(hit.GetTrackID()) << 32) + hit.GetDetectorID();
184-
mc2hit.emplace(key, ih);
189+
if (clusLabArr) { // >> read and map MC events contributing to this ROF
190+
for (int im = mcEvMin[irof]; im <= mcEvMax[irof]; im++) {
191+
if (!hitVecPool[im]) {
192+
hitTree->SetBranchAddress("ITSHit", &hitVecPool[im]);
193+
hitTree->GetEntry(im);
194+
auto& mc2hit = mc2hitVec[im];
195+
const auto* hitArray = hitVecPool[im];
196+
for (int ih = hitArray->size(); ih--;) {
197+
const auto& hit = (*hitArray)[ih];
198+
uint64_t key = (uint64_t(hit.GetTrackID()) << 32) + hit.GetDetectorID();
199+
mc2hit.emplace(key, ih);
200+
}
185201
}
186202
}
187-
}
188-
} // << cache MC events contributing to this ROF
203+
} // << cache MC events contributing to this ROF
189204

190-
for (int icl = 0; icl < rofRec.getNEntries(); icl++) {
191-
int clEntry = rofRec.getFirstEntry() + icl; // entry of icl-th cluster of this ROF in the vector of clusters
192-
// do we read MC data?
205+
for (int icl = 0; icl < rofRec.getNEntries(); icl++) {
206+
int clEntry = rofRec.getFirstEntry() + icl; // entry of icl-th cluster of this ROF in the vector of clusters
207+
// do we read MC data?
193208

194-
const auto& cluster = (*clusArr)[clEntry];
209+
const auto& cluster = (*clusArr)[clEntry];
210+
o2::itsmft::ClusterPattern pattern;
195211

196-
if (cluster.getPatternID() != CompCluster::InvalidPatternID) {
197-
LOG(warning) << "Encountered patternID = " << cluster.getPatternID() << " != " << CompCluster::InvalidPatternID;
198-
LOG(warning) << "Clusters have already been generated with a dictionary! Quitting";
199-
return;
200-
}
201-
202-
ClusterTopology topology;
203-
o2::itsmft::ClusterPattern pattern(pattIdx);
204-
topology.setPattern(pattern);
212+
if (cluster.getPatternID() != CompCluster::InvalidPatternID) {
213+
if (clusDictOld.getSize() == 0) {
214+
LOG(error) << "Encountered patternID = " << cluster.getPatternID() << " != " << CompCluster::InvalidPatternID;
215+
LOG(error) << "Clusters have already been generated with a dictionary which was not provided";
216+
return;
217+
}
218+
if (clusDictOld.isGroup(cluster.getPatternID())) {
219+
pattern.acquirePattern(pattIdx);
220+
} else {
221+
pattern = clusDictOld.getPattern(cluster.getPatternID());
222+
}
223+
} else {
224+
pattern.acquirePattern(pattIdx);
225+
}
226+
ClusterTopology topology;
227+
topology.setPattern(pattern);
205228

206-
float dX = BuildTopologyDictionary::IgnoreVal, dZ = BuildTopologyDictionary::IgnoreVal;
207-
if (clusLabArr) {
208-
const auto& lab = (clusLabArr->getLabels(clEntry))[0];
209-
auto srcID = lab.getSourceID();
210-
if (lab.isValid() && srcID != QEDSourceID) { // use MC truth info only for non-QED and non-noise clusters
211-
auto trID = lab.getTrackID();
212-
const auto& mc2hit = mc2hitVec[lab.getEventID()];
213-
const auto* hitArray = hitVecPool[lab.getEventID()];
214-
Int_t chipID = cluster.getSensorID();
215-
uint64_t key = (uint64_t(trID) << 32) + chipID;
216-
auto hitEntry = mc2hit.find(key);
217-
if (hitEntry != mc2hit.end()) {
218-
const auto& hit = (*hitArray)[hitEntry->second];
219-
if (minPtMC < 0.f || hit.GetMomentum().Perp2() > minPtMC2) {
220-
auto locH = gman->getMatrixL2G(chipID) ^ (hit.GetPos()); // inverse conversion from global to local
221-
auto locHsta = gman->getMatrixL2G(chipID) ^ (hit.GetPosStart());
222-
locH.SetXYZ(0.5 * (locH.X() + locHsta.X()), 0.5 * (locH.Y() + locHsta.Y()), 0.5 * (locH.Z() + locHsta.Z()));
223-
const auto locC = o2::itsmft::TopologyDictionary::getClusterCoordinates(cluster, pattern, false);
224-
dX = locH.X() - locC.X();
225-
dZ = locH.Z() - locC.Z();
226-
if (saveDeltas) {
227-
nt->Fill(topology.getHash(), dX, dZ);
228-
}
229-
if (checkOutliers > 0.) {
230-
if (std::abs(dX) > topology.getRowSpan() * o2::itsmft::SegmentationAlpide::PitchRow * checkOutliers ||
231-
std::abs(dZ) > topology.getColumnSpan() * o2::itsmft::SegmentationAlpide::PitchCol * checkOutliers) { // ignore outlier
232-
dX = dZ = BuildTopologyDictionary::IgnoreVal;
229+
float dX = BuildTopologyDictionary::IgnoreVal, dZ = BuildTopologyDictionary::IgnoreVal;
230+
if (clusLabArr) {
231+
const auto& lab = (clusLabArr->getLabels(clEntry))[0];
232+
auto srcID = lab.getSourceID();
233+
if (lab.isValid() && srcID != QEDSourceID) { // use MC truth info only for non-QED and non-noise clusters
234+
auto trID = lab.getTrackID();
235+
const auto& mc2hit = mc2hitVec[lab.getEventID()];
236+
const auto* hitArray = hitVecPool[lab.getEventID()];
237+
Int_t chipID = cluster.getSensorID();
238+
uint64_t key = (uint64_t(trID) << 32) + chipID;
239+
auto hitEntry = mc2hit.find(key);
240+
if (hitEntry != mc2hit.end()) {
241+
const auto& hit = (*hitArray)[hitEntry->second];
242+
if (minPtMC < 0.f || hit.GetMomentum().Perp2() > minPtMC2) {
243+
auto locH = gman->getMatrixL2G(chipID) ^ (hit.GetPos()); // inverse conversion from global to local
244+
auto locHsta = gman->getMatrixL2G(chipID) ^ (hit.GetPosStart());
245+
locH.SetXYZ(0.5 * (locH.X() + locHsta.X()), 0.5 * (locH.Y() + locHsta.Y()), 0.5 * (locH.Z() + locHsta.Z()));
246+
const auto locC = o2::itsmft::TopologyDictionary::getClusterCoordinates(cluster, pattern, false);
247+
dX = locH.X() - locC.X();
248+
dZ = locH.Z() - locC.Z();
249+
if (saveDeltas) {
250+
nt->Fill(topology.getHash(), dX, dZ);
251+
}
252+
if (checkOutliers > 0.) {
253+
if (std::abs(dX) > topology.getRowSpan() * o2::itsmft::SegmentationAlpide::PitchRow * checkOutliers ||
254+
std::abs(dZ) > topology.getColumnSpan() * o2::itsmft::SegmentationAlpide::PitchCol * checkOutliers) { // ignore outlier
255+
dX = dZ = BuildTopologyDictionary::IgnoreVal;
256+
}
233257
}
234258
}
259+
} else {
260+
printf("Failed to find MC hit entry for Tr:%d chipID:%d\n", trID, chipID);
261+
lab.print();
235262
}
263+
signalDictionary.accountTopology(topology, dX, dZ);
236264
} else {
237-
printf("Failed to find MC hit entry for Tr:%d chipID:%d\n", trID, chipID);
238-
lab.print();
265+
noiseDictionary.accountTopology(topology, dX, dZ);
239266
}
240-
signalDictionary.accountTopology(topology, dX, dZ);
241-
} else {
242-
noiseDictionary.accountTopology(topology, dX, dZ);
243267
}
268+
completeDictionary.accountTopology(topology, dX, dZ);
244269
}
245-
completeDictionary.accountTopology(topology, dX, dZ);
246-
}
247-
// clean MC cache for events which are not needed anymore
248-
if (clusLabArr) {
249-
int irfNext = irof;
250-
int limMC = irfNext == nROFRec ? hitVecPool.size() : mcEvMin[irfNext]; // can clean events up to this
251-
for (int imc = mcEvMin[irof]; imc < limMC; imc++) {
252-
delete hitVecPool[imc];
253-
hitVecPool[imc] = nullptr;
254-
mc2hitVec[imc].clear();
270+
// clean MC cache for events which are not needed anymore
271+
if (clusLabArr) {
272+
int irfNext = irof;
273+
int limMC = irfNext == nROFRec ? hitVecPool.size() : mcEvMin[irfNext]; // can clean events up to this
274+
for (int imc = mcEvMin[irof]; imc < limMC; imc++) {
275+
delete hitVecPool[imc];
276+
hitVecPool[imc] = nullptr;
277+
mc2hitVec[imc].clear();
278+
}
255279
}
256280
}
257281
}
258282
auto dID = o2::detectors::DetID::ITS;
259283

260-
completeDictionary.setThreshold(0.0001);
284+
completeDictionary.setThreshold(probThreshold);
261285
completeDictionary.groupRareTopologies();
262286
completeDictionary.printDictionaryBinary(o2::base::DetectorNameConf::getAlpideClusterDictionaryFileName(dID, ""));
263287
completeDictionary.printDictionary(o2::base::DetectorNameConf::getAlpideClusterDictionaryFileName(dID, "", "txt"));

0 commit comments

Comments
 (0)