Skip to content

Commit e38c5f2

Browse files
committed
Add the script to check hits and clusters on a track
1 parent f6b3525 commit e38c5f2

File tree

4 files changed

+786
-50
lines changed

4 files changed

+786
-50
lines changed

Detectors/Upgrades/ITS3/base/include/ITS3Base/SegmentationMosaix.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ class SegmentationMosaix
7777
static constexpr float PitchCol{constants::pixelarray::pixels::mosaix::pitchZ};
7878
static constexpr float PitchRow{constants::pixelarray::pixels::mosaix::pitchX};
7979
static constexpr float SensorLayerThickness{constants::totalThickness};
80-
static constexpr float NominalYShift{constants::nominalYShift};
80+
static constexpr float NominalYShift{0.0f};
8181

8282
/// Transformation from the curved surface to a flat surface.
8383
/// Additionally a shift in the flat coordinates must be applied because

Detectors/Upgrades/ITS3/macros/test/CompareClustersAndDigitsOnChip.C

Lines changed: 149 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,9 @@
2626
#include <TTree.h>
2727
#include <filesystem>
2828
#include <fstream>
29+
#include <regex>
30+
#include <set>
31+
#include <map>
2932
#endif
3033

3134
#define ENABLE_UPGRADES
@@ -76,7 +79,7 @@ struct Data {
7679

7780
void CompareClustersAndDigitsOnChip(std::string clusfile = "o2clus_its.root",
7881
std::string digifile = "it3digits.root",
79-
std::string dictfile = "IT3dictionary.root",
82+
std::string dictfile = "",
8083
std::string hitfile = "o2sim_HitsIT3.root",
8184
std::string inputGeom = "o2sim_geometry.root",
8285
bool batch = true)
@@ -109,6 +112,90 @@ void CompareClustersAndDigitsOnChip(std::string clusfile = "o2clus_its.root",
109112
o2::math_utils::TransformType::L2G)); // request cached transforms
110113
const int nChips = gman->getNumberOfChips();
111114

