ATLAS Offline Software
Loading...
Searching...
No Matches
LArOFCSubsetCnv_p1.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
7
8void
10 LArOFCTransType* transObj,
11 MsgStream & log) const
12{
13 // Copy basic metadata
14 transObj->setChannel (persObj->m_subset.m_channel);
15 transObj->setGroupingType (persObj->m_subset.m_groupingType);
16
17 transObj->initialize (persObj->m_subset.m_febIds, persObj->m_subset.m_gain);
18
19 // Copy conditions
20 unsigned int nfebids = persObj->m_subset.m_febIds.size();
21 const unsigned int nChannelsPerFeb = persObj->m_subset.subsetSize();
22 unsigned int nPhases = persObj->m_nPhases;
23 unsigned int nSamples = persObj->m_nSamples;
24 unsigned int dataIndex = 0;
25 unsigned int timeIndex = 0;
26
27 // Loop over febs
28 unsigned int ifebWithData = 0; // counter for febs with data
29
30 auto subsetIt = transObj->subsetBegin();
31 for (unsigned int i = 0; i < nfebids; ++i, ++subsetIt){
32 // Set febid
33 unsigned int febid = (*subsetIt).first;
34
35 bool hasSparseData = false;
36 unsigned int chansSet = 0;
37 unsigned int chansOffset = 0;
38 if (ifebWithData+1 < persObj->m_subset.m_febsWithSparseData.size() &&
39 febid == persObj->m_subset.m_febsWithSparseData[ifebWithData]) {
40 // Found feb with sparse data
41 hasSparseData = true;
42 ifebWithData++;
43 chansSet = persObj->m_subset.m_febsWithSparseData[ifebWithData];
44 chansOffset = 0;
45 ifebWithData++;
46 }
47
48 // Loop over channels in feb - only some channels are filled
49 for (unsigned int j = 0; j < nChannelsPerFeb; ++j){
50
51 bool copyChannel = true;
52 if (hasSparseData) {
53 // coverity[bad_shift]
54 // coverity[integer_overflow]
55 if (!(chansSet & (1 << (j - chansOffset)))) {
56 // Channel is missing data - skip
57 copyChannel = false;
58 }
59 if (j%32 == 31 && j < nChannelsPerFeb-2) {
60 chansSet = persObj->m_subset.m_febsWithSparseData[ifebWithData];
61 chansOffset += 32;
62 ifebWithData++;
63 }
64 }
65 if (copyChannel) {
66
67 // Channel has ofcs - loop over ofcs per channel and
68 // copy to the persistent object
69
70 // check indexes
71 if (dataIndex >= persObj->m_vOFC_a.size() ||
72 dataIndex >= persObj->m_vOFC_b.size() ||
73 timeIndex >= persObj->m_timeOffset.size() ||
74 timeIndex >= persObj->m_timeBinWidth.size()) {
75 log << MSG::ERROR
76 << "LArOFCSubsetCnv_p1::persToTrans - ofc index too large: dataIndex size ofc_a, size ofc_b, timeIndex timeOffset size, timeBinWidth size "
77 << dataIndex << " " << persObj->m_vOFC_a.size() << " "
78 << persObj->m_vOFC_b.size() << " " << timeIndex << " "
79 << persObj->m_timeOffset.size() << " "
80 << persObj->m_timeBinWidth.size()
81 << endmsg;
82 return;
83 }
84
86 (*subsetIt).second[j];
87 LArOFCP1 tmp (persObj->m_timeOffset[timeIndex],
88 persObj->m_timeBinWidth[timeIndex],
89 nPhases,
90 nSamples,
91 persObj->m_vOFC_a,
92 persObj->m_vOFC_b,
93 dataIndex);
94 ofcs.assign (tmp);
95 ++timeIndex;
96 dataIndex += nPhases * nSamples;
97 }
98 }
99 }
100
101 // Copy corrections
102 unsigned int ncorrs = persObj->m_subset.m_corrChannels.size();
104
105 if (ncorrs) {
106 // corrs exist - resize vector
107 std::vector<float> vSamples(nSamples, 0.0);
108 std::vector<std::vector<float> > vOFC(nPhases, vSamples);
109 LArOFCP1 larOFCP1(0.0, 0.0, vOFC, vOFC);
110
111 corrs.resize(ncorrs, LArOFCTransType::CorrectionPair(0, larOFCP1));
112 }
113
114 // Loop over corrections
115 for (unsigned int i = 0; i < ncorrs; ++i){
116 // check indexes
117 if (dataIndex >= persObj->m_vOFC_a.size() ||
118 dataIndex >= persObj->m_vOFC_b.size() ||
119 timeIndex >= persObj->m_timeOffset.size() ||
120 timeIndex >= persObj->m_timeBinWidth.size()) {
121 log << MSG::ERROR
122 << "LArOFCSubsetCnv_p1::persToTrans - ofc index too large: dataIndex size ofc_a, size ofc_b, timeIndex timeOffset size, timeBinWidth size "
123 << dataIndex << " " << persObj->m_vOFC_a.size() << " "
124 << persObj->m_vOFC_b.size() << " " << timeIndex << " "
125 << persObj->m_timeOffset.size() << " "
126 << persObj->m_timeBinWidth.size()
127 << endmsg;
128 return;
129 }
130
131 // copy channel id
132 corrs[i].first = persObj->m_subset.m_corrChannels[i];
133
134 LArOFCP1& ofcs = corrs[i].second;
135 LArOFCP1 tmp (persObj->m_timeOffset[timeIndex],
136 persObj->m_timeBinWidth[timeIndex],
137 nPhases,
138 nSamples,
139 persObj->m_vOFC_a,
140 persObj->m_vOFC_b,
141 dataIndex);
142 ofcs.setFrom (tmp);
143 ++timeIndex;
144 dataIndex += nPhases * nSamples;
145 }
146 transObj->insertCorrections (std::move (corrs));
147
148 transObj->shrink_to_fit();
149}
150
151
152void
154 LArOFCPersType* persObj,
155 MsgStream &log) const
156{
157 // Copy conditions
158
159 // We copy all ofcs into a few simple vectors.
160 // For the conditions, there are two situations to treat:
161 // 1) dense data: normal conditions where each feb has 128
162 // channels and all channels have data,
163 // 2) sparse data: conditions data where some channels are
164 // missing data. This is true for MC conditions (only some
165 // channels have data, and symmetry is used to obtain
166 // conditions for the rest of the channels), as well for
167 // 'normal' conditions it may happen that some channels may
168 // be missing data.
169 //
170 // Treating 1) is straight-forward. For 2) we need to keep track
171 // of which channels are present. We do so with
172 // m_subset.m_febsWithSparseData where we store the febid followed by
173 // four unsigned ints which contain the full bit pattern of the
174 // channels set (i.e. bits 0-127).
175 //
176 // Note that one may also have a subset with all channels missing
177 // data. In this case, we do not write out the empty subset.
178 //
179 // Finally, for corrections, we save the channel ids in
180 // m_subset.m_corrChannels and the ofcs in the same vectors as the
181 // rest of the conditions data.
182 //
183 // For each channel with data, the number of ofcs is assumed
184 // constant. This is calculated at the beginning, along with
185 // whether a feb is sparse or not.
186 //
187
188 // Get the number of channels, corrections and the size of ofc vectors
189 unsigned int nsubsetsNotEmpty = 0;
190 unsigned int ncorrs = transObj->correctionVecSize();
191 const unsigned int nChannelsPerFeb = transObj->channelVectorSize();
192 unsigned int nchans = 0;
193 unsigned int nPhases = 0;
194 unsigned int nSamples = 0;
195 bool foundOFCs = false;
196 std::vector<unsigned int> febsWithSparseData;
197
198 // Find the number of ofcs and check for sparse conditions,
199 // e.g. MC conditions
200 const auto subsetEnd = transObj->subsetEnd();
201 for (auto subsetIt = transObj->subsetBegin();
202 subsetIt != subsetEnd;
203 ++subsetIt)
204 {
205 unsigned int nfebChans = (*subsetIt).second.size();
206
207 if (nfebChans != 0 && nfebChans != nChannelsPerFeb) {
208 log << MSG::ERROR
209 << "LArOFCSubsetCnv_p1::transToPers - found incorrect number of channels per feb: " << nfebChans
210 << endmsg;
211 return;
212 }
213 if (nfebChans) ++nsubsetsNotEmpty; // count number of non-empty subsets
214
215 // Loop over channels and check if this subset has sparse data
216 bool subsetIsSparse = false;
217 for (unsigned int j = 0; j < nfebChans; ++j) {
219 (*subsetIt).second[j];
220 if (ofc.OFC_aSize() == 0) {
221 if (!subsetIsSparse) {
222 // save febids for sparse subsets
223 subsetIsSparse = true;
224 febsWithSparseData.push_back((*subsetIt).first);
225 }
226 }
227 else {
228 nchans++; // count number of channels
229 if (!foundOFCs) {
230 // Save the number of phases and samples for each
231 // ofc from first channels present
232 nPhases = ofc.OFC_aSize();
233 nSamples = ofc.OFC_a(0).size();
234 foundOFCs = true;
235 }
236 }
237 }
238 }
239 if (!foundOFCs && ncorrs>0) {
240 // Save the number of phases and samples for each ofc from
241 // first correction - couldn't find it from channels
242 const LArOFCP1& ofc = transObj->correctionVecBegin()->second;
243 nPhases = ofc.OFC_aSize();
244 nSamples = ofc.OFC_a(0).size();
245 }
246
247 // Save sizes
248 persObj->m_nPhases = nPhases;
249 persObj->m_nSamples = nSamples;
250
251 // Reserve space in vectors
252 persObj->m_subset.m_febIds.reserve(nsubsetsNotEmpty);
253 persObj->m_subset.m_corrChannels.reserve(ncorrs);
254 unsigned int ndataTot = (nchans + ncorrs)*nPhases*nSamples;
255 unsigned int nTime = (nchans + ncorrs);
256 persObj->m_vOFC_a.reserve(ndataTot);
257 persObj->m_vOFC_b.reserve(ndataTot);
258 persObj->m_timeOffset.reserve(nTime);
259 persObj->m_timeBinWidth.reserve(nTime);
260
261 // For subsets with sparse data, reserve space for identifying
262 // channels written out:
263 // 1 - febid
264 // 4 - for 128 bits (4*32)
265 if (febsWithSparseData.size())
266 persObj->m_subset.m_febsWithSparseData.reserve(febsWithSparseData.size()*5);
267
268 // Copy conditions in subset
269 unsigned int isparse = 0;
270 for (auto subsetIt = transObj->subsetBegin();
271 subsetIt != subsetEnd;
272 ++subsetIt)
273 {
274 unsigned int nfebChans = (*subsetIt).second.size();
275
276 // skip subsets without any channels
277 if (nfebChans == 0) continue;
278
279 unsigned int febid = (*subsetIt).first;
280 persObj->m_subset.m_febIds.push_back(febid);
281
282
283 bool isSparse = false;
284 if (isparse < febsWithSparseData.size() &&
285 febsWithSparseData[isparse] == febid) {
286 // sparse subset, save channels with data
287 isparse++;
288 isSparse = true;
289 // save febid
290 persObj->m_subset.m_febsWithSparseData.push_back(febid);
291 }
292
293 // Now loop over channels and save ofc and times
294 unsigned int chansSet = 0;
295 unsigned int chansOffset = 0;
296 for (unsigned int j = 0; j < nfebChans; ++j){
297
298 bool saveOFCs = true;
299 if (isSparse) {
300 // subset with sparse data
301 if ((*subsetIt).second[j].OFC_aSize() > 0) {
302 // store the channel number in bit map
303 assert (j >= chansOffset && (j - chansOffset) <= 31);
304 // coverity[integer_overflow]
305 chansSet |= (1 << (j - chansOffset));
306 }
307 else {
308 saveOFCs = false;
309 }
310 // Save chansSet
311 if (j == (chansOffset + 31) || j == nfebChans-1) {
312 persObj->m_subset.m_febsWithSparseData.push_back(chansSet);
313 chansSet = 0;
314 chansOffset += 32;
315 }
316 }
317 if (saveOFCs) {
318 bool tooSmall=false;
319 // Loop over phases and samples per channel
320 for (unsigned int k = 0; k < nPhases; ++k) {
321 for (unsigned int l = 0; l < nSamples; ++l) {
322 //check if data object is big enough
323 if (k >= (*subsetIt).second[j].OFC_aSize() ||
324 l >= (*subsetIt).second[j].OFC_a(k).size())
325 {
326 tooSmall=true;
327 persObj->m_vOFC_a.push_back(0.);
328 persObj->m_vOFC_b.push_back(0.);
329 }
330 else {
331 persObj->m_vOFC_a.push_back((*subsetIt).second[j].OFC_a(k)[l]);
332 persObj->m_vOFC_b.push_back((*subsetIt).second[j].OFC_b(k)[l]);
333// std::cout << "WL Data: FEB=" << std::hex << febid << std::dec << " [" << i << "] Channel="
334// << j << " Phase="<< k<< " Sample " << l << " OFC="
335// << (*subsetIt).second[j].m_vOFC_a[k][l] << std::endl;
336 }
337 }
338 }
339 // set time offset and binwidth
340 persObj->m_timeOffset.push_back((*subsetIt).second[j].timeOffset());
341 persObj->m_timeBinWidth.push_back((*subsetIt).second[j].timeBinWidth());
342 if (tooSmall)
343 log << MSG::ERROR << "Feb 0x" << std::hex << febid << std::dec << " channel " << j <<": OFC object too small. Expected "
344 << nPhases << " phases and " << nSamples << " samples. Padded with 0.0" << endmsg;
345
346 }// end if saveOFC
347
348// static unsigned int nch = 0;
349// ++nch;
350// std::cout << "transToPers - i, j, save " << i << " " << j << " "
351// << saveOFCs << " " << nch << " febid " << febid
352// << " chansSet " << std::hex << chansSet << std::dec
353// << " chansOffset " << chansOffset
354// << std::endl;
355
356 }
357 }
358
359 // Copy corrections
360 const auto corrEnd = transObj->correctionVecEnd();
361 for (auto corrIt = transObj->correctionVecBegin();
362 corrIt != corrEnd;
363 ++corrIt)
364 {
365 persObj->m_subset.m_corrChannels.push_back(corrIt->first);
366 // OFCs
367 bool tooSmall=false;
368 // Loop over phases and samples per channel
369 for (unsigned int k = 0; k < nPhases; ++k) {
370 for (unsigned int l = 0; l < nSamples; ++l) {
371 //check if data object is big enough
372 if (k >= corrIt->second.OFC_aSize() ||
373 l >= corrIt->second.OFC_a(k).size())
374 {
375 tooSmall=true;
376 persObj->m_vOFC_a.push_back(0.);
377 persObj->m_vOFC_b.push_back(0.);
378 }
379 else {
380 persObj->m_vOFC_a.push_back(corrIt->second.OFC_a(k)[l]);
381 persObj->m_vOFC_b.push_back(corrIt->second.OFC_b(k)[l]);
382 }
383 }
384 }
385 // set time offset and binwidth
386 persObj->m_timeOffset.push_back(corrIt->second.timeOffset());
387 persObj->m_timeBinWidth.push_back(corrIt->second.timeBinWidth());
388 if (tooSmall)
389 log << MSG::ERROR << "Correction (channel 0x" << std::hex << corrIt->first << std::dec <<
390 "): OFC object too small. Expected " << nPhases << " phases and " << nSamples << " samples. Padded with 0.0" << endmsg;
391 }
392
393 // Copy the rest
394 persObj->m_subset.m_gain = transObj->gain();
395 persObj->m_subset.m_channel = transObj->channel();
396 persObj->m_subset.m_groupingType = transObj->groupingType();
397
398}
#define endmsg
This file defines the template class used for I/O of conditions data.
LArOFCSubset_p1 LArOFCPersType
LArConditionsSubset< LArOFCP1 > LArOFCTransType
void setFrom(LAr2DWaveBase &other)
Assign from another wave object.
void assign(const LAr2DWaveBase &other)
Initialize the referenced data from a standalone object.
std::vector< unsigned int > m_febIds
std::vector< unsigned int > m_corrChannels
unsigned int subsetSize() const
std::vector< unsigned int > m_febsWithSparseData
std::pair< ChannelId, LArOFCP1 > CorrectionPair
Traits::ConstReference ConstReference
void initialize(const std::vector< FebId > &ids, unsigned int gain)
Initialize with set of FEB ids.
ConstSubsetIt subsetEnd() const
void shrink_to_fit()
Reallocate to match size actually used.
unsigned channelVectorSize() const
ConstCorrectionVecIt correctionVecBegin() const
Iterators over channel set.
unsigned int groupingType() const
Type of grouping - defined in LArConditionsContainerBase.h.
ConstCorrectionVecIt correctionVecEnd() const
void setGroupingType(unsigned int type)
set the type of grouping - defined in LArConditionsContainerBase.h
ConstSubsetIt subsetBegin() const
Iterators over subset.
unsigned int gain() const
Access to gain.
size_type correctionVecSize() const
Size of channel set.
std::vector< CorrectionPair > CorrectionVec
unsigned int channel() const
Access to the COOL channel number.
void insertCorrections(CorrectionVec &&corrs)
Insert a group of corrections.
void setChannel(unsigned int channel)
set the COOL channel number
c-struct reproducing the structure of the persistent data
Definition LArOFCP1.h:22
virtual void transToPers(const LArOFCTransType *transObj, LArOFCPersType *persObj, MsgStream &log) const override
virtual void persToTrans(const LArOFCPersType *persObj, LArOFCTransType *transObj, MsgStream &log) const override
std::vector< float > m_timeBinWidth
unsigned int m_nPhases
std::vector< float > m_vOFC_b
std::vector< float > m_timeOffset
std::vector< float > m_vOFC_a
unsigned int m_nSamples
LArConditionsSubset_p1 m_subset