Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
216 changes: 186 additions & 30 deletions app/tool/algorithm/local_pedestal_level.cxx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
#include "local_pedestal_level.h"

#include <iostream>

#include "../daq_run.h"
#include "../tasks/local_pedestal_level.h"
#include "pflib/utility/median.h"
#include "pflib/utility/stdev.h"
#include "pflib/utility/string_format.h"

namespace pflib::algorithm {
Expand Down Expand Up @@ -38,6 +41,23 @@ static std::array<int, 72> get_adc_medians(
return medians;
}

static std::array<double, 72> get_adc_stdevs(
int i_roc, const pflib::packing::SingleECONDRocErxMapping& mapping,
const std::vector<pflib::packing::MultiSampleECONDEventPacket>& data) {
std::array<double, 72> stdevs;
/// reserve a vector of the appropriate size to avoid repeating allocation
/// time for all 72 channels
std::vector<int> adcs(data.size());
for (int ch{0}; ch < 72; ch++) {
for (std::size_t i{0}; i < adcs.size(); i++) {
auto [i_erx, i_ch] = mapping.toErxChannel(i_roc, ch);
adcs[i] = data[i].soi().channel(i_erx, i_ch).adc();
}
stdevs[ch] = pflib::utility::stdev(adcs);
Comment thread
tomeichlersmith marked this conversation as resolved.
}
return stdevs;
}

std::map<int, std::map<std::string, std::map<std::string, uint64_t>>>
local_pedestal_level(Target* tgt) {
static auto the_log_{::pflib::logging::get("local_pedestal_level")};
Expand All @@ -53,6 +73,10 @@ local_pedestal_level(Target* tgt) {
std::map<int, std::array<int, 2>> target;
// each channel has measurements at different parameter points
std::map<int, std::array<int, 72>> baseline, highend, lowend;
// will fill with standard deviations so we can ommit dead channels
std::map<int, std::array<double, 72>> basedevs;
// include all zero parmeter run values since hcal used DACB and SIGN_DAC
std::map<int, std::array<int, 72>> allzero;

DecodeAndBuffer buffer{n_events, tgt->nrocs() * 2};

Expand All @@ -61,9 +85,13 @@ local_pedestal_level(Target* tgt) {
std::map<std::string, std::map<std::string, uint64_t>> parameters;
for (int ch{0}; ch < 72; ch++) {
std::string ch_str{"CH_" + std::to_string(ch)};
parameters[ch_str]["SIGN_DAC"] = 0;
parameters[ch_str]["DACB"] = 0;
parameters[ch_str]["TRIM_INV"] = 0;
if (pftool::state.readout_config_is_hcal()) {
parameters[ch_str]["SIGN_DAC"] = 0;
parameters[ch_str]["DACB"] = 0;
parameters[ch_str]["TRIM_INV"] = 32;
} else {
parameters[ch_str]["TRIM_INV"] = 32;
}
}
auto test_params = tgt->tempApplyAllROCs(parameters);

Expand All @@ -73,6 +101,11 @@ local_pedestal_level(Target* tgt) {
for (int i_roc : tgt->roc_ids()) {
medians[i_roc] =
get_adc_medians(i_roc, tgt->getRocErxMapping(), buffer.get_buffer());
basedevs[i_roc] =
get_adc_stdevs(i_roc, tgt->getRocErxMapping(), buffer.get_buffer());
// for (const auto& num : basedevs[i_roc]) {
// std::cout << num << " " ;
//}
}
baseline = medians;
pflib_log(trace) << "got channel medians, getting link medians";
Expand All @@ -88,14 +121,38 @@ local_pedestal_level(Target* tgt) {
pflib_log(trace) << "got medians per half";
}

{ // highend run scope
pflib_log(info) << "100 event highend run";
if (pftool::state.readout_config_is_hcal()) {
// allzero run scope (SIGN_DAC = DACB = TRIM_INV = 0)
pflib_log(info) << "100 event all-zero-parameters run";
std::map<std::string, std::map<std::string, uint64_t>> parameters;
for (int ch{0}; ch < 72; ch++) {
std::string ch_str{"CH_" + std::to_string(ch)};
parameters[ch_str]["SIGN_DAC"] = 0;
parameters[ch_str]["DACB"] = 0;
parameters[ch_str]["TRIM_INV"] = 63;
parameters[ch_str]["TRIM_INV"] = 0;
}
auto test_params = tgt->tempApplyAllROCs(parameters);

daq_run(tgt, "PEDESTAL", buffer, n_events, 100);
pflib_log(trace) << "all-zero-params run done, getting channel medians";
for (int i_roc : tgt->roc_ids()) {
allzero[i_roc] =
get_adc_medians(i_roc, tgt->getRocErxMapping(), buffer.get_buffer());
}
}

{ // highend run scope
pflib_log(info) << "100 event highend run";
std::map<std::string, std::map<std::string, uint64_t>> parameters;
for (int ch{0}; ch < 72; ch++) {
std::string ch_str{"CH_" + std::to_string(ch)};
if (pftool::state.readout_config_is_hcal()) {
parameters[ch_str]["SIGN_DAC"] = 0;
parameters[ch_str]["DACB"] = 0;
parameters[ch_str]["TRIM_INV"] = 63;
} else {
parameters[ch_str]["TRIM_INV"] = 63;
}
}
auto test_params = tgt->tempApplyAllROCs(parameters);

Expand All @@ -112,9 +169,13 @@ local_pedestal_level(Target* tgt) {
std::map<std::string, std::map<std::string, uint64_t>> parameters;
for (int ch{0}; ch < 72; ch++) {
std::string ch_str{"CH_" + std::to_string(ch)};
parameters[ch_str]["SIGN_DAC"] = 1;
parameters[ch_str]["DACB"] = 31;
parameters[ch_str]["TRIM_INV"] = 0;
if (pftool::state.readout_config_is_hcal()) {
parameters[ch_str]["SIGN_DAC"] = 1;
parameters[ch_str]["DACB"] = 31;
parameters[ch_str]["TRIM_INV"] = 0;
} else {
parameters[ch_str]["TRIM_INV"] = 0;
}
}
auto test_params = tgt->tempApplyAllROCs(parameters);

Expand All @@ -129,8 +190,14 @@ local_pedestal_level(Target* tgt) {
pflib_log(info) << "sample collections done, deducing settings";
std::map<int, std::map<std::string, std::map<std::string, uint64_t>>>
settings;
std::map<int, std::vector<int>> ignored_channels;
for (int i_roc : tgt->roc_ids()) {
// ignored_channels[i_roc];
for (int ch{0}; ch < 72; ch++) {
if (basedevs[i_roc].at(ch) < 0.1) {
ignored_channels[i_roc].push_back(ch);
continue;
}
std::string page{pflib::utility::string_format("CH_%d", ch)};
int i_half = ch / 36;
if (baseline[i_roc].at(ch) < target[i_roc].at(i_half)) {
Expand All @@ -154,48 +221,137 @@ local_pedestal_level(Target* tgt) {
continue;
}
// scale is in [0,1]
double optim = scale * 63;
double optim = 32 + (scale * 31);
uint64_t val = static_cast<uint64_t>(optim);
pflib_log(trace) << "Scale " << scale << " giving optimal value of "
<< optim << " which rounds to " << val;
settings[i_roc][page]["TRIM_INV"] = val;
} else {
continue;
} else /* baseline[ch] > target[i_half] */ {
double scale = static_cast<double>(baseline[i_roc].at(ch) -
target[i_roc].at(i_half)) /
(baseline[i_roc].at(ch) - lowend[i_roc].at(ch));
if (scale < 0) {
if (scale < 0 && pftool::state.readout_config_is_hcal()) {
pflib_log(warn) << "Channel " << ch
<< " is above target but using SIGN_DAC=1 and "
"increasing DACB made it higher??? Skipping...";
<< " is above target but decreasing TRIM_INV "
"and using SIGN_DAC=1 and increasing DACB "
"made it higher??? Skipping...";
continue;
}
if (scale > 1) {
if (scale < 0 && !pftool::state.readout_config_is_hcal()) {
pflib_log(warn) << "Channel " << ch
<< " is above target but decreasing TRIM_INV "
"made it higher??? Skipping...";
continue;
}
if (scale > 1 && pftool::state.readout_config_is_hcal()) {
pflib_log(warn)
<< "Channel " << ch
<< " is so far above target that we cannot lower it enough."
<< " Setting SIGN_DAC=1 and DACB to its maximum.";
<< " Setting SIGN_DAC=1 and DACB to its maximumum."
<< " Setting TRIM_INV = 0.";
settings[i_roc][page]["TRIM_INV"] = 0;
settings[i_roc][page]["SIGN_DAC"] = 1;
settings[i_roc][page]["DACB"] = 31;
continue;
}
double optim = scale * 31;
uint64_t val = static_cast<uint64_t>(optim);
pflib_log(trace) << "Scale " << scale << " giving optimal value of "
<< optim << " which rounds to " << val;
if (val == 0) {
pflib_log(debug) << "Channel " << ch
<< " is above target but too close to use DACB to "
"lower, skipping";
} else {
pflib_log(debug) << "Channel " << ch
<< " is above target, setting SIGN_DAC=1 and DACB";
settings[i_roc][page]["SIGN_DAC"] = 1;
settings[i_roc][page]["DACB"] = val;
if (scale > 1 && !pftool::state.readout_config_is_hcal()) {
pflib_log(warn)
<< "Channel " << ch
<< " is so far above target that we cannot lower it enough."
<< " Setting TRIM_INV = 0.";
settings[i_roc][page]["TRIM_INV"] = 0;
continue;
}
// scale is in [0,1]
double diff = static_cast<double>(baseline[i_roc].at(ch) -
target[i_roc].at(i_half));
if (pftool::state.readout_config_is_hcal()) {
double trim_diff = static_cast<double>(baseline[i_roc].at(ch) -
allzero[i_roc].at(ch));
double dacb_diff =
static_cast<double>(allzero[i_roc].at(ch) - lowend[i_roc].at(ch));
if (trim_diff < 0 || dacb_diff < 0) {
pflib_log(debug)
<< "Channel " << ch << " is above target but lowering TRIM_INV "
<< "or setting SIGN_DAC = 1 and raising DACB"
<< " made it higher??? Skipping...";
continue;
}
if (diff <= trim_diff) {
double optim = 32 - ((diff / trim_diff) * 32);
uint64_t val = static_cast<uint64_t>(optim);
pflib_log(trace) << "Scale " << (diff / trim_diff)
<< " giving optimal value of " << optim
<< " for TRIM_INV"
" which rounds to "
<< val;
if (val == 0) {
pflib_log(debug)
<< "Channel " << ch
<< " is above target but too close to use TRIM_INV "
"to lower, skipping.";
} else {
pflib_log(debug)
<< "Channel " << ch << " is above target, lowering TRIM_INV";
settings[i_roc][page]["TRIM_INV"] = val;
}
} else /* diff > trim_diff */ {
double optim = ((diff - trim_diff) / dacb_diff) * 31;
uint64_t val = static_cast<uint64_t>(optim);
pflib_log(trace) << "Scale " << ((diff - trim_diff) / dacb_diff)
<< " giving optimal value of " << optim
<< " for DACB"
" which rounds to "
<< val;
if (val == 0) {
pflib_log(debug) << "Channel " << ch
<< " is above target but too close to use DACB "
"to lower. Setting TRIM_INV = 0";
settings[i_roc][page]["TRIM_INV"] = 0;
} else {
pflib_log(debug) << "Channel" << ch
<< " is above target, setting TRIM_INV = 0."
" Setting SIGN_DAC = 1 and DACB.";
settings[i_roc][page]["TRIM_INV"] = 0;
settings[i_roc][page]["SIGN_DAC"] = 1;
settings[i_roc][page]["DACB"] = val;
}
}
} else /* ecal */ {
double optim = 32 - (scale * 32);
uint64_t val = static_cast<uint64_t>(optim);
pflib_log(trace) << "Scale " << scale << " giving optimal value of "
<< optim
<< " for TRIM_INV"
" which rounds to "
<< val;
if (val == 0) {
pflib_log(debug)
<< "Channel" << ch
<< " is above target but too close to use TRIM_INV "
"to lower, skipping.";
} else {
pflib_log(debug)
<< "Channel" << ch << " is above target, setting TRIM_INV.";
settings[i_roc][page]["TRIM_INV"] = val;
}
} // end if ecal
} // end if baseline > target
} // end loop over channels
} // end loop over rocs
for (const auto& [i_roc, values] : ignored_channels) {
std::cout << "Channels ignored for ROC " << i_roc << ": ";

if (values.empty()) {
std::cout << "No channels ignored";
} else {
for (int val : values) {
std::cout << val << " ";
}
}
std::cout << '\n';
}

return settings;
}

Expand Down