ATLAS Offline Software
Loading...
Searching...
No Matches
LArShapeSubsetCnv_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 LArShapeTransType1* transObj,
11 MsgStream & log) const
12{
13 transObj->initialize (persObj->m_subset.m_febIds, persObj->m_subset.m_gain);
14
15 // Copy conditions
16 unsigned int nfebids = persObj->m_subset.m_febIds.size();
17 unsigned int nShapes = persObj->m_vShapeSize;
18 unsigned int nShapeDers = persObj->m_vShapeDerSize;
19 unsigned int shapeIndex = 0;
20 unsigned int shapederIndex = 0;
21 const unsigned int nChannelsPerFeb = persObj->m_subset.subsetSize();
22 // Loop over febs
23 unsigned int ifebWithData = 0; // counter for febs with data
24
25 auto subsetIt = transObj->subsetBegin();
26 for (unsigned int i = 0; i < nfebids; ++i, ++subsetIt){
27 // Set febid
28 unsigned int febid = subsetIt->first;
29
30 bool hasSparseData = false;
31 unsigned int chansSet = 0;
32 unsigned int chansOffset = 0;
33 if (ifebWithData+1 < persObj->m_subset.m_febsWithSparseData.size() &&
34 febid == persObj->m_subset.m_febsWithSparseData[ifebWithData]) {
35 // Found feb with sparse data
36 hasSparseData = true;
37 ifebWithData++;
38 chansSet = persObj->m_subset.m_febsWithSparseData[ifebWithData];
39 chansOffset = 0;
40 ifebWithData++;
41 }
42
43 // Loop over channels in feb - only some channels are filled
44 for (unsigned int j = 0; j < nChannelsPerFeb; ++j){
45
46 bool copyChannel = true;
47 if (hasSparseData) {
48 // coverity[bad_shift]
49 // coverity[integer_overflow]
50 if (!(chansSet & (1 << (j - chansOffset)))) {
51 // Channel is missing data - skip
52 copyChannel = false;
53 }
54 if (j%32 == 31 && j < nChannelsPerFeb-2) {
55 chansSet = persObj->m_subset.m_febsWithSparseData[ifebWithData];
56 chansOffset += 32;
57 ifebWithData++;
58 }
59 }
60 if (copyChannel) {
61
62 // Channel has shapes - loop over shapes per channel
63 // and copy to the persistent object
64
65 // check indexes
66 if (shapeIndex >= persObj->m_vShape.size() ||
67 shapederIndex >= persObj->m_vShapeDer.size()) {
68 log << MSG::ERROR
69 << "LArShapeSubsetCnv_p1::persToTrans - shape index too large: shape/size, shapeder/size "
70 << shapeIndex << " " << persObj->m_vShape.size() << " "
71 << shapederIndex << " " << persObj->m_vShapeDer.size()
72 << endmsg;
73 return;
74 }
75
76 // This channel has shapes, resize vectors
77 subsetIt->second[j].m_vShape.resize(nShapes);
78 subsetIt->second[j].m_vShapeDer.resize(nShapeDers);
79
80 for (unsigned int k = 0; k < persObj->m_vShapeSize; ++k){
81 subsetIt->second[j].m_vShape[k] = persObj->m_vShape[shapeIndex];
82 shapeIndex++;
83 }
84 // Loop over shapeders per channel
85 for (unsigned int k = 0; k < persObj->m_vShapeDerSize; ++k){
86 subsetIt->second[j].m_vShapeDer[k] = persObj->m_vShapeDer[shapederIndex];
87 shapederIndex++;
88 }
89 }
90
91// static unsigned int nch1 = 0;
92// ++nch1;
93// std::cout << "persToTrans - i, j, copy " << i << " " << j << " "
94// << copyChannel << " " << (chansSet & (1 << (j + chansOffset))) << " "
95// << (chansSet & (1 << (j - chansOffset))) << " "
96// << nch1
97// << " hasSparseData " << hasSparseData
98// << " chansSet, chansOffset, ifebWithData " << std::hex
99// << chansSet << std::dec << " " << chansOffset << " " << ifebWithData
100// << " febids " << febid
101// << std::endl;
102
103 }
104 }
105
106 // Copy corrections
107 unsigned int ncorrs = persObj->m_subset.m_corrChannels.size();
109
110 if (ncorrs) {
111 // corrs exist - resize vector
112 std::vector<float> vShape(nShapes,0.0);
113 std::vector<float> vShapeDer(nShapeDers,0.0);
114 LArShapeP1 larShapeP1(vShape, vShapeDer);
115
116 corrs.resize(ncorrs, LArShapeTransType1::CorrectionPair(0, larShapeP1));
117 }
118
119 // Loop over corrections
120 for (unsigned int i = 0; i < ncorrs; ++i){
121 // check indexes
122 if (shapeIndex >= persObj->m_vShape.size() ||
123 shapederIndex >= persObj->m_vShapeDer.size()) {
124 log << MSG::ERROR
125 << "LArShapeSubsetCnv_p1::persToTrans - shape index too large: shape/size, shapeder/size "
126 << shapeIndex << " " << persObj->m_vShape.size() << " "
127 << shapederIndex << " " << persObj->m_vShapeDer.size()
128 << endmsg;
129 return;
130 }
131 corrs[i].first = persObj->m_subset.m_corrChannels[i];
132 // Loop over shapes per channel
133 for (unsigned int k = 0; k < persObj->m_vShapeSize; ++k){
134 corrs[i].second.m_vShape[k] = persObj->m_vShape[shapeIndex];
135 shapeIndex++;
136 }
137 // Loop over shapeders per channel
138 for (unsigned int k = 0; k < persObj->m_vShapeDerSize; ++k){
139 corrs[i].second.m_vShapeDer[k] = persObj->m_vShapeDer[shapederIndex];
140 shapederIndex++;
141 }
142 }
143 transObj->insertCorrections (std::move (corrs));
144
145 // Copy the rest
146 transObj->setChannel (persObj->m_subset.m_channel);
147 transObj->setGroupingType (persObj->m_subset.m_groupingType);
148}
149
150
151
152
153void
155 LArShapePersType1* persObj,
156 MsgStream &log) const
157{
158 // Copy conditions
159
160 // We copy all shapes into a single vector and the same for
161 // shaperDers.
162 // For the conditions, there are two situations to treat:
163 // 1) dense data: normal conditions where each feb has 128
164 // channels and all channels have data,
165 // 2) sparse data: conditions data where some channels are
166 // missing data. This is true for MC conditions (only some
167 // channels have data, and symmetry is used to obtain
168 // conditions for the rest of the channels), as well for
169 // 'normal' conditions it may happen that some channels may
170 // be missing data.
171 //
172 // Treating 1) is straight-forward. For 2) we need to keep track
173 // of which channels are present. We do so with
174 // m_subset.m_febsWithSparseData where we store the febid followed by
175 // four unsigned ints which contain the full bit pattern of the
176 // channels set (i.e. bits 0-127).
177 //
178 // Note that one may also have a subset with all channels missing
179 // data. In this case, we do not write out the empty subset.
180 //
181 // Finally, for corrections, we save the channel ids in
182 // m_subset.m_corrChannels and the shapes and shapeders in the
183 // same vectors as the rest of the conditions data.
184 //
185 // For each channel with data, the number of shapes and shape
186 // derivatives is assumed constant. This is calculated at the
187 // beginning, along with whether a feb is sparse or not.
188 //
189
190 // Get the number of channels, corrections and the size of shape and shapeder
191 unsigned int nsubsetsNotEmpty = 0;
192 unsigned int ncorrs = transObj->correctionVecSize();
193 unsigned int nchans = 0;
194 unsigned int nShapes = 0;
195 unsigned int nShapeDers = 0;
196 bool foundNShapes = false;
197 std::vector<unsigned int> febsWithSparseData;
198 const unsigned int nChannelsPerFeb = transObj->channelVectorSize();
199 // Find the number of shapes/shapeders and check for sparse
200 // conditions, e.g. MC conditions
201 const auto subsetEnd = transObj->subsetEnd();
202 for (auto subsetIt = transObj->subsetBegin();
203 subsetIt != subsetEnd;
204 ++subsetIt)
205 {
206 unsigned int nfebChans = subsetIt->second.size();
207
208 if (nfebChans != 0 && nfebChans != nChannelsPerFeb) {
209 log << MSG::ERROR
210 << "LArShapeSubsetCnv_p1::transToPers - found incorrect number of channels per feb: " << nfebChans
211 << endmsg;
212 return;
213 }
214 if (nfebChans) ++nsubsetsNotEmpty; // count number of non-empty subsets
215
216 // Loop over channels and check if this subset has sparse data
217 bool subsetIsSparse = false;
218 for (unsigned int j = 0; j < nfebChans; ++j) {
219 const LArShapeP1& shape = subsetIt->second[j];
220 if (shape.m_vShape.size() == 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 (!foundNShapes) {
230 // Save the number of shapes and derivatives from first channels present
231 nShapes = shape.m_vShape.size();
232 nShapeDers = shape.m_vShapeDer.size();
233 foundNShapes = true;
234 }
235 }
236 }
237 }
238 if (!foundNShapes && ncorrs > 0) {
239 // Save the number of shapes and derivatives from first
240 // correct - couldn't find it from channels
241 const LArShapeP1& shape = transObj->correctionVecBegin()->second;
242 nShapes = shape.m_vShape.size();
243 nShapeDers = shape.m_vShapeDer.size();
244 }
245 if (nShapes == 0 && nShapeDers == 0) {
246 log << MSG::ERROR
247 << "LArShapeSubsetCnv_p1::transToPers - cannot get number of shapes and shape derivatives"
248 << endmsg;
249 return;
250 }
251
252 // Save sizes
253 persObj->m_vShapeSize = nShapes;
254 persObj->m_vShapeDerSize = nShapeDers;
255
256 // Reserve space in vectors
257 persObj->m_subset.m_febIds.reserve(nsubsetsNotEmpty);
258 persObj->m_subset.m_corrChannels.reserve(ncorrs);
259 unsigned int nShapesTot = (nchans + ncorrs)*nShapes;
260 unsigned int nShapeDersTot = (nchans + ncorrs)*nShapeDers;
261 persObj->m_vShape.reserve(nShapesTot);
262 persObj->m_vShapeDer.reserve(nShapeDersTot);
263
264 // For subsets with sparse data, reserve space for identifying
265 // channels written out:
266 // 1 - febid
267 // 4 - for 128 bits (4*32)
268 if (febsWithSparseData.size())
269 persObj->m_subset.m_febsWithSparseData.reserve(febsWithSparseData.size()*5);
270
271 // Copy conditions in subset
272 unsigned int isparse = 0;
273 for (auto subsetIt = transObj->subsetBegin();
274 subsetIt != subsetEnd;
275 ++subsetIt)
276 {
277 unsigned int nfebChans = subsetIt->second.size();
278
279 // skip subsets without any channels
280 if (nfebChans == 0) continue;
281
282 unsigned int febid = subsetIt->first;
283 persObj->m_subset.m_febIds.push_back(febid);
284
285
286 bool isSparse = false;
287 if (isparse < febsWithSparseData.size() &&
288 febsWithSparseData[isparse] == febid) {
289 // sparse subset, save channels with data
290 isparse++;
291 isSparse = true;
292 // save febid
293 persObj->m_subset.m_febsWithSparseData.push_back(febid);
294 }
295
296 // Now loop over channels and save shapes/shapeders and
297 // channel number
298 unsigned int chansSet = 0;
299 unsigned int chansOffset = 0;
300 for (unsigned int j = 0; j < nfebChans; ++j){
301
302 bool saveShapes = true;
303 if (isSparse) {
304 // subset with sparse data
305
306 if (subsetIt->second[j].m_vShape.size() > 0) {
307 // store the channel number in bit map
308 assert (j >= chansOffset && (j - chansOffset) <= 31);
309 // coverity[integer_overflow]
310 chansSet |= (1 << (j - chansOffset));
311 }
312 else {
313 saveShapes = false;
314 }
315 // Save chansSet
316 if (j == (chansOffset + 31) || j == nfebChans-1) {
317 persObj->m_subset.m_febsWithSparseData.push_back(chansSet);
318 chansSet = 0;
319 chansOffset += 32;
320 }
321 }
322 if (saveShapes) {
323 // save shapes
324 for (unsigned int k = 0; k < nShapes; ++k){
325 persObj->m_vShape.push_back(subsetIt->second[j].m_vShape[k]);
326 }
327 // save shapeders
328 for (unsigned int k = 0; k < nShapeDers; ++k){
329 persObj->m_vShapeDer.push_back(subsetIt->second[j].m_vShapeDer[k]);
330 }
331 }
332
333// static unsigned int nch = 0;
334// ++nch;
335// std::cout << "transToPers - i, j, save " << i << " " << j << " "
336// << saveShapes << " " << nch << " febid " << febid
337// << " chansSet " << std::hex << chansSet << std::dec
338// << " chansOffset " << chansOffset
339// << std::endl;
340
341 }
342 }
343
344 // Copy corrections
345 const auto corrEnd = transObj->correctionVecEnd();
346 for (auto corrIt = transObj->correctionVecBegin();
347 corrIt != corrEnd;
348 ++corrIt)
349 {
350 // Save channel id in febid vector
351 persObj->m_subset.m_corrChannels.push_back(corrIt->first);
352 // Shapes
353 for (unsigned int k = 0; k < nShapes; ++k){
354 persObj->m_vShape.push_back(corrIt->second.m_vShape[k]);
355 }
356 // ShapeDers
357 for (unsigned int k = 0; k < nShapeDers; ++k){
358 persObj->m_vShapeDer.push_back(corrIt->second.m_vShapeDer[k]);
359 }
360 }
361
362 // Copy the rest
363 persObj->m_subset.m_gain = transObj->gain();
364 persObj->m_subset.m_channel = transObj->channel();
365 persObj->m_subset.m_groupingType = transObj->groupingType();
366}
#define endmsg
This file defines the template class used for I/O of conditions data.
LArShapeSubset_p1 LArShapePersType1
LArConditionsSubset< LArShapeP1 > LArShapeTransType1
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, LArShapeP1 > CorrectionPair
void initialize(const std::vector< FebId > &ids, unsigned int gain)
Initialize with set of FEB ids.
ConstSubsetIt subsetEnd() const
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 LArShapeP1.h:16
std::vector< float > m_vShapeDer
Definition LArShapeP1.h:25
std::vector< float > m_vShape
Definition LArShapeP1.h:24
virtual void persToTrans(const LArShapePersType1 *persObj, LArShapeTransType1 *transObj, MsgStream &log) const override
virtual void transToPers(const LArShapeTransType1 *transObj, LArShapePersType1 *persObj, MsgStream &log) const override
unsigned int m_vShapeDerSize
std::vector< float > m_vShape
unsigned int m_vShapeSize
std::vector< float > m_vShapeDer
LArConditionsSubset_p1 m_subset