115+
LOGP(info, "Total number of chips is {} in ITS3 (IB and OB)", nChips);
116+
117+
// Create all plots
118+
LOGP(info, "Selecting chips to be visualised");
119+
std::set<int> selectedChips;
120+
std::map<std::string, std::vector<int>> chipGroups;
121+
122+
for (int chipID{0}; chipID < nChips; ++chipID) {
123+
TString tpath = gman->getMatrixPath(chipID);
124+
std::string path = tpath.Data();
125+
126+
std::vector<std::string> tokens;
127+
std::istringstream iss(path);
128+
std::string token;
129+
while (std::getline(iss, token, '/')) {
130+
if (!token.empty()) {
131+
tokens.push_back(token);
132+
}
133+
}
134+
135+
std::string segmentName, staveName, carbonFormName;
136+
for (const auto& t : tokens) {
137+
if (t.find("ITS3Segment") != std::string::npos) segmentName = t;
138+
if (t.find("ITSUStave") != std::string::npos) staveName = t;
139+
if (t.find("ITS3CarbonForm") != std::string::npos) carbonFormName = t;
140+
}
141+
142+
std::string groupKey;
143+
if (!segmentName.empty()) {
144+
groupKey = segmentName + "_" + carbonFormName;
145+
} else if (!staveName.empty()) {
146+
groupKey = staveName;
147+
} else {
148+
continue;
149+
}
150+
151+
chipGroups[groupKey].push_back(chipID);
152+
}
153+
154+
LOGP(info, "From each IB Segment or OB Stave, 10 chipIDs are uniformly selected");
155+
LOGP(info, "Selected chipID: ");
156+
for (auto& [groupName, ids] : chipGroups) {
157+
std::vector<int> sampled;
158+
if (ids.size() <= 10) {
159+
for (auto id : ids) {
160+
selectedChips.insert(id);
161+
sampled.push_back(id);
162+
}
163+
} else {
164+
for (int i{0}; i < 10; ++i) {
165+
int idx = i * (ids.size() - 1) / 9; // 9 intervals for 10 points
166+
int id = ids[idx];
167+
if (selectedChips.insert(id).second) {
168+
sampled.push_back(id);
169+
}
170+
}
171+
}
172+
173+
std::ostringstream oss;
174+
std::string topOrBot = "N/A";
175+
std::smatch match;
176+
std::regex rgxSegment(R"(Segment(\d+)_(\d+)_ITS3CarbonForm\d+_(\d+))");
177+
std::regex rgxStave(R"(Stave(\d+)_(\d+))");
178+
if (std::regex_search(groupName, match, rgxSegment)) {
179+
int layer = std::stoi(match[1]);
180+
int segment = std::stoi(match[2]);
181+
int carbonForm = std::stoi(match[3]);
182+
topOrBot = (carbonForm == 0 ? "TOP" : "BOT");
183+
oss << topOrBot << " segment " << segment << " at layer " << layer << ": ";
184+
} else if (std::regex_search(groupName, match, rgxStave)) {
185+
int layer = std::stoi(match[1]);
186+
int stave = std::stoi(match[2]);
187+
oss << "Stave " << stave << " at layer " << layer << ": ";
188+
} else {
189+
LOGP(error, "Cannot select the correct chipID in OB or IB");
190+
return;
191+
}
192+
for (auto id : sampled) {
193+
oss << id << " ";
194+
}
195+
LOG(info) << oss.str();
196+
}
197+
LOGP(info, "{} selected chips will be visualized and analyzed.", chipGroups.size());
198+
112199
// Hits
113200
TFile fileH(hitfile.data());
114201
auto* hitTree = dynamic_cast<TTree*>(fileH.Get("o2sim"));
@@ -198,12 +285,15 @@ void CompareClustersAndDigitsOnChip(std::string clusfile = "o2clus_its.root",
198285

199286
// Create all plots
200287
LOGP(info, "Creating plots");
201-
std::vector<Data> data(nChips);
202-
for (int iChip{0}; iChip < nChips; ++iChip) {
203-
auto& dat = data[iChip];
288+
std::unordered_map<int, Data> data;
289+
auto initData = [&](int chipID, Data& dat) {
290+
if (dat.pixelArray) return;
291+
204292
int nCol{0}, nRow{0};
205293
float lengthPixArr{0}, widthPixArr{0};
206-
if (o2::its3::constants::detID::isDetITS3(iChip)) {
294+
bool isIB = o2::its3::constants::detID::isDetITS3(chipID);
295+
int layer = gman->getLayer(chipID);
296+
if (isIB) {
207297
nCol = o2::its3::SegmentationMosaix::NCols;
208298
nRow = o2::its3::SegmentationMosaix::NRows;
209299
lengthPixArr = o2::its3::constants::pixelarray::pixels::mosaix::pitchZ * nCol;
@@ -214,44 +304,40 @@ void CompareClustersAndDigitsOnChip(std::string clusfile = "o2clus_its.root",
214304
lengthPixArr = o2::itsmft::SegmentationAlpide::PitchCol * nCol;
215305
widthPixArr = o2::itsmft::SegmentationAlpide::PitchRow * nRow;
216306
}
217-
218-
dat.pixelArray = new TH2F(Form("histSensor_%d", iChip), Form("SensorID=%d;z(cm);x(cm)", iChip),
307+
308+
dat.pixelArray = new TH2F(Form("histSensor_%d", chipID), Form("SensorID=%d;z(cm);x(cm)", chipID),
219309
nCol, -0.5 * lengthPixArr, 0.5 * lengthPixArr,
220310
nRow, -0.5 * widthPixArr, 0.5 * widthPixArr);
221311
dat.hitS = new TGraph();
222312
dat.hitS->SetMarkerStyle(kFullTriangleDown);
223313
dat.hitS->SetMarkerColor(kGreen);
224-
dat.hitS->SetEditable(kFALSE);
225314
dat.hitM = new TGraph();
226315
dat.hitM->SetMarkerStyle(kFullCircle);
227316
dat.hitM->SetMarkerColor(kGreen + 3);
228-
dat.hitM->SetEditable(kFALSE);
229317
dat.hitE = new TGraph();
230318
dat.hitE->SetMarkerStyle(kFullTriangleUp);
231319
dat.hitE->SetMarkerColor(kGreen + 5);
232-
dat.hitE->SetEditable(kFALSE);
233-
dat.clusS = new TGraph(1);
320+
dat.clusS = new TGraph();
234321
dat.clusS->SetMarkerStyle(kFullSquare);
235322
dat.clusS->SetMarkerColor(kBlue);
236-
dat.clusS->SetEditable(kFALSE);
237-
dat.cog = new TGraph(1);
323+
dat.cog = new TGraph();
238324
dat.cog->SetMarkerStyle(kFullDiamond);
239325
dat.cog->SetMarkerColor(kRed);
240-
dat.cog->SetEditable(kFALSE);
241326
dat.leg = new TLegend(0.7, 0.7, 0.92, 0.92);
242327
dat.leg->AddEntry(dat.hitS, "Hit Start");
243328
dat.leg->AddEntry(dat.hitM, "Hit Middle");
244329
dat.leg->AddEntry(dat.hitE, "Hit End");
245330
dat.leg->AddEntry(dat.clusS, "Cluster Start");
246331
dat.leg->AddEntry(dat.cog, "Cluster COG");
247332
dat.vClusBox = new std::vector<TBox*>;
248-
}
333+
};
249334

250335
LOGP(info, "Filling digits");
251336
for (int iDigit{0}; digTree->LoadTree(iDigit) >= 0; ++iDigit) {
252337
digTree->GetEntry(iDigit);
253338
for (const auto& digit : *digArr) {
254339
const auto chipID = digit.getChipIndex();
340+
if (!selectedChips.count(chipID)) continue;
255341
const auto layer = gman->getLayer(chipID);
256342
bool isIB = layer < 3;
257343
float locDigiX{0}, locDigiZ{0};
@@ -260,14 +346,16 @@ void CompareClustersAndDigitsOnChip(std::string clusfile = "o2clus_its.root",
260346
} else {
261347
o2::itsmft::SegmentationAlpide::detectorToLocal(digit.getRow(), digit.getColumn(), locDigiX, locDigiZ);
262348
}
349+
auto& dat = data[chipID];
350+
initData(chipID, dat);
263351
data[chipID].pixelArray->Fill(locDigiZ, locDigiX);
264352
}
265353
}
266354

267355
LOGP(info, "Building min and max MC events used by each ROF, total ROFs {}", nROFRec);
268356
auto pattIt = patternsPtr->cbegin();
269357
bool isAllPattIDInvaild{true};
270-
for (unsigned int irof = 0; irof < nROFRec; irof++) {
358+
for (unsigned int irof{0}; irof < nROFRec; irof++) {
271359
const auto& rofRec = rofRecVec[irof];
272360
// >> read and map MC events contributing to this ROF
273361
for (int im = mcEvMin[irof]; im <= mcEvMax[irof]; im++) {
@@ -285,14 +373,39 @@ void CompareClustersAndDigitsOnChip(std::string clusfile = "o2clus_its.root",
285373
}
286374

287375
// Clusters in this ROF
288-
for (int icl = 0; icl < rofRec.getNEntries(); icl++) {
376+
for (int icl{0}; icl < rofRec.getNEntries(); icl++) {
289377
int clEntry = rofRec.getFirstEntry() + icl; // entry of icl-th cluster of this ROF in the vector of clusters
290378
const auto& cluster = (*clusArr)[clEntry];
291379
const auto chipID = cluster.getSensorID();
380+
if (!selectedChips.count(chipID)) {
381+
// Even if not selected, advance pattIt if patternID is InvalidPatternID
382+
if (cluster.getPatternID() == o2::itsmft::CompCluster::InvalidPatternID) {
383+
o2::itsmft::ClusterPattern::skipPattern(pattIt);
384+
}
385+
continue;
386+
}
292387
const auto pattID = cluster.getPatternID();
293388
const bool isIB = o2::its3::constants::detID::isDetITS3(chipID);
294389
const auto layer = gman->getLayer(chipID);
390+
auto& dat = data[chipID];
391+
initData(chipID, dat);
295392
o2::itsmft::ClusterPattern pattern;
393+
// Pattern extraction
394+
if (cluster.getPatternID() != o2::itsmft::CompCluster::InvalidPatternID) {
395+
isAllPattIDInvaild = false;
396+
if (!hasAvailableDict) {
397+
LOGP(error, "Encountered pattern ID {}, which is not equal to the invalid pattern ID {}", cluster.getPatternID(), o2::itsmft::CompCluster::InvalidPatternID);
398+
LOGP(error, "Clusters have already been generated with a dictionary which was not provided properly!");
399+
return;
400+
}
401+
if (dict.isGroup(cluster.getPatternID(), isIB)) {
402+
pattern.acquirePattern(pattIt);
403+
} else {
404+
pattern = dict.getPattern(cluster.getPatternID(), isIB);
405+
}
406+
} else {
407+
pattern.acquirePattern(pattIt);
408+
}
296409

297410
// Hits
298411
const auto& lab = (clusLabArr->getLabels(clEntry))[0];
@@ -332,30 +445,17 @@ void CompareClustersAndDigitsOnChip(std::string clusfile = "o2clus_its.root",
332445
}
333446
data[chipID].clusS->AddPoint(locCluZ, locCluX);
334447

335-
// Pattern extraction
336-
if (cluster.getPatternID() != o2::itsmft::CompCluster::InvalidPatternID) {
337-
isAllPattIDInvaild = false;
338-
if (!hasAvailableDict) {
339-
LOGP(error, "Encountered pattern ID {}, which is not equal to the invalid pattern ID {}", cluster.getPatternID(), o2::itsmft::CompCluster::InvalidPatternID);
340-
LOGP(error, "Clusters have already been generated with a dictionary which was not provided properly!");
341-
return;
342-
}
343-
if (dict.isGroup(cluster.getPatternID(), isIB)) {
344-
pattern.acquirePattern(pattIt);
345-
} else {
346-
pattern = dict.getPattern(cluster.getPatternID(), isIB);
347-
}
348-
} else {
349-
pattern.acquirePattern(pattIt);
350-
}
351-
352448
// COG
353449
o2::math_utils::Point3D<float> locCOG;
354450
// Cluster COG using dictionary (if available)
355451
if (hasAvailableDict && (pattID != o2::itsmft::CompCluster::InvalidPatternID && !dict.isGroup(pattID, isIB))) {
356452
locCOG = dict.getClusterCoordinates(cluster);
357453
} else {
358-
locCOG = o2::itsmft::TopologyDictionary::getClusterCoordinates(cluster, pattern, false);
454+
if(isIB) {
455+
locCOG = o2::its3::TopologyDictionary::getClusterCoordinates(cluster, pattern, false);
456+
} else {
457+
locCOG = o2::itsmft::TopologyDictionary::getClusterCoordinates(cluster, pattern, false);
458+
}
359459
}
360460
if (isIB) {
361461
float flatX{0}, flatY{0};
@@ -402,15 +502,16 @@ void CompareClustersAndDigitsOnChip(std::string clusfile = "o2clus_its.root",
402502
return;
403503
}
404504
}
405-
505+
406506
LOGP(info, "Writing to root file");
407507
double x1, y1, x2, y2;
408508
auto oFileOut = TFile::Open("CompareClustersAndDigitsOnChip.root", "RECREATE");
409509
oFileOut->cd();
410-
for (int iChip = 0; iChip < 4000; ++iChip) {
411-
auto& dat = data[iChip];
412-
auto path = gman->getMatrixPath(iChip);
413-
const std::string cpath{path.Data() + 39, path.Data() + path.Length()};
510+
for (int chipID{0}; chipID < nChips ; chipID++) {
511+
if (!selectedChips.count(chipID)) continue;
512+
auto& dat = data[chipID];
513+
TString tpath = gman->getMatrixPath(chipID);
514+
const std::string cpath{tpath.Data() + 39, tpath.Data() + tpath.Length()};
414515
const std::filesystem::path p{cpath};
415516
std::string nestedDir = p.parent_path().string();
416517
TDirectory* currentDir = oFileOut;
@@ -431,12 +532,12 @@ void CompareClustersAndDigitsOnChip(std::string clusfile = "o2clus_its.root",
431532
currentDir->cd();
432533
}
433534
if (!currentDir) {
434-
LOGP(error, "Failed to create nested directory for chip %d", iChip);
535+
LOGP(error, "Failed to create nested directory for chip %d", chipID);
435536
continue;
436537
}
437-
438-
auto canv = new TCanvas(Form("%s_%d", p.filename().c_str(), iChip));
439-
canv->SetTitle(Form("%s_%d", p.filename().c_str(), iChip));
538+
539+
auto canv = new TCanvas(Form("%s_%d", p.filename().c_str(), chipID));
540+
canv->SetTitle(Form("%s_%d", p.filename().c_str(), chipID));
440541
canv->cd();
441542
gPad->SetGrid(1, 1);
442543
dat.pixelArray->Draw("colz");
@@ -445,7 +546,7 @@ void CompareClustersAndDigitsOnChip(std::string clusfile = "o2clus_its.root",
445546
dat.hitE->Draw("p;same");
446547
auto arr = new TArrow();
447548
arr->SetArrowSize(0.01);
448-
for (int i = 0; i < dat.hitS->GetN(); ++i) {
549+
for (int i{0}; i < dat.hitS->GetN(); ++i) {
449550
dat.hitS->GetPoint(i, x1, y1);
450551
dat.hitE->GetPoint(i, x2, y2);
451552
arr->DrawArrow(x1, y1, x2, y2);
@@ -458,15 +559,15 @@ void CompareClustersAndDigitsOnChip(std::string clusfile = "o2clus_its.root",
458559
}
459560
dat.leg->Draw();
460561
canv->SetEditable(false);
461-
562+
462563
currentDir->WriteTObject(canv, canv->GetName());
463564
dat.clear();
464565
delete canv;
465566
delete arr;
466-
printf("\rWriting chip %05d", iChip);
567+
printf("\rWriting chip %05d", chipID);
467568
}
468569
printf("\n");
469570
oFileOut->Write();
470571
oFileOut->Close();
471-
LOGP(info, "Finished!");
572+
LOGP(info, "Finished writing selected chip visualizations.");
472573
}

0 commit comments

Comments
 (0)