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