Skip to content

Commit 41279c2

Browse files
authored
ITS3: move the energy deposition wrt. centre of response (#14415)
* move the energy deposition wrt. centre of response * fix the order of IB/OB for noise seeding * print out the resp centre in the CheckChipResponseFile * find the real centre * should use the total eff but not only seed
1 parent 0d55348 commit 41279c2

File tree

3 files changed

+97
-55
lines changed

3 files changed

+97
-55
lines changed

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

Lines changed: 41 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424

2525
#define ENABLE_UPGRADES
2626
#include "ITSMFTSimulation/AlpideSimResponse.h"
27+
#include "ITS3Simulation/ChipSimResponse.h"
2728

2829
#include "ITS3Base/SegmentationMosaix.h"
2930
#include "fairlogger/Logger.h"
@@ -34,61 +35,71 @@ using SegmentationMosaix = o2::its3::SegmentationMosaix;
3435
double um2cm(double um) { return um * 1e-4; }
3536
double cm2um(double cm) { return cm * 1e+4; }
3637

37-
o2::itsmft::AlpideSimResponse *mAlpSimResp0 = nullptr,
38-
*mAlpSimResp1 = nullptr,
39-
*mAptSimResp1 = nullptr;
38+
std::unique_ptr<o2::its3::ChipSimResponse> mAlpSimResp0, mAlpSimResp1, mAptSimResp1;
4039

41-
o2::itsmft::AlpideSimResponse* loadResponse(const std::string& fileName, const std::string& respName)
40+
std::unique_ptr<o2::its3::ChipSimResponse> loadResponse(const std::string& fileName, const std::string& respName)
4241
{
4342
TFile* f = TFile::Open(fileName.data());
4443
if (!f) {
4544
std::cerr << fileName << " not found" << std::endl;
4645
return nullptr;
4746
}
48-
auto resp = (o2::itsmft::AlpideSimResponse*)f->Get(respName.data());
49-
if (!resp)
47+
auto base = f->Get<o2::itsmft::AlpideSimResponse>(respName.c_str());
48+
if (!base) {
5049
std::cerr << respName << " not found in " << fileName << std::endl;
51-
return resp;
50+
return nullptr;
51+
}
52+
return std::make_unique<o2::its3::ChipSimResponse>(base);
5253
}
5354

5455
void LoadRespFunc()
5556
{
5657
std::string AptsFile = "$(O2_ROOT)/share/Detectors/Upgrades/ITS3/data/ITS3ChipResponseData/APTSResponseData.root";
5758
std::string AlpideFile = "$(O2_ROOT)/share/Detectors/ITSMFT/data/AlpideResponseData/AlpideResponseData.root";
5859

60+
std::cout << "=====================\n";
61+
LOGP(info, "ALPIDE Vbb=0V response");
5962
mAlpSimResp0 = loadResponse(AlpideFile, "response0"); // Vbb=0V
60-
LOG(info) << "ALPIDE Vbb=0V response" << std::endl;
63+
mAlpSimResp0->computeCentreFromData();
6164
mAlpSimResp0->print();
65+
LOGP(info, "Response Centre {}", mAlpSimResp0->getRespCentreDep());
66+
std::cout << "=====================\n";
67+
LOGP(info, "ALPIDE Vbb=-3V response");
6268
mAlpSimResp1 = loadResponse(AlpideFile, "response1"); // Vbb=-3V
63-
LOG(info) << "ALPIDE Vbb=-3V response" << std::endl;
69+
mAlpSimResp1->computeCentreFromData();
6470
mAlpSimResp1->print();
71+
LOGP(info, "Response Centre {}", mAlpSimResp1->getRespCentreDep());
72+
std::cout << "=====================\n";
73+
LOGP(info, "APTS response");
6574
mAptSimResp1 = loadResponse(AptsFile, "response1"); // APTS
66-
LOG(info) << "APTS response" << std::endl;
75+
mAptSimResp1->computeCentreFromData();
6776
mAptSimResp1->print();
77+
LOGP(info, "Response Centre {}", mAptSimResp1->getRespCentreDep());
78+
std::cout << "=====================\n";
6879
}
6980

70-
std::vector<float> getCollectionSeediciencies(o2::itsmft::AlpideSimResponse* resp,
81+
std::vector<float> getCollectionSeediciencies(o2::its3::ChipSimResponse* resp,
7182
const std::vector<float>& depths)
7283
{
7384
std::vector<float> seed;
7485
bool flipRow = false, flipCol = false;
7586
for (auto depth : depths) {
7687
auto rspmat = resp->getResponse(0.0, 0.0,
77-
um2cm(depth) + resp->getDepthMin() + 1.e-9,
88+
um2cm(depth) + 1.e-9,
7889
flipRow, flipCol);
7990
seed.push_back(rspmat ? rspmat->getValue(2, 2) : 0.f);
8091
}
8192
return seed;
8293
}
8394

84-
std::vector<float> getShareValues(o2::itsmft::AlpideSimResponse* resp,
95+
std::vector<float> getShareValues(o2::its3::ChipSimResponse* resp,
8596
const std::vector<float>& depths)
8697
{
8798
std::vector<float> share;
8899
bool flipRow = false, flipCol = false;
89100
for (auto depth : depths) {
90101
auto rspmat = resp->getResponse(0.0, 0.0,
91-
um2cm(depth) + resp->getDepthMin() + 1.e-9,
102+
um2cm(depth) + 1.e-9,
92103
flipRow, flipCol);
93104
float s = 0;
94105
int npix = resp->getNPix();
@@ -103,14 +114,14 @@ std::vector<float> getShareValues(o2::itsmft::AlpideSimResponse* resp,
103114
return share;
104115
}
105116

106-
std::vector<float> getEffValues(o2::itsmft::AlpideSimResponse* resp,
117+
std::vector<float> getEffValues(o2::its3::ChipSimResponse* resp,
107118
const std::vector<float>& depths)
108119
{
109120
std::vector<float> all;
110121
bool flipRow = false, flipCol = false;
111122
for (auto depth : depths) {
112123
auto rspmat = resp->getResponse(0.0, 0.0,
113-
um2cm(depth) + resp->getDepthMin() + 1.e-9,
124+
um2cm(depth) + 1.e-9,
114125
flipRow, flipCol);
115126
float s = 0;
116127
int npix = resp->getNPix();
@@ -129,13 +140,16 @@ void CheckChipResponseFile()
129140
LoadRespFunc();
130141
LOG(info) << "Response function loaded" << std::endl;
131142

132-
std::vector<float> vecDepth(50);
133-
for (int i = 0; i < 50; ++i)
134-
vecDepth[i] = i;
143+
std::vector<float> vecDepth;
144+
int numPoints = 100;
145+
for (int i = 0; i < numPoints; ++i) {
146+
float value = -50 + i * (100.0f / (numPoints - 1));
147+
vecDepth.push_back(value);
148+
}
135149

136150
int colors[] = {kOrange + 7, kRed + 1, kAzure + 4};
137151
struct RespInfo {
138-
o2::itsmft::AlpideSimResponse* resp;
152+
std::unique_ptr<o2::its3::ChipSimResponse>& resp;
139153
std::string title;
140154
int color;
141155
};
@@ -145,7 +159,7 @@ void CheckChipResponseFile()
145159
{mAlpSimResp1, "ALPIDE Vbb=-3V", colors[2]}};
146160

147161
TCanvas* c1 = new TCanvas("c1", "c1", 800, 600);
148-
TH1* frame = c1->DrawFrame(-1, -0.049, 50, 1.049);
162+
TH1* frame = c1->DrawFrame(-50, -0.049, 50, 1.049);
149163
frame->SetTitle(";Depth(um);Charge Collection Seed / Share / Eff");
150164
TLegend* leg = new TLegend(0.15, 0.5, 0.4, 0.85);
151165
leg->SetFillStyle(0);
@@ -154,11 +168,11 @@ void CheckChipResponseFile()
154168
for (auto& r : responses) {
155169
if (!r.resp)
156170
continue;
157-
auto seed = getCollectionSeediciencies(r.resp, vecDepth);
158-
auto shr = getShareValues(r.resp, vecDepth);
159-
auto all = getEffValues(r.resp, vecDepth);
171+
auto seed = getCollectionSeediciencies(r.resp.get(), vecDepth);
172+
auto shr = getShareValues(r.resp.get(), vecDepth);
173+
auto all = getEffValues(r.resp.get(), vecDepth);
160174

161-
TGraph* grSeed = new TGraph(vecDepth.size(), vecDepth.data(), seed.data());
175+
auto grSeed = new TGraph(vecDepth.size(), vecDepth.data(), seed.data());
162176
grSeed->SetTitle(Form("%s seed", r.title.c_str()));
163177
grSeed->SetLineColor(r.color);
164178
grSeed->SetLineWidth(2);
@@ -168,7 +182,7 @@ void CheckChipResponseFile()
168182
grSeed->Draw("SAME LP");
169183
leg->AddEntry(grSeed, Form("%s seed", r.title.c_str()), "lp");
170184

171-
TGraph* grShare = new TGraph(vecDepth.size(), vecDepth.data(), shr.data());
185+
auto grShare = new TGraph(vecDepth.size(), vecDepth.data(), shr.data());
172186
grShare->SetLineColor(r.color);
173187
grShare->SetLineWidth(2);
174188
grShare->SetMarkerColor(r.color);
@@ -177,7 +191,7 @@ void CheckChipResponseFile()
177191
grShare->Draw("SAME LP");
178192
leg->AddEntry(grShare, Form("%s share", r.title.c_str()), "p");
179193

180-
TGraph* grEff = new TGraph(vecDepth.size(), vecDepth.data(), all.data());
194+
auto grEff = new TGraph(vecDepth.size(), vecDepth.data(), all.data());
181195
grEff->SetLineColor(r.color);
182196
grEff->SetLineWidth(2);
183197
grEff->SetMarkerColor(r.color);

Detectors/Upgrades/ITS3/simulation/src/ChipDigitsContainer.cxx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,12 @@ void ChipDigitsContainer::addNoise(UInt_t rofMin, UInt_t rofMax, const o2::its3:
3131
int nel = 0;
3232

3333
if (isIB()) {
34-
// Inner barrel: use ITS3-specific noise interface with OB segmentation.
35-
mean = params->getIBNoisePerPixel() * SegmentationOB::NPixels;
34+
// Inner barrel: use ITS3-specific noise interface with IB segmentation.
35+
mean = params->getIBNoisePerPixel() * SegmentationIB::NPixels;
3636
nel = static_cast<int>(params->getIBChargeThreshold() * 1.1);
3737
} else {
38-
// Outer barrel: use base class noise interface with IB segmentation.
39-
mean = params->getNoisePerPixel() * SegmentationIB::NPixels;
38+
// Outer barrel: use base class noise interface with OB segmentation.
39+
mean = params->getNoisePerPixel() * SegmentationOB::NPixels;
4040
nel = static_cast<int>(params->getChargeThreshold() * 1.1);
4141
}
4242

Detectors/Upgrades/ITS3/simulation/src/ChipSimResponse.cxx

Lines changed: 52 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -25,38 +25,66 @@ void ChipSimResponse::initData(int tableNumber, std::string dataPath, const bool
2525

2626
void ChipSimResponse::computeCentreFromData()
2727
{
28-
std::vector<float> zVec, qVec;
2928
const int npix = o2::itsmft::AlpideRespSimMat::getNPix();
29+
std::vector<float> zVec, effVec;
30+
zVec.reserve(mNBinDpt);
31+
effVec.reserve(mNBinDpt);
3032

3133
for (int iz = 0; iz < mNBinDpt; ++iz) {
32-
size_t bin = iz + mNBinDpt * (0 + mNBinRow * 0);
33-
const auto& mat = mData[bin];
34-
float val = mat.getValue(npix / 2, npix / 2);
35-
float gz = mDptMin + iz / mStepInvDpt;
36-
zVec.push_back(gz);
37-
qVec.push_back(val);
34+
int rev = mNBinDpt - 1 - iz;
35+
float z = mDptMin + iz / mStepInvDpt;
36+
float sum = 0.f;
37+
const auto& mat = mData[rev];
38+
for (int ix = 0; ix < npix; ++ix) {
39+
for (int iy = 0; iy < npix; ++iy) {
40+
sum += mat.getValue(ix, iy);
41+
}
42+
}
43+
zVec.push_back(z);
44+
effVec.push_back(sum);
3845
}
3946

40-
std::vector<std::pair<float, float>> zqPairs;
41-
for (size_t i = 0; i < zVec.size(); ++i) {
42-
zqPairs.emplace_back(zVec[i], qVec[i]);
43-
}
44-
std::sort(zqPairs.begin(), zqPairs.end());
45-
zVec.clear();
46-
qVec.clear();
47-
for (auto& p : zqPairs) {
48-
zVec.push_back(p.first);
49-
qVec.push_back(p.second);
50-
}
47+
struct Bin {
48+
float z0, z1, q0, q1, dq;
49+
};
50+
std::vector<Bin> bins;
51+
bins.reserve(zVec.size() - 1);
5152

52-
float intQ = 0.f, intZQ = 0.f;
53+
float totQ = 0.f;
5354
for (size_t i = 0; i + 1 < zVec.size(); ++i) {
5455
float z0 = zVec[i], z1 = zVec[i + 1];
55-
float q0 = qVec[i], q1 = qVec[i + 1];
56-
float dz = z1 - z0;
57-
intQ += 0.5f * (q0 + q1) * dz;
58-
intZQ += 0.5f * (z0 * q0 + z1 * q1) * dz;
56+
float q0 = effVec[i], q1 = effVec[i + 1];
57+
float dq = 0.5f * (q0 + q1) * (z1 - z0);
58+
bins.push_back({z0, z1, q0, q1, dq});
59+
totQ += dq;
60+
}
61+
62+
if (totQ <= 0.f) {
63+
mRespCentreDep = mDptMin;
64+
return;
65+
}
66+
67+
float halfQ = 0.5f * totQ;
68+
float cumQ = 0.f;
69+
for (auto& b : bins) {
70+
if (cumQ + b.dq < halfQ) {
71+
cumQ += b.dq;
72+
continue;
73+
}
74+
float dz = b.z1 - b.z0;
75+
float slope = (b.q1 - b.q0) / dz;
76+
float disc = b.q0 * b.q0 - 2.f * slope * (cumQ - halfQ);
77+
78+
float x;
79+
if (disc >= 0.f && std::abs(slope) > 1e-6f) {
80+
x = (-b.q0 + std::sqrt(disc)) / slope;
81+
} else {
82+
x = (halfQ - cumQ) / b.q0;
83+
}
84+
x = std::clamp(x, 0.f, dz);
85+
mRespCentreDep = b.z0 + x;
86+
return;
5987
}
6088

61-
mRespCentreDep = (intQ > 0.f) ? intZQ / intQ : 0.f;
89+
mRespCentreDep = mDptMax;
6290
}

0 commit comments

Comments
 (0)