ATLAS Offline Software
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 
8 void
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 
168 void
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 }
LArConditionsSubset::setGroupingType
void setGroupingType(unsigned int type)
set the type of grouping - defined in LArConditionsContainerBase.h
Definition: LArConditionsSubset.h:575
LArConditionsSubset_p1::m_channel
unsigned int m_channel
Definition: LArConditionsSubset_p1.h:79
LArShapeSubset_p2::m_timeOffset
std::vector< float > m_timeOffset
Definition: LArShapeSubset_p2.h:38
LArConditionsSubset_p1::m_corrChannels
std::vector< unsigned int > m_corrChannels
Definition: LArConditionsSubset_p1.h:76
LArConditionsSubset_p1::m_febsWithSparseData
std::vector< unsigned int > m_febsWithSparseData
Definition: LArConditionsSubset_p1.h:77
LArShapeSubsetCnv_p2::persToTrans
virtual void persToTrans(const LArShapePersType2 *persObj, LArShapeTransType2 *transObj, MsgStream &log) const override
Definition: LArShapeSubsetCnv_p2.cxx:9
LArConditionsSubset::channelVectorSize
unsigned channelVectorSize() const
Definition: LArConditionsSubset.h:608
LAr2DWaveBase::setFrom
void setFrom(LAr2DWaveBase &other)
Assign from another wave object.
Definition: LAr2DWaveBase.cxx:109
LArConditionsSubset_p1::subsetSize
unsigned int subsetSize() const
Definition: LArConditionsSubset_p1.h:82
LArShapeSubsetCnv_p2.h
UploadAMITag.l
list l
Definition: UploadAMITag.larcaf.py:157
LArConditionsSubset::shrink_to_fit
void shrink_to_fit()
Reallocate to match size actually used.
Definition: LArConditionsSubset.h:550
LArConditionsSubset_p1::m_gain
unsigned int m_gain
Definition: LArConditionsSubset_p1.h:78
LArConditionsSubset::correctionVecEnd
ConstCorrectionVecIt correctionVecEnd() const
Definition: LArConditionsSubset.h:472
LArConditionsSubset_p1::m_febIds
std::vector< unsigned int > m_febIds
Definition: LArConditionsSubset_p1.h:75
LArConditionsSubset::initialize
void initialize(const std::vector< FebId > &ids, unsigned int gain)
Initialize with set of FEB ids.
Definition: LArConditionsSubset.h:529
LArShapeSubset_p2::m_nSamples
unsigned int m_nSamples
Definition: LArShapeSubset_p2.h:41
LArShapeSubset_p2::m_timeBinWidth
std::vector< float > m_timeBinWidth
Definition: LArShapeSubset_p2.h:39
LArConditionsSubset::CorrectionVec
std::vector< CorrectionPair > CorrectionVec
Definition: LArConditionsSubset.h:144
LArShapeSubsetCnv_p2::transToPers
virtual void transToPers(const LArShapeTransType2 *transObj, LArShapePersType2 *persObj, MsgStream &log) const override
Definition: LArShapeSubsetCnv_p2.cxx:169
LArShapeSubset_p2::m_nPhases
unsigned int m_nPhases
Definition: LArShapeSubset_p2.h:40
lumiFormat.i
int i
Definition: lumiFormat.py:85
endmsg
#define endmsg
Definition: AnalysisConfig_Ntuple.cxx:63
LArConditionsSubset_p1::m_groupingType
unsigned int m_groupingType
Definition: LArConditionsSubset_p1.h:80
LArConditionsSubset::channel
unsigned int channel() const
Access to the COOL channel number.
Definition: LArConditionsSubset.h:498
LArShapeSubset_p2
persistent class container of LArConditionsSubset for LArShape data.
Definition: LArShapeSubset_p2.h:30
DeMoUpdate.tmp
string tmp
Definition: DeMoUpdate.py:1167
LArConditionsSubset::setChannel
void setChannel(unsigned int channel)
set the COOL channel number
Definition: LArConditionsSubset.h:567
LArConditionsSubset::ConstReference
Traits::ConstReference ConstReference
Definition: LArConditionsSubset.h:136
LArConditionsSubset
template class for use for I/O of conditions data
Definition: LArConditionsSubset.h:122
LArConditionsSubset.h
This file defines the template class used for I/O of conditions data.
LArConditionsSubset::CorrectionPair
std::pair< ChannelId, T > CorrectionPair
Definition: LArConditionsSubset.h:143
LArShapeP2
c-struct reproducing the structure of the persistent data
Definition: LArShapeP2.h:21
LArShapeSubset_p2::m_vShapeDer
std::vector< float > m_vShapeDer
Definition: LArShapeSubset_p2.h:37
LArShapeP2::shape
ShapeRef_t shape(size_t tbin) const
Definition: LArShapeP2.h:44
LArShapeSubset_p2::m_vShape
std::vector< float > m_vShape
Definition: LArShapeSubset_p2.h:36
LArConditionsSubset::gain
unsigned int gain() const
Access to gain.
Definition: LArConditionsSubset.h:490
LArConditionsSubset::correctionVecSize
size_type correctionVecSize() const
Size of channel set.
Definition: LArConditionsSubset.h:481
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
LArShapeSubset_p2::m_subset
LArConditionsSubset_p1 m_subset
Definition: LArShapeSubset_p2.h:35
LArShapeP2::shapeSize
size_t shapeSize() const
Definition: LArShapeP2.h:41
LArConditionsSubset::Reference
Traits::Reference Reference
Definition: LArConditionsSubset.h:135
LArDigits2NtupleDumper.nSamples
nSamples
Definition: LArDigits2NtupleDumper.py:85
LArConditionsSubset::subsetBegin
ConstSubsetIt subsetBegin() const
Iterators over subset.
Definition: LArConditionsSubset.h:412
LArConditionsSubset::subsetEnd
ConstSubsetIt subsetEnd() const
Definition: LArConditionsSubset.h:420
LArConditionsSubset::correctionVecBegin
ConstCorrectionVecIt correctionVecBegin() const
Iterators over channel set.
Definition: LArConditionsSubset.h:465
LArConditionsSubset::insertCorrections
void insertCorrections(CorrectionVec &&corrs)
Insert a group of corrections.
Definition: LArConditionsSubset.h:593
fitman.k
k
Definition: fitman.py:528
LArConditionsSubset::groupingType
unsigned int groupingType() const
Type of grouping - defined in LArConditionsContainerBase.h.
Definition: LArConditionsSubset.h:507