Skip to content

Commit 574fb08

Browse files
draft multi-roc level pedestals
1 parent d315d04 commit 574fb08

13 files changed

Lines changed: 185 additions & 135 deletions

File tree

app/tool/algorithm/level_pedestals.cxx

Lines changed: 139 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -7,25 +7,6 @@
77

88
namespace pflib::algorithm {
99

10-
/**
11-
* Retrieve the ADC sample for the input channel from the input event packet
12-
*/
13-
static int get_adc(const pflib::packing::MultiSampleECONDEventPacket& p,
14-
int ch) {
15-
// Use link specific channel calculation
16-
// TODO: 348
17-
// Use the "Sample Of Interest" inside the EventPacket
18-
// TODO this is only true if we only have one ROC's channels enabled
19-
// in the ECON-D. In the more realistic case, we should get the
20-
// link indices depending on which ROC we are aligning
21-
int i_link = ch / 36; // 0 or 1
22-
int i_ch = ch % 36; // 0 - 35
23-
24-
// ECONDEventPacket.h defines channel differently to SingleROCEventPacket.h
25-
// because it can have more than 2 links readout
26-
return p.samples[p.i_soi].channel(i_link, i_ch).adc();
27-
}
28-
2910
/**
3011
* get the medians of the channel ADC values
3112
*
@@ -59,8 +40,8 @@ static std::array<int, 72> get_adc_medians(
5940
return medians;
6041
}
6142

62-
std::map<std::string, std::map<std::string, uint64_t>> level_pedestals(
63-
Target* tgt, ROC roc) {
43+
std::map<int, std::map<std::string, std::map<std::string, uint64_t>>>
44+
level_pedestals(Target* tgt) {
6445
static auto the_log_{::pflib::logging::get("level_pedestals")};
6546

6647
/// do three runs of 100 samples each to have well defined pedestals
@@ -70,118 +51,166 @@ std::map<std::string, std::map<std::string, uint64_t>> level_pedestals(
7051
pflib_log(info) << "Using DAQ format mode: "
7152
<< static_cast<int>(pftool::state.daq_format_mode);
7253

73-
std::array<int, 2> target;
74-
std::array<int, 72> baseline, highend, lowend;
54+
// each output stream ("half" of a ROC) has its own target pedestal value
55+
std::map<int, std::array<int, 2>> target;
56+
// each channel has measurements at different parameter points
57+
std::map<int, std::array<int, 72>> baseline, highend, lowend;
7558

76-
/// TODO for multi-ROC set ups, we could dynamically determine the number
77-
// of ROCs and the number of channels from the Target
78-
DecodeAndBuffer buffer{n_events, 2};
59+
DecodeAndBuffer buffer{n_events, tgt->nrocs()*2};
7960

8061
{ // baseline run scope
8162
pflib_log(info) << "100 event baseline run";
82-
auto test_handle = roc.testParameters()
83-
.add_all_channels("SIGN_DAC", 0)
84-
.add_all_channels("DACB", 0)
85-
.add_all_channels("TRIM_INV", 0)
86-
.apply();
63+
64+
std::map<std::string, std::map<std::string, uint64_t>> parameters;
65+
for (int ch{0}; ch < 72; ch++) {
66+
std::string ch_str{"CH_"+std::to_string(ch)};
67+
parameters[ch_str]["SIGN_DAC"] = 0;
68+
parameters[ch_str]["DACB"] = 0;
69+
parameters[ch_str]["TRIM_INV"] = 0;
70+
}
71+
72+
std::map<int, std::map<int, std::map<int, uint8_t>>> prior_registers;
73+
for (int i_roc : tgt->roc_ids()) {
74+
prior_registers[i_roc] = tgt->roc(i_roc).applyParameters(parameters);
75+
}
76+
8777
daq_run(tgt, "PEDESTAL", buffer, n_events, 100);
8878
pflib_log(trace) << "baseline run done, getting channel medians";
89-
auto medians = get_adc_medians(buffer.get_buffer());
79+
std::map<int, std::array<int, 72>> medians;
80+
for (int i_roc : tgt->roc_ids()) {
81+
medians[i_roc] = get_adc_medians(i_roc, tgt->getRocErxMapping(), buffer.get_buffer());
82+
}
9083
baseline = medians;
9184
pflib_log(trace) << "got channel medians, getting link medians";
92-
for (int i_link{0}; i_link < 2; i_link++) {
93-
auto start{medians.begin() + 36 * i_link};
94-
auto end{start + 36};
95-
auto halfway{start + 18};
96-
std::nth_element(start, halfway, end);
97-
target[i_link] = *halfway;
85+
for (int i_half{0}; i_half < 2; i_half++) {
86+
for (int i_roc : tgt->roc_ids()) {
87+
auto start{medians.at(i_roc).begin() + 36 * i_half};
88+
auto end{start + 36};
89+
auto halfway{start + 18};
90+
std::nth_element(start, halfway, end);
91+
target[i_roc][i_half] = *halfway;
92+
}
93+
}
94+
pflib_log(trace) << "got medians per half";
95+
96+
for (int i_roc : tgt->roc_ids()) {
97+
tgt->roc(i_roc).setRegisters(prior_registers.at(i_roc));
9898
}
99-
pflib_log(trace) << "got link medians";
10099
}
101100

102101
{ // highend run scope
103102
pflib_log(info) << "100 event highend run";
104-
auto test_handle = roc.testParameters()
105-
.add_all_channels("SIGN_DAC", 0)
106-
.add_all_channels("DACB", 0)
107-
.add_all_channels("TRIM_INV", 63)
108-
.apply();
103+
104+
std::map<std::string, std::map<std::string, uint64_t>> parameters;
105+
for (int ch{0}; ch < 72; ch++) {
106+
std::string ch_str{"CH_"+std::to_string(ch)};
107+
parameters[ch_str]["SIGN_DAC"] = 0;
108+
parameters[ch_str]["DACB"] = 0;
109+
parameters[ch_str]["TRIM_INV"] = 63;
110+
}
111+
112+
std::map<int, std::map<int, std::map<int, uint8_t>>> prior_registers;
113+
for (int i_roc : tgt->roc_ids()) {
114+
prior_registers[i_roc] = tgt->roc(i_roc).applyParameters(parameters);
115+
}
116+
109117
daq_run(tgt, "PEDESTAL", buffer, n_events, 100);
110-
highend = get_adc_medians(buffer.get_buffer());
118+
119+
for (int i_roc : tgt->roc_ids()) {
120+
highend[i_roc] = get_adc_medians(i_roc, tgt->getRocErxMapping(), buffer.get_buffer());
121+
}
122+
123+
for (int i_roc : tgt->roc_ids()) {
124+
tgt->roc(i_roc).setRegisters(prior_registers.at(i_roc));
125+
}
111126
}
112127

113128
{ // lowend run
114129
pflib_log(info) << "100 event lowend run";
115-
auto test_handle = roc.testParameters()
116-
.add_all_channels("SIGN_DAC", 1)
117-
.add_all_channels("DACB", 31)
118-
.add_all_channels("TRIM_INV", 0)
119-
.apply();
130+
131+
std::map<std::string, std::map<std::string, uint64_t>> parameters;
132+
for (int ch{0}; ch < 72; ch++) {
133+
std::string ch_str{"CH_"+std::to_string(ch)};
134+
parameters[ch_str]["SIGN_DAC"] = 1;
135+
parameters[ch_str]["DACB"] = 31;
136+
parameters[ch_str]["TRIM_INV"] = 0;
137+
}
138+
139+
std::map<int, std::map<int, std::map<int, uint8_t>>> prior_registers;
140+
for (int i_roc : tgt->roc_ids()) {
141+
prior_registers[i_roc] = tgt->roc(i_roc).applyParameters(parameters);
142+
}
143+
120144
daq_run(tgt, "PEDESTAL", buffer, n_events, 100);
121-
lowend = get_adc_medians(buffer.get_buffer());
145+
146+
for (int i_roc : tgt->roc_ids()) {
147+
lowend[i_roc] = get_adc_medians(i_roc, tgt->getRocErxMapping(), buffer.get_buffer());
148+
}
122149
}
123150

124151
pflib_log(info) << "sample collections done, deducing settings";
125-
std::map<std::string, std::map<std::string, uint64_t>> settings;
126-
for (int ch{0}; ch < 72; ch++) {
127-
std::string page{pflib::utility::string_format("CH_%d", ch)};
128-
int i_link = ch / 36;
129-
if (baseline.at(ch) < target.at(i_link)) {
130-
pflib_log(debug) << "Channel " << ch
131-
<< " is below target, setting TRIM_INV";
132-
double scale = static_cast<double>(target.at(i_link) - baseline.at(ch)) /
133-
(highend.at(ch) - baseline.at(ch));
134-
if (scale < 0) {
135-
pflib_log(warn) << "Channel " << ch
136-
<< " is below target but increasing TRIM_INV made it "
137-
"lower??? Skipping...";
138-
continue;
139-
}
140-
if (scale > 1) {
141-
pflib_log(warn) << "Channel " << ch
142-
<< " is so far below target that we cannot increase "
143-
"TRIM_INV enough."
144-
<< " Setting TRIM_INV to its maximum.";
145-
settings[page]["TRIM_INV"] = 63;
146-
continue;
147-
}
148-
// scale is in [0,1]
149-
double optim = scale * 63;
150-
uint64_t val = static_cast<uint64_t>(optim);
151-
pflib_log(trace) << "Scale " << scale << " giving optimal value of "
152-
<< optim << " which rounds to " << val;
153-
settings[page]["TRIM_INV"] = val;
154-
} else {
155-
double scale = static_cast<double>(baseline.at(ch) - target.at(i_link)) /
156-
(baseline.at(ch) - lowend.at(ch));
157-
if (scale < 0) {
158-
pflib_log(warn) << "Channel " << ch
159-
<< " is above target but using SIGN_DAC=1 and "
160-
"increasing DACB made it higher??? Skipping...";
161-
continue;
162-
}
163-
if (scale > 1) {
164-
pflib_log(warn)
165-
<< "Channel " << ch
166-
<< " is so far above target that we cannot lower it enough."
167-
<< " Setting SIGN_DAC=1 and DACB to its maximum.";
168-
settings[page]["SIGN_DAC"] = 1;
169-
settings[page]["DACB"] = 31;
170-
continue;
171-
}
172-
double optim = scale * 31;
173-
uint64_t val = static_cast<uint64_t>(optim);
174-
pflib_log(trace) << "Scale " << scale << " giving optimal value of "
175-
<< optim << " which rounds to " << val;
176-
if (val == 0) {
177-
pflib_log(debug)
178-
<< "Channel " << ch
179-
<< " is above target but too close to use DACB to lower, skipping";
180-
} else {
152+
std::map<int, std::map<std::string, std::map<std::string, uint64_t>>> settings;
153+
for (int i_roc : tgt->roc_ids()) {
154+
for (int ch{0}; ch < 72; ch++) {
155+
std::string page{pflib::utility::string_format("CH_%d", ch)};
156+
int i_half = ch / 36;
157+
if (baseline[i_roc].at(ch) < target[i_roc].at(i_half)) {
181158
pflib_log(debug) << "Channel " << ch
182-
<< " is above target, setting SIGN_DAC=1 and DACB";
183-
settings[page]["SIGN_DAC"] = 1;
184-
settings[page]["DACB"] = val;
159+
<< " is below target, setting TRIM_INV";
160+
double scale = static_cast<double>(target[i_roc].at(i_half) - baseline[i_roc].at(ch)) /
161+
(highend[i_roc].at(ch) - baseline[i_roc].at(ch));
162+
if (scale < 0) {
163+
pflib_log(warn) << "Channel " << ch
164+
<< " is below target but increasing TRIM_INV made it "
165+
"lower??? Skipping...";
166+
continue;
167+
}
168+
if (scale > 1) {
169+
pflib_log(warn) << "Channel " << ch
170+
<< " is so far below target that we cannot increase "
171+
"TRIM_INV enough."
172+
<< " Setting TRIM_INV to its maximum.";
173+
settings[i_roc][page]["TRIM_INV"] = 63;
174+
continue;
175+
}
176+
// scale is in [0,1]
177+
double optim = scale * 63;
178+
uint64_t val = static_cast<uint64_t>(optim);
179+
pflib_log(trace) << "Scale " << scale << " giving optimal value of "
180+
<< optim << " which rounds to " << val;
181+
settings[i_roc][page]["TRIM_INV"] = val;
182+
} else {
183+
double scale = static_cast<double>(baseline[i_roc].at(ch) - target[i_roc].at(i_half)) /
184+
(baseline[i_roc].at(ch) - lowend[i_roc].at(ch));
185+
if (scale < 0) {
186+
pflib_log(warn) << "Channel " << ch
187+
<< " is above target but using SIGN_DAC=1 and "
188+
"increasing DACB made it higher??? Skipping...";
189+
continue;
190+
}
191+
if (scale > 1) {
192+
pflib_log(warn)
193+
<< "Channel " << ch
194+
<< " is so far above target that we cannot lower it enough."
195+
<< " Setting SIGN_DAC=1 and DACB to its maximum.";
196+
settings[i_roc][page]["SIGN_DAC"] = 1;
197+
settings[i_roc][page]["DACB"] = 31;
198+
continue;
199+
}
200+
double optim = scale * 31;
201+
uint64_t val = static_cast<uint64_t>(optim);
202+
pflib_log(trace) << "Scale " << scale << " giving optimal value of "
203+
<< optim << " which rounds to " << val;
204+
if (val == 0) {
205+
pflib_log(debug)
206+
<< "Channel " << ch
207+
<< " is above target but too close to use DACB to lower, skipping";
208+
} else {
209+
pflib_log(debug) << "Channel " << ch
210+
<< " is above target, setting SIGN_DAC=1 and DACB";
211+
settings[i_roc][page]["SIGN_DAC"] = 1;
212+
settings[i_roc][page]["DACB"] = val;
213+
}
185214
}
186215
}
187216
}

app/tool/algorithm/level_pedestals.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ namespace pflib::algorithm {
1515
*
1616
* @note Only functional for single-ROC targets
1717
*/
18-
std::map<std::string, std::map<std::string, uint64_t>> level_pedestals(
19-
Target* tgt, ROC roc);
18+
std::map<int, std::map<std::string, std::map<std::string, uint64_t>>>
19+
level_pedestals(Target* tgt);
2020

2121
} // namespace pflib::algorithm

