Project
Loading...
Searching...
No Matches
CRUCalibHelpers.cxx
Go to the documentation of this file.
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#include <fstream>
13#include <iostream>
14#include <numeric>
15#include <vector>
16
17#include "TPCBase/Utils.h"
18#include "TROOT.h"
19
20#include "Framework/Logger.h"
22
23using namespace o2::tpc;
24
26int cru_calib_helpers::getHWChannel(int sampa, int channel, int regionIter)
27{
28 const int sampaOffet[5] = {0, 4, 8, 0, 4};
29 if (regionIter && sampa == 2) {
30 channel -= 16;
31 }
32 int outch = sampaOffet[sampa] + ((channel % 16) % 2) + 2 * (channel / 16) + (channel % 16) / 2 * 10;
33 return outch;
34}
35
37std::tuple<int, int> cru_calib_helpers::getSampaInfo(int hwChannel, int cruID)
38{
39 static constexpr int sampaMapping[10] = {0, 0, 1, 1, 2, 3, 3, 4, 4, 2};
40 static constexpr int channelOffset[10] = {0, 16, 0, 16, 0, 0, 16, 0, 16, 16};
41 const int regionIter = cruID % 2;
42
43 const int istreamm = ((hwChannel % 10) / 2);
44 const int partitionStream = istreamm + regionIter * 5;
45 const int sampaOnFEC = sampaMapping[partitionStream];
46 const int channel = (hwChannel % 2) + 2 * (hwChannel / 10);
47 const int channelOnSAMPA = channel + channelOffset[partitionStream];
48
49 return {sampaOnFEC, channelOnSAMPA};
50}
51
56{
57 const int sampaMapping[10] = {0, 0, 1, 1, 2, 3, 3, 4, 4, 2};
58 const int channelOffset[10] = {0, 16, 0, 16, 0, 0, 16, 0, 16, 16};
59 const int regionIter = cruID % 2;
60
61 for (std::size_t ichannel = 0; ichannel < 80; ++ichannel) {
62 const int istreamm = ((ichannel % 10) / 2);
63 const int partitionStream = istreamm + regionIter * 5;
64 const int sampaOnFEC = sampaMapping[partitionStream];
65 const int channel = (ichannel % 2) + 2 * (ichannel / 10);
66 const int channelOnSAMPA = channel + channelOffset[partitionStream];
67
68 const size_t outch = cru_calib_helpers::getHWChannel(sampaOnFEC, channelOnSAMPA, regionIter);
69 printf("%4zu %4d %4d : %4zu %s\n", outch, sampaOnFEC, channelOnSAMPA, ichannel, (outch != ichannel) ? "============" : "");
70 }
71}
72
74void cru_calib_helpers::debugDiff(std::string_view file1, std::string_view file2, std::string_view objName)
75{
76 using namespace o2::tpc;
77 CalPad dummy;
78 CalPad* calPad1{nullptr};
79 CalPad* calPad2{nullptr};
80
81 std::unique_ptr<TFile> tFile1(TFile::Open(file1.data()));
82 std::unique_ptr<TFile> tFile2(TFile::Open(file2.data()));
83 gROOT->cd();
84
85 tFile1->GetObject(objName.data(), calPad1);
86 tFile2->GetObject(objName.data(), calPad2);
87
88 for (size_t iroc = 0; iroc < calPad1->getData().size(); ++iroc) {
89 const auto& calArray1 = calPad1->getCalArray(iroc);
90 const auto& calArray2 = calPad2->getCalArray(iroc);
91 // skip empty
92 if (!(std::abs(calArray1.getSum() + calArray2.getSum()) > 0)) {
93 continue;
94 }
95
96 for (size_t ipad = 0; ipad < calArray1.getData().size(); ++ipad) {
97 const auto val1 = calArray1.getValue(ipad);
98 const auto val2 = calArray2.getValue(ipad);
99
100 if (std::abs(val2 - val1) >= 0.25) {
101 printf("%2zu %5zu : %.5f - %.5f = %.2f\n", iroc, ipad, val2, val1, val2 - val1);
102 }
103 }
104 }
105}
106
107std::unordered_map<std::string, CalPad> cru_calib_helpers::preparePedestalFiles(const CalPad& pedestals, const CalPad& noise, std::vector<float> sigmaNoiseROCType, std::vector<float> minADCROCType, float pedestalOffset, bool onlyFilled, bool maskBad, float noisyChannelThreshold, float sigmaNoiseNoisyChannels, float badChannelThreshold, bool fixedSize)
108{
109 const auto& mapper = Mapper::instance();
110
111 auto expandVector = [](std::vector<float>& vec, const std::string name) {
112 if (vec.size() == 1) {
113 vec.resize(4);
114 std::fill_n(&vec[1], 3, vec[0]);
115 } else if (vec.size() == 2) {
116 vec.resize(4);
117 std::fill_n(&vec[2], 2, vec[1]);
118 } else if (vec.size() != 4) {
119 LOGP(fatal, "{} definition must be either one value for all ROC types, or {{IROC, OROC}}, or {{IROC, OROC1, OROC2, OROC3}}", name);
120 }
121 LOGP(info, "Using {} = {{{}}}", name, utils::elementsToString(vec));
122 };
123
124 expandVector(sigmaNoiseROCType, "sigmaNoiseROCType");
125 expandVector(minADCROCType, "minADCROCType");
126
127 std::unordered_map<std::string, CalPad> pedestalsThreshold;
128 pedestalsThreshold["Pedestals"] = CalPad("Pedestals");
129 pedestalsThreshold["ThresholdMap"] = CalPad("ThresholdMap");
130 pedestalsThreshold["PedestalsPhys"] = CalPad("Pedestals");
131 pedestalsThreshold["ThresholdMapPhys"] = CalPad("ThresholdMap");
132
133 auto& pedestalsCRU = pedestalsThreshold["Pedestals"];
134 auto& thresholdCRU = pedestalsThreshold["ThresholdMap"];
135
136 // ===| prepare values |===
137 for (size_t iroc = 0; iroc < pedestals.getData().size(); ++iroc) {
138 const ROC roc(iroc);
139
140 const auto& rocPedestal = pedestals.getCalArray(iroc);
141 const auto& rocNoise = noise.getCalArray(iroc);
142
143 const int padOffset = roc.isOROC() ? mapper.getPadsInIROC() : 0;
144 const auto& traceLengths = roc.isIROC() ? mapper.getTraceLengthsIROC() : mapper.getTraceLengthsOROC();
145
146 // skip empty
147 if (!(std::abs(rocPedestal.getSum() + rocNoise.getSum()) > 0)) {
148 continue;
149 }
150
151 // loop over pads
152 for (size_t ipad = 0; ipad < rocPedestal.getData().size(); ++ipad) {
153 const int globalPad = ipad + padOffset;
154 const FECInfo& fecInfo = mapper.fecInfo(globalPad);
155 const CRU cru = mapper.getCRU(roc.getSector(), globalPad);
156 const uint32_t region = cru.region();
157 const int cruID = cru.number();
158 const int sampa = fecInfo.getSampaChip();
159 const int sampaChannel = fecInfo.getSampaChannel();
160 // int globalLinkID = fecInfo.getIndex();
161
162 const PartitionInfo& partInfo = mapper.getMapPartitionInfo()[cru.partition()];
163 const int nFECs = partInfo.getNumberOfFECs();
164 const int fecOffset = (nFECs + 1) / 2;
165 const int fecInPartition = fecInfo.getIndex() - partInfo.getSectorFECOffset();
166 // const int dataWrapperID = fecInPartition >= fecOffset;
167 // const int globalLinkID = (fecInPartition % fecOffset) + dataWrapperID * 12;
168 const int rocType = roc.isIROC() ? 0 : cru.partition() - 1;
169 const float sigmaNoise = sigmaNoiseROCType[rocType];
170 const float minADC = minADCROCType[rocType];
171
172 const auto traceLength = traceLengths[ipad];
173
174 float pedestal = rocPedestal.getValue(ipad);
175 if ((pedestal > 0) && (pedestalOffset > pedestal)) {
176 LOGP(warning, "ROC: {:2}, pad: {:3} -- pedestal offset {:.2f} larger than the pedestal value {:.2f}. Pedestal and noise will be set to 0", iroc, ipad, pedestalOffset, pedestal);
177 } else {
178 pedestal -= pedestalOffset;
179 }
180
181 float noise = std::abs(rocNoise.getValue(ipad)); // it seems with the new fitting procedure, the noise can also be negative, since in gaus sigma is quadratic
182 float noiseCorr = noise - (0.847601 + 0.031514 * traceLength);
183 if ((pedestal <= 0) || (pedestal > 150) || (noise <= 0) || (noise > 50)) {
184 LOGP(info, "Bad pedestal or noise value in ROC {:2}, CRU {:3}, fec in CRU: {:2}, SAMPA: {}, channel: {:2}, pedestal: {:.4f}, noise {:.4f}", iroc, cruID, fecInPartition, sampa, sampaChannel, pedestal, noise);
185 if (maskBad) {
186 pedestal = 1023;
187 noise = 1023;
188 LOGP(info, ", they will be masked using pedestal value {:.0f} and noise {:.0f}", pedestal, noise);
189 } else {
190 LOGP(info, ", setting both to 0");
191 pedestal = 0;
192 noise = 0;
193 }
194 }
195 float threshold = (noise > 0) ? std::max(sigmaNoise * noise, minADC) : 0;
196 threshold = std::min(threshold, 1023.f);
197 float thresholdHighNoise = (noiseCorr > noisyChannelThreshold) ? std::max(sigmaNoiseNoisyChannels * noise, minADC) : threshold;
198 thresholdHighNoise = std::min(thresholdHighNoise, 1023.f);
199
200 float pedestalHighNoise = pedestal;
201 if (noiseCorr > badChannelThreshold) {
202 pedestalHighNoise = 1023;
203 thresholdHighNoise = 1023;
204 }
205
206 const int hwChannel = getHWChannel(sampa, sampaChannel, region % 2);
207 // for debugging
208 // printf("%4d %4d %4d %4d %4d: %u\n", cru.number(), globalLinkID, hwChannel, fecInfo.getSampaChip(), fecInfo.getSampaChannel(), getADCValue(pedestal));
209
210 // default thresholds
211 if (fixedSize) {
212 pedestal = floatToFixedSize(pedestal);
213 threshold = floatToFixedSize(threshold);
214
215 // higher thresholds for physics data taking
216 pedestalHighNoise = floatToFixedSize(pedestalHighNoise);
217 thresholdHighNoise = floatToFixedSize(thresholdHighNoise);
218 }
219
220 pedestalsThreshold["Pedestals"].getCalArray(iroc).setValue(ipad, pedestal);
221 pedestalsThreshold["ThresholdMap"].getCalArray(iroc).setValue(ipad, threshold);
222 pedestalsThreshold["PedestalsPhys"].getCalArray(iroc).setValue(ipad, pedestalHighNoise);
223 pedestalsThreshold["ThresholdMapPhys"].getCalArray(iroc).setValue(ipad, thresholdHighNoise);
224 // for debugging
225 // if(!(std::abs(pedestal - fixedSizeToFloat(adcPedestal)) <= 0.5 * 0.25)) {
226 // printf("%4d %4d %4d %4d %4d: %u %.2f %.4f %.4f\n", cru.number(), globalLinkID, hwChannel, sampa, sampaChannel, adcPedestal, fixedSizeToFloat(adcPedestal), pedestal, pedestal - fixedSizeToFloat(adcPedestal));
227 //}
228 }
229 }
230
231 return pedestalsThreshold;
232}
uint32_t roc
Definition RawData.h:3
unsigned char region() const
Definition CRU.h:64
unsigned short number() const
Definition CRU.h:60
unsigned char partition() const
Definition CRU.h:63
const CalType & getCalArray(size_t position) const
Definition CalDet.h:63
const std::vector< CalType > & getData() const
Definition CalDet.h:58
unsigned char getSampaChannel() const
Definition FECInfo.h:45
unsigned char getIndex() const
Definition FECInfo.h:41
unsigned char getSampaChip() const
Definition FECInfo.h:44
static Mapper & instance(const std::string mappingDir="")
Definition Mapper.h:44
unsigned char getNumberOfFECs() const
unsigned char getSectorFECOffset() const
GLsizeiptr size
Definition glcorearb.h:659
GLuint const GLchar * name
Definition glcorearb.h:781
int getHWChannel(int sampa, int channel, int regionIter)
return the hardware channel number as mapped in the CRU
std::unordered_map< std::string, CalPad > preparePedestalFiles(const CalPad &pedestals, const CalPad &noise, std::vector< float > sigmaNoiseROCType={3, 3, 3, 3}, std::vector< float > minADCROCType={2, 2, 2, 2}, float pedestalOffset=0, bool onlyFilled=false, bool maskBad=true, float noisyChannelThreshold=1.5, float sigmaNoiseNoisyChannels=4, float badChannelThreshold=6, bool fixedSize=false)
std::tuple< int, int > getSampaInfo(int hwChannel, int cruID)
convert HW mapping to sampa and channel number
constexpr uint32_t floatToFixedSize(float value)
convert float to integer with fixed precision and max number of digits
void testChannelMapping(int cruID=0)
void debugDiff(std::string_view file1, std::string_view file2, std::string_view objName)
debug differences between two cal pad objects
Global TPC definitions and constants.
Definition SimTraits.h:167
CalDet< float > CalPad
Definition CalDet.h:492
std::vector< o2::ctf::BufferType > vec