Skip to content

Commit 255c9ac

Browse files
committed
Add a macro to compare ITS3 clusters and digits on a pixel array
Add the script to check hits and clusters on a track Add script for visualizing chip responses
1 parent 0574f19 commit 255c9ac

File tree

10 files changed

+266
-38
lines changed

10 files changed

+266
-38
lines changed

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

Lines changed: 40 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -43,24 +43,22 @@ class SegmentationMosaix
4343
// 3. The detector coordinate system. Defined by the row and column segmentation
4444
// defined at the upper edge in the flat coord.
4545

46-
// row,col=0
47-
// |
48-
// v
49-
// x----------------------x
46+
// O----------------------|
5047
// | | |
48+
// | | | ^ x
49+
// | | | |
50+
// | | | |
51+
// | | | |
52+
// | | | X----> z X marks (x,z)=(0,0)
53+
// |-----------X----------|
54+
// | | | O----> col O marks (row,col)=(0,0)
55+
// | | | |
56+
// | | | |
57+
// | | | v
58+
// | | | row
5159
// | | |
52-
// | | | ^ x
53-
// | | | |
54-
// | | | |
55-
// | | | |
56-
// |-----------X----------| X marks (x,z)=(0,0) X----> z
57-
// | | |
58-
// | | |
59-
// | | |
60-
// | | |
61-
// | | |
62-
// | | |
63-
// x----------------------x
60+
// |----------------------|
61+
6462
public:
6563
constexpr SegmentationMosaix(int layer) : mRadius(static_cast<float>(constants::radiiMiddle[layer])) {}
6664
constexpr ~SegmentationMosaix() = default;
@@ -79,7 +77,7 @@ class SegmentationMosaix
7977
static constexpr float PitchCol{constants::pixelarray::pixels::mosaix::pitchZ};
8078
static constexpr float PitchRow{constants::pixelarray::pixels::mosaix::pitchX};
8179
static constexpr float SensorLayerThickness{constants::totalThickness};
82-
static constexpr float NominalYShift{constants::nominalYShift};
80+
static constexpr float NominalYShift{0.0f};
8381