app/tool/tasks/level_pedestals.cxx

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,15 +7,19 @@
77
#include "../algorithm/level_pedestals.h"
88

99
void level_pedestals(Target* tgt) {
10-
auto roc{tgt->roc(pftool::state.iroc)};
11-
auto settings = pflib::algorithm::level_pedestals(tgt, roc);
10+
auto settings = pflib::algorithm::level_pedestals(tgt);
1211
YAML::Emitter out;
1312
out << YAML::BeginMap;
14-
for (const auto& page : settings) {
15-
out << YAML::Key << page.first;
13+
for (const auto& roc : settings) {
14+
out << YAML::Key << roc.first;
1615
out << YAML::Value << YAML::BeginMap;
17-
for (const auto& param : page.second) {
18-
out << YAML::Key << param.first << YAML::Value << param.second;
16+
for (const auto& page : roc.second) {
17+
out << YAML::Key << page.first;
18+
out << YAML::Value << YAML::BeginMap;
19+
for (const auto& param : page.second) {
20+
out << YAML::Key << param.first << YAML::Value << param.second;
21+
}
22+
out << YAML::EndMap;
1923
}
2024
out << YAML::EndMap;
2125
}
@@ -26,7 +30,9 @@ void level_pedestals(Target* tgt) {
2630
}
2731

2832
if (pftool::readline_bool("Apply settings to the chip? ", false)) {
29-
roc.applyParameters(settings);
33+
for (int i_roc : tgt->roc_ids()) {
34+
tgt->roc(i_roc).applyParameters(settings.at(i_roc));
35+
}
3036
}
3137

3238
if (pftool::readline_bool("Save settings to a file? ", false)) {

app/tool/tasks/setup/align_phase_word.cxx

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,9 @@ void align_phase_word(Target* tgt) {
325325
*/
326326
auto roc_ids = tgt->roc_ids();
327327
// Get channels dynamically from ROC to eRx object channel mapping
328-
auto& mapping = tgt->getRocErxMapping();
328+
// we need to use the lower-level hardware mapping since we want the
329+
// eRx ID number and not just the index it would produce after decoding
330+
auto& mapping = tgt->getHardwareRocErxMapping();
329331
// Dynamic channels. 2 eRx per ROC
330332
std::vector<int> channels;
331333
for (int i_roc : roc_ids) {

include/pflib/Ecal.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ class EcalModule {
6868
void softResetECON();
6969

7070
/** Get the mapping of ROC channels to ERX channels */
71-
static const std::vector<std::pair<int, int>>& getRocErxMapping();
71+
static const std::vector<std::pair<int, int>>& getHardwareRocErxMapping();
7272

7373
/// mapping of ROC halves to ECON-D eRx channels
7474
static const std::vector<std::pair<int, int>> ROC_ERX_MAPPING;

include/pflib/HcalBackplane.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class HcalBackplane : public Target {
6767
virtual DAQ& daq() = 0;
6868

6969
/** Get the ROC to eRx mapping */
70-
const std::vector<std::pair<int, int>>& getRocErxMapping() override;
70+
const std::vector<std::pair<int, int>>& getHardwareRocErxMapping() override;
7171

7272
/// the ROC to eRx mapping for this hardware
7373
static const std::vector<std::pair<int, int>> ROC_ERX_MAPPING;

0 commit comments

Comments
 (0)