Skip to content

Commit 90fb080

Browse files
author
Marcello Di Costanzo
committed
Fix cluster x COG computation + floating-point issue in stepping arithmetics
1 parent fb22569 commit 90fb080

8 files changed

Lines changed: 265 additions & 219 deletions

File tree

‎Detectors/Upgrades/ALICE3/IOTOF/base/include/IOTOFBase/Segmentation.h‎

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ namespace iotof
2727
{
2828

2929
/// Segmentation and response for pixels in inner and outer TOF of the ALICE 3 apparatus
30-
/// Questions to solve:
3130
class Segmentation
3231
{
3332
private:
@@ -204,10 +203,12 @@ inline bool Segmentation::localToDetector(float xRow, float zCol, int& iRow, int
204203
iRow = int(xRow / specsConfig.PitchRow);
205204
iCol = int(zCol / specsConfig.PitchCol);
206205
// check pixel passive region
206+
// if (specsConfig.PixelPassiveEdgeX > 1e-6 && specsConfig.PixelPassiveEdgeZ > 1e-6) {
207207
if (std::abs(xRow - (iRow + 0.5) * specsConfig.PitchRow) > (0.5 * specsConfig.PitchRow - specsConfig.PixelPassiveEdgeX) || std::abs(zCol - (iCol + 0.5) * specsConfig.PitchCol) > (0.5 * specsConfig.PitchCol - specsConfig.PixelPassiveEdgeZ)) {
208208
iRow = iCol = -1;
209209
return false;
210210
}
211+
// }
211212
return true;
212213
}
213214

‎Detectors/Upgrades/ALICE3/IOTOF/macros/CheckClustersIOTOF.C‎

Lines changed: 139 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151

5252
#define ENABLE_UPGRADES
5353

54-
void addTLines(float pitch)
54+
void addTLines(float pitchRow, float pitchCol)
5555
{
5656
// Add grid lines at multiples of pitch on the current pad
5757
if (!gPad)
@@ -66,20 +66,30 @@ void addTLines(float pitch)
6666

6767
// Calculate the first vertical line position (multiple of pitch)
6868
int nLinesX = 0;
69-
for (float x = xmin; x <= xmax && nLinesX < 1000; x += pitch, nLinesX++) {
70-
TLine* line = new TLine(x, ymin, x, ymax);
71-
line->SetLineStyle(2);
72-
line->SetLineColor(kGray);
73-
line->Draw("same");
69+
float xRow = 0.f;
70+
while (xRow > xmin) {
71+
TLine* lineNeg = new TLine(xRow, ymin, xRow, ymax);
72+
lineNeg->SetLineStyle(2);
73+
lineNeg->SetLineColor(kGray+3);
74+
lineNeg->Draw("same");
75+
TLine* linePos = new TLine(std::abs(xRow), ymin, std::abs(xRow), ymax);
76+
linePos->SetLineStyle(2);
77+
linePos->SetLineColor(kGray+3);
78+
linePos->Draw("same");
79+
xRow -= pitchRow / 2;
7480
}
7581

76-
// Calculate the first horizontal line position (multiple of pitch)
77-
int nLinesY = 0;
78-
for (float y = ymin; y <= ymax && nLinesY < 1000; y += pitch, nLinesY++) {
79-
TLine* line = new TLine(xmin, y, xmax, y);
80-
line->SetLineStyle(2);
81-
line->SetLineColor(kGray);
82-
line->Draw("same");
82+
float yCol = 0.f;
83+
while (yCol > ymin) {
84+
TLine* lineNeg = new TLine(xmin, yCol, xmax, yCol);
85+
lineNeg->SetLineStyle(2);
86+
lineNeg->SetLineColor(kGray+3);
87+
lineNeg->Draw("same");
88+
TLine* linePos = new TLine(xmin, std::abs(yCol), xmax, std::abs(yCol));
89+
linePos->SetLineStyle(2);
90+
linePos->SetLineColor(kGray+3);
91+
linePos->Draw("same");
92+
yCol -= pitchCol / 2;
8393
}
8494

8595
gPad->Modified();
@@ -108,7 +118,8 @@ void CheckClustersIOTOF(std::string clusfile = "tf3clusters.root",
108118
using ROFRec = o2::itsmft::ROFRecord;
109119
using MC2ROF = o2::itsmft::MC2ROFRecord;
110120
using HitVec = std::vector<Hit>;
111-
using MC2HITS_map = std::unordered_map<uint64_t, int>; // maps (track_ID<<16 + chip_ID) to entry in the hit vector
121+
// trackID + chipID --> eventID + hitIndex
122+
using MC2HITS_map = std::unordered_map<uint64_t, std::vector<int>>; // maps (track_ID<<16 + chip_ID) to entry in the hit vector
112123

113124
std::vector<HitVec*> hitVecPool;
114125
std::vector<MC2HITS_map> mc2hitVec;
@@ -180,120 +191,136 @@ void CheckClustersIOTOF(std::string clusfile = "tf3clusters.root",
180191
// << build min and max MC events used by each ROF
181192
auto pattIt = patternsPtr->cbegin();
182193
int invalidPattIDCounter{0};
183-
for (int irof = 0; irof < nROFRec; irof++) {
184-
const auto& rofRec = rofRecVec[irof];
185-
rofRec.print();
186-
187-
188-
// >> read and map MC events contributing to this ROF
189-
for (int im = 0; im <= nEvts; im++) {
190-
if (!hitVecPool[im]) {
191-
hitTree->SetBranchAddress("TF3Hit", &hitVecPool[im]);
192-
hitTree->GetEntry(im);
193-
auto& mc2hit = mc2hitVec[im];
194-
const auto* hitArray = hitVecPool[im];
195-
for (int ih = hitArray->size(); ih--;) {
196-
const auto& hit = (*hitArray)[ih];
197-
uint64_t key = (uint64_t(hit.GetTrackID()) << 32) + hit.GetDetectorID();
198-
mc2hit.emplace(key, ih);
199-
}
194+
// for (int irof = 0; irof < nROFRec; irof++) {
195+
const auto& rofRec = rofRecVec[0];
196+
rofRec.print();
197+
198+
// >> read and map MC events contributing to this ROF
199+
// for (int im = 0; im <= nEvts; im++) {
200+
for (int im = 0; im < nEvts; im++) {
201+
if (!hitVecPool[im]) {
202+
hitTree->SetBranchAddress("TF3Hit", &hitVecPool[im]);
203+
hitTree->GetEntry(im);
204+
auto& mc2hit = mc2hitVec[im];
205+
const auto* hitArray = hitVecPool[im];
206+
for (int ih = hitArray->size(); ih--;) {
207+
const auto& hit = (*hitArray)[ih];
208+
uint64_t key = (uint64_t(hit.GetTrackID()) << 32) + hit.GetDetectorID();
209+
mc2hit[key].push_back(ih);
200210
}
201211
}
212+
}
202213

203-
// << cache MC events contributing to this ROF
204-
for (int icl = 0; icl < rofRec.getNEntries(); icl++) {
205-
int clEntry = icl; // entry of icl-th cluster of this ROF in the vector of clusters
206-
std::cout << "Processing cluster " << icl << "/" << rofRec.getNEntries() << std::endl;
207-
const auto& cluster = (*clusArr)[clEntry];
208-
209-
float errX{0.f};
210-
float errZ{0.f};
211-
int npix = 0;
212-
uint16_t pattID = cluster.getPattern();
213-
uint8_t spanRow = cluster.getRowSpan();
214-
uint8_t spanCol = cluster.getColSpan();
215-
o2::math_utils::Point3D<float> locC;
216-
// std::cout << "CIAO1" << std::endl;
217-
if (pattID == o2::iotof::Cluster::InvalidPatternID) {
218-
invalidPattIDCounter++;
219-
continue;
220-
}
221-
// std::cout << "CIAO2" << std::endl;
222-
223-
uint32_t topoKey = TopologyClassifier::makeKey(spanRow, spanCol, pattID);
224-
errX = topoClassifier.getErrX(topoKey);
225-
errZ = topoClassifier.getErrZ(topoKey);
226-
npix = topoClassifier.getNPixels(topoKey);
227-
auto chipID = cluster.getSensorID();
228-
// std::cout << "CIAO3" << std::endl;
229-
230-
// Transformation to the local --> global
231-
locC = topoClassifier.getClusterCoordinates(cluster);
232-
// std::cout << "CIAO31" << std::endl;
233-
auto gloC = gman->getMatrixL2G(chipID) * locC;
234-
// std::cout << "CIAO32" << std::endl;
235-
236-
// Check how many labels are there
237-
if (clusLabArr->getLabels(clEntry).empty()) {
238-
continue;
239-
}
240-
const auto& lab = (clusLabArr->getLabels(clEntry))[0];
241-
// std::cout << "CIAO33" << std::endl;
242-
243-
// std::cout << "CIAO4" << std::endl;
244-
if (!lab.isValid() || lab.getSourceID() == QEDSourceID)
245-
continue;
246-
// std::cout << "CIAO5" << std::endl;
247-
248-
// get MC info
249-
int trID = lab.getTrackID();
250-
const auto& mc2hit = mc2hitVec[lab.getEventID()];
251-
const auto* hitArray = hitVecPool[lab.getEventID()];
252-
uint64_t key = (uint64_t(trID) << 32) + chipID;
253-
auto hitEntry = mc2hit.find(key);
254-
if (hitEntry == mc2hit.end()) {
255-
LOG(error) << "Failed to find MC hit entry for Tr" << trID << " chipID" << chipID;
256-
continue;
214+
// << cache MC events contributing to this ROF
215+
for (int clEntry = 0; clEntry < rofRec.getNEntries(); clEntry++) {
216+
std::cout << "\nProcessing cluster " << clEntry << "/" << rofRec.getNEntries() << std::endl;
217+
const auto& cluster = (*clusArr)[clEntry];
218+
219+
uint16_t pattID = cluster.getPattern();
220+
o2::math_utils::Point3D<float> locC;
221+
if (pattID == o2::iotof::Cluster::InvalidPatternID) {
222+
invalidPattIDCounter++;
223+
continue;
224+
}
225+
226+
auto chipID = cluster.getSensorID();
227+
228+
// Transformation to the local --> global
229+
locC = topoClassifier.getClusterCoordinates(cluster);
230+
auto gloC = gman->getMatrixL2G(chipID) * locC;
231+
232+
// Check how many labels are there
233+
if (clusLabArr->getLabels(clEntry).empty()) {
234+
continue;
235+
}
236+
const auto& lab = (clusLabArr->getLabels(clEntry))[0];
237+
238+
if (!lab.isValid() || lab.getSourceID() == QEDSourceID)
239+
continue;
240+
241+
// get MC info
242+
int trID = lab.getTrackID();
243+
int evID = lab.getEventID();
244+
const auto& mc2hit = mc2hitVec[lab.getEventID()];
245+
const auto* hitArray = hitVecPool[lab.getEventID()];
246+
uint64_t key = (uint64_t(trID) << 32) + chipID;
247+
auto hitEntry = mc2hit.find(key);
248+
if (hitEntry == mc2hit.end()) {
249+
LOG(error) << "Failed to find MC hit entry for Track: " << trID << ", chipID: " << chipID;
250+
continue;
251+
}
252+
253+
if (hitEntry->second.size() == 0) {
254+
LOG(error) << "No hits found for Track: " << trID << ", chipID: " << chipID;
255+
continue;
256+
}
257+
o2::math_utils::Point3D<float> locH, locHsta;
258+
int closestHitIdx = -1;
259+
if (hitEntry->second.size() == 1) {
260+
closestHitIdx = 0;
261+
} else {
262+
float maxDist = std::numeric_limits<float>::max();
263+
for (int iHitIdx=0; iHitIdx < hitEntry->second.size(); iHitIdx++) {
264+
const o2::itsmft::Hit* hit = &((*hitArray)[hitEntry->second[iHitIdx]]);
265+
if (!hit) {
266+
LOG(error) << "Failed to find matching hit for Track: " << trID << ", chipID: " << chipID << ", eventID: " << evID;
267+
continue;
268+
}
269+
locH = gman->getMatrixL2G(chipID) ^ (hit->GetPos()); // inverse conversion from global to local
270+
locHsta = gman->getMatrixL2G(chipID) ^ (hit->GetPosStart());
271+
locH.SetXYZ(0.5 * (locH.X() + locHsta.X()), 0.5 * (locH.Y() + locHsta.Y()), 0.5 * (locH.Z() + locHsta.Z()));
272+
float dx = std::abs(locC.X() - locH.X());
273+
float dz = std::abs(locC.Z() - locH.Z());
274+
float dist = std::sqrt(dx * dx + dz * dz);
275+
if (maxDist > dist) {
276+
maxDist = dist;
277+
closestHitIdx = iHitIdx;
278+
}
257279
}
258-
// std::cout << "CIAO6" << std::endl;
259-
const auto& hit = (*hitArray)[hitEntry->second];
260-
//
261-
float dx = 0, dz = 0;
262-
int ievH = lab.getEventID();
263-
o2::math_utils::Point3D<float> locH, locHsta;
264-
265-
// mean local position of the hit
266-
locH = gman->getMatrixL2G(chipID) ^ (hit.GetPos()); // inverse conversion from global to local
267-
locHsta = gman->getMatrixL2G(chipID) ^ (hit.GetPosStart());
268-
// std::cout << "CIAO7" << std::endl;
269-
auto x0 = locHsta.X(), dltx = locH.X() - x0;
270-
auto y0 = locHsta.Y(), dlty = locH.Y() - y0;
271-
auto z0 = locHsta.Z(), dltz = locH.Z() - z0;
272-
auto r = (0.5 * (chipInfo.SensorLayerThickness - chipInfo.SensorLayerThicknessEff) - y0) / dlty;
273-
locH.SetXYZ(x0 + r * dltx, y0 + r * dlty, z0 + r * dltz);
274-
// locH.SetXYZ(0.5 * (locH.X() + locHsta.X()), 0.5 * (locH.Y() + locHsta.Y()), 0.5 * (locH.Z() + locHsta.Z()));
275-
std::array<float, 10> data = {(float)chipID, (float)lab.getEventID(), (float)trID,
276-
locH.X(), locH.Z(),
277-
gloC.X(), gloC.Y(), gloC.Z(),
278-
locC.X() - locH.X(), locC.Z() - locH.Z()};
279-
// std::cout << "CIAO8" << std::endl;
280-
nt.Fill(data.data());
281280
}
281+
const o2::itsmft::Hit* hit = &((*hitArray)[hitEntry->second[closestHitIdx]]);
282+
if (!hit) {
283+
LOG(error) << "Failed to find matching hit for cluster " << clEntry << std::endl;
284+
continue;
285+
}
286+
locH = gman->getMatrixL2G(chipID) ^ (hit->GetPos()); // inverse conversion from global to local
287+
locHsta = gman->getMatrixL2G(chipID) ^ (hit->GetPosStart());
288+
locH.SetXYZ(0.5 * (locH.X() + locHsta.X()), 0.5 * (locH.Y() + locHsta.Y()), 0.5 * (locH.Z() + locHsta.Z()));
289+
290+
// mean local position of the hit
291+
std::array<float, 10> data = {(float)chipID, (float)lab.getEventID(), (float)trID,
292+
locH.X(), locH.Z(),
293+
gloC.X(), gloC.Y(), gloC.Z(),
294+
locC.X() - locH.X(), locC.Z() - locH.Z()};
295+
nt.Fill(data.data());
282296
}
297+
// } ROF loop
283298
std::cout << "CheckClustersIOTOF: Found " << invalidPattIDCounter << " clusters with invalid pattern ID" << std::endl;
284299

300+
// cluster maps in the xy and yz planes
301+
auto canvXY = new TCanvas("canvXY", "", 1600, 800);
302+
canvXY->Divide(2, 1);
303+
canvXY->cd(1);
304+
nt.Draw("cgy:cgx>>h_y_vs_x_IOTOF(1000, -100, 100, 1000, -100, 100)", "chip >= 0 && chip < 55488", "colz");
305+
canvXY->cd(2);
306+
nt.Draw("cgy:cgz>>h_y_vs_z_IOTOF(1000, -400, 400, 1000, -100, 100)", "chip >= 0 && chip < 55488", "colz");
307+
canvXY->SaveAs("tf3clusters_y_vs_x_vs_z.pdf");
308+
canvXY->SaveAs("tf3clusters_y_vs_x_vs_z.root");
309+
285310
// distributions of differences between local positions of digits and hits in x and z
311+
float canvaEdgeRow = 1.25 * chipInfo.PitchRow;
312+
float canvaEdgeCol = 1.25 * chipInfo.PitchCol;
286313
auto canvdXdZ = new TCanvas("canvdXdZ", "", 1600, 800);
287314
canvdXdZ->Divide(2, 1);
288315
canvdXdZ->cd(1);
289-
nt.Draw("dx:dz>>h_dx_vs_dz_ITOF(600, -0.03, 0.03, 600, -0.03, 0.03)", "chip >= 0 && chip < 1920", "colz");
290-
addTLines(0.01);
316+
nt.Draw(Form("dx:dz>>h_dx_vs_dz_ITOF(600, -%f, %f, 600, -%f, %f)", canvaEdgeRow, canvaEdgeRow, canvaEdgeCol, canvaEdgeCol), "chip >= 0 && chip < 1920", "colz");
317+
addTLines(chipInfo.PitchRow, chipInfo.PitchCol);
291318
auto h = (TH2F*)gPad->GetPrimitive("h_dx_vs_dz_ITOF");
292319
Info("ITOF", "RMS(dx)=%.1f mu", h->GetRMS(2) * 1e4);
293320
Info("ITOF", "RMS(dz)=%.1f mu", h->GetRMS(1) * 1e4);
294321
canvdXdZ->cd(2);
295-
nt.Draw("dx:dz>>h_dx_vs_dz_OTOF(600, -0.03, 0.03, 600, -0.03, 0.03)", "chip >= 1920 && chip < 55488", "colz");
296-
addTLines(0.01);
322+
nt.Draw(Form("dx:dz>>h_dx_vs_dz_OTOF(600, -%f, %f, 600, -%f, %f)", canvaEdgeRow, canvaEdgeRow, canvaEdgeCol, canvaEdgeCol), "chip >= 1920 && chip < 55488", "colz");
323+
addTLines(chipInfo.PitchRow, chipInfo.PitchCol);
297324
h = (TH2F*)gPad->GetPrimitive("h_dx_vs_dz_OTOF");
298325
Info("OTOF", "RMS(dx)=%.1f mu", h->GetRMS(2) * 1e4);
299326
Info("OTOF", "RMS(dz)=%.1f mu", h->GetRMS(1) * 1e4);

0 commit comments

Comments
 (0)