8482
/// Transformation from the curved surface to a flat surface.
8583
/// Additionally a shift in the flat coordinates must be applied because
@@ -143,8 +141,11 @@ class SegmentationMosaix
143141
/// \param int iCol Detector z cell coordinate.
144142
constexpr bool localToDetector(float const xRow, float const zCol, int& iRow, int& iCol) const noexcept
145143
{
144+
if (!isValidLoc(xRow, zCol)) {
145+
return false;
146+
}
146147
localToDetectorUnchecked(xRow, zCol, iRow, iCol);
147-
if (!isValid(iRow, iCol)) {
148+
if (!isValidDet(iRow, iCol)) {
148149
iRow = iCol = -1;
149150
return false;
150151
}
@@ -169,25 +170,27 @@ class SegmentationMosaix
169170
/// If iRow and or iCol is outside of the segmentation range a value of -0.5*Dx()
170171
/// or -0.5*Dz() is returned.
171172
template <typename T>
172-
constexpr bool detectorToLocal(T const row, T const col, float& xRow, float& zCol) const noexcept {
173-
if (!isValid(row, col)) {
173+
constexpr bool detectorToLocal(T const row, T const col, float& xRow, float& zCol) const noexcept
174+
{
175+
if (!isValidDet(row, col)) {
174176
return false;
175177
}
176178
detectorToLocalUnchecked(row, col, xRow, zCol);
177-
return isValid(xRow, zCol);
179+
return isValidLoc(xRow, zCol);
178180
}
179181

180182
// Same as detectorToLocal w.o. checks.
181183
// We position ourself in the middle of the pixel.
182184
template <typename T>
183-
constexpr void detectorToLocalUnchecked(T const row, T const col, float& xRow, float& zCol) const noexcept {
185+
constexpr void detectorToLocalUnchecked(T const row, T const col, float& xRow, float& zCol) const noexcept
186+
{
184187
xRow = -(static_cast<float>(row) + 0.5f) * PitchRow + WidthH;
185188
zCol = (static_cast<float>(col) + 0.5f) * PitchCol - LengthH;
186189
}
187190

188-
189191
template <typename T>
190-
constexpr bool detectorToLocal(T const row, T const col, math_utils::Point3D<float>& loc) const noexcept {
192+
constexpr bool detectorToLocal(T const row, T const col, math_utils::Point3D<float>& loc) const noexcept
193+
{
191194
float xRow{0.}, zCol{0.};
192195
if (!detectorToLocal(row, col, xRow, zCol)) {
193196
return false;
@@ -197,21 +200,27 @@ class SegmentationMosaix
197200
}
198201

199202
template <typename T>
200-
constexpr void detectorToLocalUnchecked(T const row, T const col, math_utils::Point3D<float>& loc) const noexcept {
203+
constexpr void detectorToLocalUnchecked(T const row, T const col, math_utils::Point3D<float>& loc) const noexcept
204+
{
201205
float xRow{0.}, zCol{0.};
202206
detectorToLocalUnchecked(row, col, xRow, zCol);
203207
loc.SetCoordinates(xRow, NominalYShift, zCol);
204208
}
205209

206210
private:
211+
// Check local coordinates (cm) validity.
207212
template <typename T>
208-
[[nodiscard]] constexpr bool isValid(T const row, T const col) const noexcept
213+
constexpr bool isValidLoc(T const x, T const z) const noexcept
209214
{
210-
if constexpr (std::is_floating_point_v<T>) { // compares in local coord.
211-
return (-WidthH < row && row < WidthH && -LengthH < col && col < LengthH);
212-
} else { // compares in rows/cols
213-
return !static_cast<bool>(row < 0 || row >= static_cast<int>(NRows) || col < 0 || col >= static_cast<int>(NCols));
214-
}
215+
return (-WidthH < x && x < WidthH && -LengthH < z && z < LengthH);
216+
}
217+
218+
// Check detector coordinates validity.
219+
template <typename T>
220+
constexpr bool isValidDet(T const row, T const col) const noexcept
221+
{
222+
return (row >= 0 && row < static_cast<T>(NRows) &&
223+
col >= 0 && col < static_cast<T>(NCols));
215224
}
216225

217226
float mRadius;

Detectors/Upgrades/ITS3/macros/test/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,10 @@ its3_add_macro(CompareClusterSize.C)
2222
its3_add_macro(CheckSuperAlpideSegment.C)
2323
its3_add_macro(CheckSuperAlpideSegmentTrans.C)
2424
its3_add_macro(CompareClustersAndDigits.C)
25+
its3_add_macro(CompareClustersAndDigitsOnChip.C)
2526
its3_add_macro(CheckROFs.C)
2627
its3_add_macro(CheckTileNumbering.C)
2728
its3_add_macro(CreateITS3StaticDeadMap.C)
2829
its3_add_macro(TestSensorGeometry.C)
2930
its3_add_macro(CorrTracksClusters.C)
31+
its3_add_macro(CheckChipResponseFile.C)
Lines changed: 192 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,192 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \file CheckChipResponseFile.C
13+
/// \brief Simple macro to check the chip response files
14+
15+
#if !defined(__CLING__) || defined(__ROOTCLING__)
16+
#include <TFile.h>
17+
#include <TGraph.h>
18+
#include <TCanvas.h>
19+
#include <TH1.h>
20+
#include <TLegend.h>
21+
#include <iostream>
22+
#include <vector>
23+
#include <string>
24+
25+
#define ENABLE_UPGRADES
26+
#include "ITSMFTSimulation/AlpideSimResponse.h"
27+
28+
#include "ITS3Base/SegmentationMosaix.h"
29+
#include "fairlogger/Logger.h"
30+
#endif
31+
32+
using SegmentationMosaix = o2::its3::SegmentationMosaix;
33+
34+
double um2cm(double um) { return um * 1e-4; }
35+
double cm2um(double cm) { return cm * 1e+4; }
36+
37+
o2::itsmft::AlpideSimResponse *mAlpSimResp0 = nullptr,
38+
*mAlpSimResp1 = nullptr,
39+
*mAptSimResp1 = nullptr;
40+
41+
o2::itsmft::AlpideSimResponse* loadResponse(const std::string& fileName, const std::string& respName)
42+
{
43+
TFile* f = TFile::Open(fileName.data());
44+
if (!f) {
45+
std::cerr << fileName << " not found" << std::endl;
46+
return nullptr;
47+
}
48+
auto resp = (o2::itsmft::AlpideSimResponse*)f->Get(respName.data());
49+
if (!resp)
50+
std::cerr << respName << " not found in " << fileName << std::endl;
51+
return resp;
52+
}
53+
54+
void LoadRespFunc()
55+
{
56+
std::string AptsFile = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root";
57+
std::string AlpideFile = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root";
58+
59+
mAlpSimResp0 = loadResponse(AlpideFile, "response0"); // Vbb=0V
60+
LOG(info) << "ALPIDE Vbb=0V response" << std::endl;
61+
mAlpSimResp0->print();
62+
mAlpSimResp1 = loadResponse(AlpideFile, "response1"); // Vbb=-3V
63+
LOG(info) << "ALPIDE Vbb=-3V response" << std::endl;
64+
mAlpSimResp1->print();
65+
mAptSimResp1 = loadResponse(AptsFile, "response1"); // APTS
66+
LOG(info) << "APTS response" << std::endl;
67+
mAptSimResp1->print();
68+
}
69+
70+
std::vector<float> getCollectionSeediciencies(o2::itsmft::AlpideSimResponse* resp,
71+
const std::vector<float>& depths)
72+
{
73+
std::vector<float> seed;
74+
bool flipRow = false, flipCol = false;
75+
for (auto depth : depths) {
76+
auto rspmat = resp->getResponse(0.0, 0.0,
77+
um2cm(depth) + resp->getDepthMin() + 1.e-9,
78+
flipRow, flipCol);
79+
seed.push_back(rspmat ? rspmat->getValue(2, 2) : 0.f);
80+
}
81+
return seed;
82+
}
83+
84+
std::vector<float> getShareValues(o2::itsmft::AlpideSimResponse* resp,
85+
const std::vector<float>& depths)
86+
{
87+
std::vector<float> share;
88+
bool flipRow = false, flipCol = false;
89+
for (auto depth : depths) {
90+
auto rspmat = resp->getResponse(0.0, 0.0,
91+
um2cm(depth) + resp->getDepthMin() + 1.e-9,
92+
flipRow, flipCol);
93+
float s = 0;
94+
int npix = resp->getNPix();
95+
if (rspmat) {
96+
for (int i = 0; i < npix; ++i)
97+
for (int j = 0; j < npix; ++j)
98+
if (!(i == npix / 2 && j == npix / 2))
99+
s += rspmat->getValue(i, j);
100+
}
101+
share.push_back(s);
102+
}
103+
return share;
104+
}
105+
106+
std::vector<float> getEffValues(o2::itsmft::AlpideSimResponse* resp,
107+
const std::vector<float>& depths)
108+
{
109+
std::vector<float> all;
110+
bool flipRow = false, flipCol = false;
111+
for (auto depth : depths) {
112+
auto rspmat = resp->getResponse(0.0, 0.0,
113+
um2cm(depth) + resp->getDepthMin() + 1.e-9,
114+
flipRow, flipCol);
115+
float s = 0;
116+
int npix = resp->getNPix();
117+
if (rspmat) {
118+
for (int i = 0; i < npix; ++i)
119+
for (int j = 0; j < npix; ++j)
120+
s += rspmat->getValue(i, j);
121+
}
122+
all.push_back(s);
123+
}
124+
return all;
125+
}
126+
127+
void CheckChipResponseFile()
128+
{
129+
LoadRespFunc();
130+
LOG(info) << "Response function loaded" << std::endl;
131+
132+
std::vector<float> vecDepth(50);
133+
for (int i = 0; i < 50; ++i)
134+
vecDepth[i] = i;
135+
136+
int colors[] = {kOrange + 7, kRed + 1, kAzure + 4};
137+
struct RespInfo {
138+
o2::itsmft::AlpideSimResponse* resp;
139+
std::string title;
140+
int color;
141+
};
142+
std::vector<RespInfo> responses = {
143+
{mAptSimResp1, "APTS", colors[0]},
144+
{mAlpSimResp0, "ALPIDE Vbb=0V", colors[1]},
145+
{mAlpSimResp1, "ALPIDE Vbb=-3V", colors[2]}};
146+
147+
TCanvas* c1 = new TCanvas("c1", "c1", 800, 600);
148+
TH1* frame = c1->DrawFrame(-1, -0.049, 50, 1.049);
149+
frame->SetTitle(";Depth(um);Charge Collection Seed / Share / Eff");
150+
TLegend* leg = new TLegend(0.15, 0.5, 0.4, 0.85);
151+
leg->SetFillStyle(0);
152+
leg->SetBorderSize(0);
153+
154+
for (auto& r : responses) {
155+
if (!r.resp)
156+
continue;
157+
auto seed = getCollectionSeediciencies(r.resp, vecDepth);
158+
auto shr = getShareValues(r.resp, vecDepth);
159+
auto all = getEffValues(r.resp, vecDepth);
160+
161+
TGraph* grSeed = new TGraph(vecDepth.size(), vecDepth.data(), seed.data());
162+
grSeed->SetTitle(Form("%s seed", r.title.c_str()));
163+
grSeed->SetLineColor(r.color);
164+
grSeed->SetLineWidth(2);
165+
grSeed->SetMarkerColor(r.color);
166+
grSeed->SetMarkerStyle(kFullCircle);
167+
grSeed->SetMarkerSize(0.8);
168+
grSeed->Draw("SAME LP");
169+
leg->AddEntry(grSeed, Form("%s seed", r.title.c_str()), "lp");
170+
171+
TGraph* grShare = new TGraph(vecDepth.size(), vecDepth.data(), shr.data());
172+
grShare->SetLineColor(r.color);
173+
grShare->SetLineWidth(2);
174+
grShare->SetMarkerColor(r.color);
175+
grShare->SetMarkerStyle(kOpenSquare);
176+
grShare->SetMarkerSize(1);
177+
grShare->Draw("SAME LP");
178+
leg->AddEntry(grShare, Form("%s share", r.title.c_str()), "p");
179+
180+
TGraph* grEff = new TGraph(vecDepth.size(), vecDepth.data(), all.data());
181+
grEff->SetLineColor(r.color);
182+
grEff->SetLineWidth(2);
183+
grEff->SetMarkerColor(r.color);
184+
grEff->SetMarkerStyle(kFullDiamond);
185+
grEff->SetMarkerSize(1);
186+
grEff->Draw("SAME LP");
187+
leg->AddEntry(grEff, Form("%s eff", r.title.c_str()), "p");
188+
}
189+
leg->Draw();
190+
191+
c1->SaveAs("ChipResponse.pdf");
192+
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,6 @@ void CheckDigitsITS3(std::string digifile = "it3digits.root", std::string hitfil
7979

8080
int nevD = digTree->GetEntries(); // digits in cont. readout may be grouped as few events per entry
8181

82-
8382
int nDigitReadIB{0}, nDigitReadOB{0};
8483
int nDigitFilledIB{0}, nDigitFilledOB{0};
8584

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@
5252

5353
#endif
5454

55-
void CreateDictionariesITS3(bool saveDeltas = false,
55+
void CreateDictionariesITS3(bool saveDeltas = true,
5656
float probThreshold = 1e-6,
5757
std::string clusDictFile = "",
5858
std::string clusfile = "o2clus_its.root",
@@ -94,7 +94,7 @@ void CreateDictionariesITS3(bool saveDeltas = false,
9494
TNtuple* nt = nullptr;
9595
if (saveDeltas) {
9696
fout = TFile::Open("CreateDictionaries.root", "recreate");
97-
nt = new TNtuple("nt", "hashes ntuple", "hash:layer:chipID:dx:dz:outlimDx:outlimDz");
97+
nt = new TNtuple("nt", "hashes ntuple", "hash:layer:chipID:xhf:zhf:xcf:zcf:dx:dz:outlimDx:outlimDz");
9898
}
9999

100100
const o2::steer::DigitizationContext* digContext = nullptr;
@@ -285,7 +285,7 @@ void CreateDictionariesITS3(bool saveDeltas = false,
285285
dX /= (ib) ? o2::its3::SegmentationMosaix::PitchRow : o2::itsmft::SegmentationAlpide::PitchRow;
286286
dZ /= (ib) ? o2::its3::SegmentationMosaix::PitchCol : o2::itsmft::SegmentationAlpide::PitchCol;
287287

288-
float outLimitDx{-1}, outLimitDz{-1};
288+
float outLimitDx{-1}, outLimitDz{-1};
289289
if (checkOutliers > 0.) {
290290
outLimitDx = topology.getRowSpan() * checkOutliers;
291291
outLimitDz = topology.getColumnSpan() * checkOutliers;
@@ -301,7 +301,7 @@ void CreateDictionariesITS3(bool saveDeltas = false,
301301
}
302302
}
303303
if (saveDeltas) {
304-
nt->Fill(topology.getHash(), layer, chipID, dX, dZ, outLimitDx, outLimitDz);
304+
nt->Fill(topology.getHash(), layer, chipID, xyzLocM.X(), xyzLocM.Z(), locC.X(), locC.Z(), dX, dZ, outLimitDx, outLimitDz);
305305
}
306306
}
307307
} else {

Detectors/Upgrades/ITS3/simulation/include/ITS3Simulation/ChipSimResponse.h

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,14 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
112
#ifndef ALICEO2_ITS3SIMULATION_CHIPSIMRESPONSE_H
213
#define ALICEO2_ITS3SIMULATION_CHIPSIMRESPONSE_H
314

0 commit comments

Comments
 (0)