ATLAS Offline Software
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 
8 void
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 
152 void
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 }
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
LArOFCSubset_p1::m_timeOffset
std::vector< float > m_timeOffset
Definition: LArOFCSubset_p1.h:38
LArOFCP1
c-struct reproducing the structure of the persistent data
Definition: LArOFCP1.h:22
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
LArOFCSubset_p1::m_nPhases
unsigned int m_nPhases
Definition: LArOFCSubset_p1.h:40
LArOFCSubset_p1::m_subset
LArConditionsSubset_p1 m_subset
Definition: LArOFCSubset_p1.h:35
LArConditionsSubset::channelVectorSize
unsigned channelVectorSize() const
Definition: LArConditionsSubset.h:608
LAr2DWaveBase::setFrom
void setFrom(LAr2DWaveBase &other)
Assign from another wave object.
Definition: LAr2DWaveBase.cxx:109
LArOFCSubsetCnv_p1::persToTrans
virtual void persToTrans(const LArOFCPersType *persObj, LArOFCTransType *transObj, MsgStream &log) const override
Definition: LArOFCSubsetCnv_p1.cxx:9
LArConditionsSubset_p1::subsetSize
unsigned int subsetSize() const
Definition: LArConditionsSubset_p1.h:82
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
LArOFCSubset_p1::m_vOFC_b
std::vector< float > m_vOFC_b
Definition: LArOFCSubset_p1.h:37
LArOFCSubset_p1::m_timeBinWidth
std::vector< float > m_timeBinWidth
Definition: LArOFCSubset_p1.h:39
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
LArOFCSubset_p1::m_vOFC_a
std::vector< float > m_vOFC_a
Definition: LArOFCSubset_p1.h:36
LArConditionsSubset::CorrectionVec
std::vector< CorrectionPair > CorrectionVec
Definition: LArConditionsSubset.h:144
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
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
LArOFCSubsetCnv_p1::transToPers
virtual void transToPers(const LArOFCTransType *transObj, LArOFCPersType *persObj, MsgStream &log) const override
Definition: LArOFCSubsetCnv_p1.cxx:153
LArOFCSubset_p1
persistent class container of LArConditionsSubset for LArOFC data.
Definition: LArOFCSubset_p1.h:30
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
LArConditionsSubset::gain
unsigned int gain() const
Access to gain.
Definition: LArConditionsSubset.h:490
LArOFCSubsetCnv_p1.h
LArConditionsSubset::correctionVecSize
size_type correctionVecSize() const
Size of channel set.
Definition: LArConditionsSubset.h:481
python.CaloCondTools.log
log
Definition: CaloCondTools.py:20
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
LArOFCSubset_p1::m_nSamples
unsigned int m_nSamples
Definition: LArOFCSubset_p1.h:41
LArConditionsSubset::subsetEnd
ConstSubsetIt subsetEnd() const
Definition: LArConditionsSubset.h:420
ReadOfcFromCool.ofc
ofc
Definition: ReadOfcFromCool.py:110
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