ATLAS Offline Software
LArConditionsContainer.icc
Go to the documentation of this file.
1 //Dear emacs, this is -*- c++ -*-
2 
3 /*
4  Copyright (C) 2002-2020 CERN for the benefit of the ATLAS collaboration
5 */
6 
7 /**
8  * @file LArConditionContainer.icc
9  *
10  * @brief This file defines the methods for the template class
11  * LArConditionsContainer used for transient conditions data
12  *
13  * @author RD Schaffer <R.D.Schaffer@cern.ch>
14  * @author Hong Ma <hma@bnl.gov>
15  * @author Walter Lampl <wlampl@mail.cern.ch>
16  *
17  * $Id: LArConditionsContainer.icc,v 1.17 2009-04-23 09:19:22 wlampl Exp $
18  */
19 // Services/helpers
20 #include "LArIdentifier/LArOnlineID.h"
21 
22 #include <algorithm>
23 #include <deque>
24 //#include <typeinfo>
25 
26 
27 template<class T>
28 inline
29 LArConditionsContainer<T>::~LArConditionsContainer()
30 {}
31 
32 
33 template<class T>
34 inline
35 LArConditionsContainer<T>::LArConditionsContainer()
36  :
37  LArConditionsContainerBase(),
38  m_correctionsApplied(false)
39 
40 
41 {}
42 
43 template<class T>
44 inline
45 LArConditionsContainer<T>::LArConditionsContainer(GroupingType type)
46  :
47  LArConditionsContainerBase(type),
48  m_correctionsApplied(false)
49 
50 {}
51 
52 template<class T>
53 inline
54 typename LArConditionsContainer<T>::ConstReference
55 LArConditionsContainer<T>::empty() const
56 {
57  return Traits::empty();
58 }
59 
60 
61 template<class T>
62 inline
63 void
64 LArConditionsContainer<T>::sortSubsets()
65 {
66  // Sort subsets according to their channel number and refill the
67  // map from cool channel number to index
68 
69 
70 // typedef DataVector<Subset> SubsetDV;
71 // typedef typename SubsetDV::iterator iterator;
72 // iterator it = SubsetDV::begin();
73 // iterator itEnd = SubsetDV::end();
74 
75  this->sort (SubsetSort());
76 // std::sort (it, itEnd, SubsetSort());
77 
78  // Reset and refill cool channel numbers and lookup table
79  this->resetChannelNumbers();
80  m_channelToMultChanCollIndex = std::vector<unsigned int>(m_febIdChanMap.totalChannels(), 9999);
81  for (unsigned int i = 0; i < this->size(); ++i) {
82  unsigned int coolChannel = this->at(i)->channel();
83  m_channelToMultChanCollIndex[coolChannel] = i;
84  this->add(coolChannel);
85  }
86 
87 // for (unsigned int i = 0; i < this->size(); ++i) {
88 // unsigned int coolChannel = this->at(i)->channel();
89 // m_channelToMultChanCollIndex[coolChannel] = i;
90 // add(coolChannel);
91 // }
92 
93 
94 
95 
96 
97 }
98 
99 
100 template<class T>
101 inline
102 StatusCode
103 LArConditionsContainer<T>::updateConditionsMap(FebId febId, unsigned int gain,
104  ConditionsMap& conditionsMap)
105 {
106 
107  // The conditions map is not yet initialized for this
108  // FEB. Now find the conditions for this FEB in the
109  // LArConditionsSubsets, creating a new subset if
110  // necessary
111 
112  // Get COOL channel number and corresponding index into
113  // CondMultChanCollection vector
114  unsigned int coolChannel = 0;
115  unsigned int index;
116 
117 // std::cout << "LArConditionsContainer::updateConditionsMap: febid, gain, conditionmap size group type "
118 // << std::hex << febId << " " << std::dec
119 // << gain << " " << conditionsMap.size() << " " << m_groupType
120 // << std::endl;
121 
122  if (m_febIdChanMap.getChannel(febId, gain, coolChannel)) {
123 
124 // std::cout << "updateConditionsMap: coolChannel, index map size, chan size "
125 // << coolChannel << " " << m_channelToMultChanCollIndex.size()
126 // << " " << chan_size()
127 // << std::endl;
128 
129  // Get subset
130  Subset* subset = 0;
131 
132 
133  // Check whether cool channel has already been added
134  // to CondMultChanCollection
135  bool exist = false;
136  if (coolChannel < m_channelToMultChanCollIndex.size()) {
137  index = m_channelToMultChanCollIndex[coolChannel];
138  if (index < chan_size()) {
139  exist = true;
140  subset = this->at(index);
141  }
142  }
143  else {
144  std::cout << "LArConditionsContainer::updateConditionsMap: Invalid Cool channel: chan/max "
145  << coolChannel << " " << m_channelToMultChanCollIndex.size()
146  << std::endl;
147  return (StatusCode::FAILURE);
148  }
149 
150 
151  if (!exist) {
152  // Cool channel does not yet exist. Add new
153  // LArConditionsSubset to CondMultChanCollection
154  // and add setup the DB to point to new subset
155 
156  // add new subset
157  subset = new LArConditionsSubset<T>(m_febIdChanMap.febIdVector(gain, coolChannel), gain);
158  // Set attributes
159  subset->setGain(gain);
160  subset->setChannel(coolChannel);
161  subset->setGroupingType(m_groupType);
162  this->push_back(subset);
163  // sort the subsets, adding in the cool channel number as appropriate
164  sortSubsets();
165 
166 // std::cout << "updateConditionsMap: Added New Subset - gain, coolChannel, grouping type "
167 // << gain << " " << coolChannel << " " << m_groupType
168 // << std::endl;
169 
170  }
171 
172  // LArConditionsSubset exists, now find ChannelVector
173  // for FEB ID
174 
175  typename LArConditionsSubset<T>::SubsetIt subsetIt = subset->findChannelVector(febId);
176  if (subsetIt == subset->subsetEnd()) {
177  std::cout << " LArConditionsContainer::updateConditionsMap: unable to get ChannelVector for febId: febId/gain/index "
178  << std::hex << febId << " " << std::dec
179  << gain << " " << index
180  << std::endl;
181  return (StatusCode::FAILURE);
182  }
183 
184  // Now add pointer to ChannelVector to Conditions map DB
185  FebPairReference pair = *subsetIt;
186  conditionsMap.add(febId, &pair.second);
187 
188  }
189  else {
190  std::cout << " LArConditionsContainer::updateConditionsMap: unable to get channel: febid/gain "
191  << std::hex << febId << " " << std::dec << gain
192  << std::endl;
193  return (StatusCode::FAILURE);
194  }
195 
196  return (StatusCode::SUCCESS);
197 }
198 
199 template<class T>
200 inline
201 void
202 LArConditionsContainer<T>::setPdata(const HWIdentifier id,
203  const T& payload,
204  unsigned int gain )
205 {
206 // std::cout<<" LArConditionsContainer::setPdata 1 "
207 // << std::hex << id << " " << std::dec << gain << " " << this->size()
208 // << std::endl;
209 
210  unsigned int maxGain = m_febIdChanMap.minGain() + m_febIdChanMap.nGains();
211  if(gain < maxGain) {
212 
213 // std::cout<<" LArConditionsContainer::setPdata 2 "
214 // << std::hex << id << " " << std::dec << gain << " " << this->size()
215 // << " online helper " << m_onlineHelper
216 // << std::endl;
217 
218  // Extract FEB id and channel number from id
219  const unsigned int febId = m_onlineHelper->feb_Id(id).get_identifier32().get_compact();
220  const int febChannel = m_onlineHelper->channel(id);
221 
222 // std::cout<<" LArConditionsContainer::setPdata 3 "
223 // << std::hex << id << " " << std::dec << gain << " " << this->size()
224 // << std::endl;
225 
226  // Get cached conditions map DB for this gain, create if necessary
227  GainMapIterator gainMapIt = m_cached.find(gain);
228 
229 // std::cout<<" LArConditionsContainer::setPdata 4 "
230 // << std::hex << id << " " << std::dec << gain << " " << this->size()
231 // << std::endl;
232 
233  if(gainMapIt == m_cached.end()) {
234  // Insert new conditions map and set iterator
235 
236 // std::cout<<" LArConditionsContainer::setPdata: insert gain map "<<std::endl;
237 
238  gainMapIt = (m_cached.insert(GainPair(gain, ConditionsMap(gain)))).first;
239  }
240 
241 // std::cout<<" LArConditionsContainer::setPdata 5 "
242 // << std::hex << id << " " << std::dec << gain << " " << this->size()
243 // << std::endl;
244 
245  ConditionsMap& conditionsMap = (*gainMapIt).second;
246 
247 // std::cout<<" LArConditionsContainer::setPdata 6 "
248 // << std::hex << id << " " << std::dec << gain << " " << this->size()
249 // << std::endl;
250 
251  // Now see if FEB ID exists in DB, if not we must add it with
252  // a pointer the ChannelVector which is in one of the
253  // LArConditionsSubset. This may require to create the
254  // LArConditionsSubset.
255 
256  if (!(conditionsMap.exist(febId))) {
257 
258  // Initialize the conditions map for this feb id
259  StatusCode sc = updateConditionsMap(febId, gain, conditionsMap);
260  if (sc != StatusCode::SUCCESS) {
261  std::cout<<" LArConditionsContainer::setPdata: unable to updateConditionsMap "<<std::endl;
262  return;
263  }
264  }
265 
266  // Now add in the new payload
267  conditionsMap.set(febId,febChannel,payload);
268 
269  }
270  else {
271  std::cout<<" LArConditionsContainer::setPdata: Invalid Gain "<<std::endl;
272  }
273 }
274 
275 template<class T>
276 inline
277 typename LArConditionsContainer<T>::ConstReference
278 LArConditionsContainer<T>::get(const HWIdentifier id,
279  unsigned int gain) const
280 {
281  // Extract FEB id and channel number from id
282  const unsigned int febId = m_onlineHelper->feb_Id(id).get_identifier32().get_compact();
283  const int channel = m_onlineHelper->channel(id);
284 
285  // Get cached conditions map DB for this gain, create if necessary
286  ConstGainMapIterator it = m_cached.find(gain);
287  if(it!=m_cached.end()) {
288  return (*it).second.get(febId, channel);
289  }
290  else {
291  return (empty());
292  }
293 
294 }
295 
296 
297 template<class T>
298 inline
299 typename LArConditionsContainer<T>::Reference
300 LArConditionsContainer<T>::get(const HWIdentifier id,
301  unsigned int gain)
302 {
303  const unsigned int febId = m_onlineHelper->feb_Id(id).get_identifier32().get_compact();
304  const int channel = m_onlineHelper->channel(id);
305 
306  GainMapIterator gainMapIt = m_cached.find(gain);
307  if(gainMapIt == m_cached.end()) {
308  gainMapIt = (m_cached.insert(GainPair(gain,ConditionsMap(gain)))).first;
309  }
310  ConditionsMap& conditionsMap = (*gainMapIt).second;
311 
312  // Now see if FEB ID exists in DB, if not we must add it with
313  // a pointer the ChannelVector which is in one of the
314  // LArConditionsSubset. This may require to create the
315  // LArConditionsSubset.
316 
317  if (!conditionsMap.exist(febId)) {
318 
319  // Initialize the conditions map for this feb id
320  StatusCode sc = updateConditionsMap(febId, gain, conditionsMap);
321  if (sc != StatusCode::SUCCESS) {
322  throw std::runtime_error (" LArConditionsContainer::get: unable to updateConditionsMap ");
323  }
324  }
325 
326  return (gainMapIt->second.getNonConst(febId,channel));
327 }
328 
329 
330 template<class T>
331 inline
332 unsigned int
333 LArConditionsContainer<T>::coolChannel (const HWIdentifier id,
334  unsigned int gain) const
335 {
336  // Extract FEB id
337  const unsigned int febId = m_onlineHelper->feb_Id(id).get_identifier32().get_compact();
338  unsigned int coolChannel = 0;
339 
340  // Look for cool channel in map, == 9999 if not found
341  m_febIdChanMap.getChannel(febId, gain, coolChannel);
342  return (coolChannel);
343 }
344 
345 template<class T>
346 inline
347 unsigned int
348 LArConditionsContainer<T>::groupingType() const
349 {
350  return (m_groupType);
351 }
352 
353 template<class T>
354 inline
355 std::string
356 LArConditionsContainer<T>::groupingTypeToString() const
357 {
358  return (groupingTypeToString());
359 }
360 
361 
362 template<class T>
363 inline
364 unsigned int
365 LArConditionsContainer<T>::groupNumber(unsigned int coolChannel) const
366 {
367  return (m_febIdChanMap.groupNumber(coolChannel));
368 }
369 
370 template<class T>
371 inline
372 unsigned int
373 LArConditionsContainer<T>::nGroups() const
374 {
375  return (m_febIdChanMap.nGroups());
376 }
377 
378 template<class T>
379 inline
380 unsigned int
381 LArConditionsContainer<T>::minGain() const
382 {
383  return (m_febIdChanMap.minGain());
384 }
385 
386 template<class T>
387 inline
388 unsigned int
389 LArConditionsContainer<T>::nGains() const
390 {
391  return (m_febIdChanMap.nGains());
392 }
393 
394 
395 
396 template<class T>
397 inline
398 typename LArConditionsContainer<T>::chan_const_iterator
399 LArConditionsContainer<T>::chan_begin() const
400 {
401  return (MultChanCollection::chan_begin());
402 }
403 
404 template<class T>
405 inline
406 typename LArConditionsContainer<T>::chan_const_iterator
407 LArConditionsContainer<T>::chan_end () const
408 {
409  return (MultChanCollection::chan_end());
410 }
411 
412 template<class T>
413 inline
414 typename LArConditionsContainer<T>::chan_size_type
415 LArConditionsContainer<T>::chan_size() const
416 {
417  return (MultChanCollection::chan_size());
418 }
419 
420 template<class T>
421 inline
422 typename LArConditionsContainer<T>::iov_const_iterator
423 LArConditionsContainer<T>::iov_begin() const
424 {
425  return (MultChanCollection::iov_begin());
426 }
427 
428 template<class T>
429 inline
430 typename LArConditionsContainer<T>::iov_const_iterator
431 LArConditionsContainer<T>::iov_end () const
432 {
433  return (MultChanCollection::iov_end());
434 }
435 
436 template<class T>
437 inline
438 typename LArConditionsContainer<T>::iov_size_type
439 LArConditionsContainer<T>::iov_size() const
440 {
441  return (MultChanCollection::iov_size());
442 }
443 
444 template<class T>
445 inline
446 unsigned int
447 LArConditionsContainer<T>::conditionsPerChannel(unsigned int coolChannel) const
448 {
449  if (coolChannel < m_channelToMultChanCollIndex.size()) {
450  unsigned int index = m_channelToMultChanCollIndex[coolChannel];
451  if (index < chan_size()) {
452  // Subset exists
453  const Subset* subset = this->at(index);
454  return (subset->nConditions());
455  }
456  }
457  return (0); // not found
458 }
459 
460 
461 template<class T>
462 inline
463 unsigned int
464 LArConditionsContainer<T>::conditionsPerGroup(unsigned int group) const
465 {
466  unsigned int tot = 0;
467  const_iterator it = SubsetDV::begin();
468  const_iterator endIt = SubsetDV::end();
469  for (; it != endIt; ++it) {
470  const Subset* subset = (*it);
471  if (m_febIdChanMap.groupNumber(subset->channel()) == group) {
472  tot += subset->nConditions();
473  }
474  }
475  return (tot);
476 }
477 
478 
479 template<class T>
480 inline
481 unsigned int
482 LArConditionsContainer<T>::conditionsPerGain(unsigned int gain) const
483 {
484  unsigned int tot = 0;
485  const_iterator it = SubsetDV::begin();
486  const_iterator endIt = SubsetDV::end();
487  for (; it != endIt; ++it) {
488  const Subset* subset = (*it);
489  if ((unsigned int)subset->gain() == gain) {
490  tot += subset->nConditions();
491  }
492  }
493  return (tot);
494 }
495 
496 template<class T>
497 inline
498 unsigned int
499 LArConditionsContainer<T>::totalNumberOfConditions() const
500 {
501  unsigned int tot = 0;
502  const_iterator it = SubsetDV::begin();
503  const_iterator endIt = SubsetDV::end();
504  for (; it != endIt; ++it) {
505  tot += (*it)->nConditions();
506  }
507  return (tot);
508 }
509 
510 template<class T>
511 inline
512 unsigned int
513 LArConditionsContainer<T>::totalNumberOfCorrections() const
514 {
515  unsigned int tot = 0;
516  const_iterator it = SubsetDV::begin();
517  const_iterator endIt = SubsetDV::end();
518  for (; it != endIt; ++it) {
519  tot += (*it)->correctionVecSize();
520  }
521  return (tot);
522 }
523 
524 
525 
526  /// Have corrections been applied?
527 template<class T>
528 inline
529 bool
530 LArConditionsContainer<T>::correctionsApplied() const
531 {
532  return (m_correctionsApplied);
533 }
534 
535 
536 template<class T>
537 inline
538 StatusCode
539 LArConditionsContainer<T>::applyCorrections()
540 {
541  //const char* nameOfT=typeid(T).name();
542  //std::cout << "LArConditionsContainer<"<<nameOfT<<">::applyCorrections Applying corrections" << std::endl;
543  // Currently the logic is that one must undo corrections before
544  // one may reapply them
545  if (m_correctionsApplied) {
546  std::cout << "LArConditionsContainer<T>::applyCorrections: WARNING corrections already applied. NOT APPLYING THEM." << std::endl;
547  return (StatusCode::SUCCESS);
548  }
549 
550  // Save number of gain values and the minimum gain - not
551  // necessarily 0
552  const unsigned int nGains = m_febIdChanMap.nGains();
553  //const unsigned int minGain = m_febIdChanMap.minGain();
554  // Check whether CorrectionVector is correct size
555  if (m_correctionsUndo.size() < nGains) m_correctionsUndo.resize(nGains);
556 
557  m_correctionsApplied = true;
558 
559  std::deque<const Subset*> subsetsWithCorrections;
560 
561  //Loop over all underlying subsets
562  for (const Subset* subset : static_cast<MultChanCollection&>(*this)) {
563  if (subset->correctionVecSize()>0) { //Have corrections
564  if (subset->nConditions()==0) //Have only corrections -> apply at the end
565  subsetsWithCorrections.push_back(subset);
566  else //Corrections in regular subsets are applied first
567  subsetsWithCorrections.push_front(subset);
568  }
569  }
570 
571  for (const Subset* subset : subsetsWithCorrections) {
572  const int gain=subset->gain();
573  //std::cout << "Applying Corrections found in channel " << subset->channel() << std::endl;
574  GainMapIterator mapIt = m_cached.find(gain);
575  if (mapIt != m_cached.end()) {
576  ConditionsMap& conditionsMap = (*mapIt).second;
577 
578  CorrectionVector& undo = m_correctionsUndo[gain];
579  // Loop over corrections inside subset
580  ConstCorrectionVecIt itc = subset->correctionVecBegin();
581  ConstCorrectionVecIt itc_e = subset->correctionVecEnd();
582  for (;itc!=itc_e;++itc) {
583  const HWIdentifier id((*itc).first);
584  // Extract FEB id and channel number from id
585  const unsigned int febId = m_onlineHelper->feb_Id(id).get_identifier32().get_compact();
586  const int febChannel = m_onlineHelper->channel(id);
587 
588  if (conditionsMap.exist(febId)) {
589  // Save old value
590  T old = conditionsMap.get(febId, febChannel);
591  // Set new value
592  conditionsMap.set(febId, febChannel, (*itc).second);
593  // Save undo values
594  undo.push_back(CorrectionPair(id.get_identifier32().get_compact(), old));
595  }
596  }//end loop over corrections in this subset
597  }// end if find gain
598  }//end loop over subsets in deque
599 
600  return (StatusCode::SUCCESS);
601 }
602 
603 
604 template<class T>
605 inline
606 StatusCode
607 LArConditionsContainer<T>::undoCorrections()
608 {
609  // If correction not already applied, return
610  if (!m_correctionsApplied) {
611  std::cout << "LArConditionsContainer<T>::undoCorrections: WARNING corrections NOT already applied." << std::endl;
612  return (StatusCode::SUCCESS);
613  }
614 
615  m_correctionsApplied = false;
616 
617  // Save number of gain values and the minimum gain - not
618  // necessarily 0
619  unsigned int nGains = m_febIdChanMap.nGains();
620  unsigned int minGain = m_febIdChanMap.minGain();
621 
622  // Loop over the corrections for each gain and apply them to the
623  // corresponding subsets
624  for (unsigned int igain = 0; igain < nGains; ++igain) {
625 
626  unsigned int gain = igain + minGain; // gain value, not index
627 
628  // Get current corrections undo vector
629  CorrectionVector& undo = m_correctionsUndo[igain];
630 
631  // May not have all gains
632  GainMapIterator mapIt = m_cached.find(gain);
633  if (mapIt != m_cached.end()) {
634 
635  ConditionsMap& conditionsMap = (*mapIt).second;
636 
637  // Loop over undo corrections
638  ConstCorrectionIt it = undo.begin();
639  ConstCorrectionIt end = undo.end();
640  for (; it != end; ++it) {
641 
642  // Find the corresponding channel to correct,
643  // replace it and save overridden value
644  HWIdentifier id((*it).first);
645  // Extract FEB id and channel number from id
646  unsigned int febId = m_onlineHelper->feb_Id(id).get_identifier32().get_compact();
647  int febChannel = m_onlineHelper->channel(id);
648 
649  if (conditionsMap.exist(febId)) {
650  // Set undo value
651  conditionsMap.set(febId, febChannel, (*it).second);
652  }
653  }
654  }
655  // Reset undo vector
656  undo.clear();
657  }
658  return (StatusCode::SUCCESS);
659 }
660 
661 /*
662 
663 
664  The following methods are commented out because they don't work any more and/or don't
665  make sense any more since we have now the option to store corrections in the same subsets
666  as the regular data. (And not used anywhere anyway).
667 
668 
669 template<class T>
670 inline
671 typename LArConditionsContainer<T>::ConstCorrectionIt
672 LArConditionsContainer<T>::findCorrection (HWIdentifier channelId,
673  unsigned int gain) const
674 {
675  // Loop over corrections
676  std::vector<unsigned int> indexes;
677  correctionIndexes(gain, indexes);
678  for (unsigned int i = 0; i < indexes.size(); ++i) {
679  unsigned int index = indexes[i];
680  if (index < m_channelToMultChanCollIndex.size()) {
681  const Subset* corrections = this->at(index);
682  ConstCorrectionIt it = corrections->findConditionsObj(channelId);
683  if (it != corrections->correctionVecEnd()) return (it);
684  }
685  }
686  return (m_emptyCorrectionVec.end());
687 }
688 
689 template<class T>
690 inline
691 typename LArConditionsContainer<T>::ConstCorrectionIt
692 LArConditionsContainer<T>::findCorrectionEnd() const
693 {
694  // Simply return the empty end
695  return (m_emptyCorrectionVec.end());
696 }
697 
698 
699 template<class T>
700 inline
701 void
702 LArConditionsContainer<T>::correctionIndexes(unsigned int gain,
703  std::vector<unsigned int>& indexes) const
704 {
705  // Find indexed into data vector for the correction sets
706  indexes.clear();
707  std::vector<unsigned int> coolChannels;
708  if (m_febIdChanMap.getCorrectionSetChannels(gain, coolChannels)) {
709  // loop over cool channels and look for indexes
710  indexes.reserve(coolChannels.size());
711  for (unsigned int i = 0; i < coolChannels.size(); ++i) {
712  if (coolChannels[i] < m_channelToMultChanCollIndex.size()) {
713  indexes.push_back(m_channelToMultChanCollIndex[coolChannels[i]]);
714  }
715  }
716  }
717 }
718 
719 
720 template<class T>
721 inline
722 typename LArConditionsContainer<T>::ConstCorrectionIt
723 LArConditionsContainer<T>::correctionsBegin(unsigned int index) const
724 {
725  if (index < m_channelToMultChanCollIndex.size()) {
726  const Subset* corrections = this->at(index);
727  return (corrections->correctionVecBegin());
728  }
729  else {
730  return (m_emptyCorrectionVec.begin());
731  }
732 }
733 
734 template<class T>
735 inline
736 typename LArConditionsContainer<T>::ConstCorrectionIt
737 LArConditionsContainer<T>::correctionsEnd(unsigned int index) const
738 {
739  if (index < m_channelToMultChanCollIndex.size()) {
740  const Subset* corrections = this->at(index);
741  return (corrections->correctionVecEnd());
742  }
743  else {
744  return (m_emptyCorrectionVec.end());
745  }
746 }
747 
748 
749 template<class T>
750 inline
751 typename LArConditionsContainer<T>::size_type
752 LArConditionsContainer<T>::correctionsSize(unsigned int gain) const
753 {
754  // Loop over corrections
755  size_type ncorr = 0;
756  std::vector<unsigned int> indexes;
757  correctionIndexes(gain, indexes);
758  for (unsigned int i = 0; i < indexes.size(); ++i) {
759  unsigned int index = indexes[i];
760  if (index < m_channelToMultChanCollIndex.size()) {
761  const Subset* corrections = this->at(index);
762  ncorr += (corrections->correctionVecSize());
763  }
764  }
765  return (ncorr);
766 }
767 
768 */
769 
770 template<class T>
771 inline
772 std::vector<unsigned>
773 LArConditionsContainer<T>::completeCorrectionChannels() {
774 
775  std::vector<unsigned> result;
776 
777  typedef std::map<unsigned int,std::pair<HWIdentifier,unsigned> > INSERTMAP;
778  INSERTMAP idsToInsert;
779  typename MultChanCollection::const_iterator cit=MultChanCollection::begin();
780  typename MultChanCollection::const_iterator cit_e=MultChanCollection::end();
781  for(;cit!=cit_e;++cit) {
782  const unsigned gain=(*cit)->gain();
783  //msg << MSG::INFO << "Checking COOL channel " << (*it)->channel() << " Gain " << gain << endmsg;;
784  if ((*cit)->subsetBegin()!=(*cit)->subsetEnd()) { //not empty subset
785  const HWIdentifier febId((*(*cit)->subsetBegin()).first);
786  unsigned int index;
787  unsigned int coolChannel;
788  correctionIndexAndCoolChannel(febId, gain, index, coolChannel);
789  if (m_channelToMultChanCollIndex.size() <= index && idsToInsert.find(coolChannel)==idsToInsert.end()) {
790  //msg << MSG::WARNING << "Correction channel " << coolChannel << " does not exit" << endmsg;
791  idsToInsert[coolChannel]=std::make_pair(febId,gain);
792  }
793  }//end if non-empty subset
794  }//end loop over COOL channels
795 
796  INSERTMAP::const_iterator it1=idsToInsert.begin();
797  INSERTMAP::const_iterator it1_e=idsToInsert.end();
798  for (;it1!=it1_e;++it1) {
799  const unsigned gain=it1->second.second;
800  const int coolChannel=it1->first;
801  result.push_back(coolChannel);
802  //(*m_log) << MSG::INFO << "Inserting channel " << chid.get_compact() << " gain " << gain
803  // << " to create correction channel " << it1->first << endmsg;
804 
805  // index is size before new push_back
806  //index = chan_size();
807  // add new corrections subset
808  Subset* subset = new LArConditionsSubset<T>(gain);
809  // Set attributes
810  subset->setGain(gain);
811  subset->setChannel(coolChannel);
812  subset->setGroupingType(m_groupType);
813  this->push_back(subset);
814  }
815  // sort the subsets, adding in the cool channel number as appropriate
816  sortSubsets();
817 
818  return result;
819 }
820 
821 
822 template<class T>
823 inline
824 StatusCode
825 LArConditionsContainer<T>::insertCorrection (HWIdentifier id,
826  const T& cond,
827  unsigned int gain,
828  bool corrChannel /*=true*/)
829 {
830  unsigned int id32 = id.get_identifier32().get_compact();
831  if (corrChannel) {
832  unsigned int index;
833  unsigned int coolChannel;
834  correctionIndexAndCoolChannel(id, gain, index, coolChannel);
835 
836 // std::cout << "insertCorrection: Gain, index, size "
837 // << gain << " " << index << " "
838 // << m_channelToMultChanCollIndex.size() << " "
839 // << std::endl;
840 
841 
842  Subset* subset = 0;
843  if (m_channelToMultChanCollIndex.size() <= index) {
844  // Create new SubSet
845 
846  // index is size before new push_back
847  index = chan_size();
848  // add new corrections subset
849  subset = new LArConditionsSubset<T>(gain);
850  // Set attributes
851  subset->setGain(gain);
852  subset->setChannel(coolChannel);
853  subset->setGroupingType(m_groupType);
854  this->push_back(subset);
855  // sort the subsets, adding in the cool channel number as appropriate
856  sortSubsets();
857 
858 // std::cout << "insertCorrection - added subset : gain, index, coolchannel "
859 // << gain << " " << index << " " << coolChannel
860 // << std::endl;
861 
862  }
863  else {
864  subset = this->at(index);
865  }
866  //std::cout << "Inserting correction at correction channel " << subset->channel() << std::endl;
867  subset->insertCorrection(id32, cond);
868  }
869  else { //Store correction in regular subset
870  unsigned int febId = m_onlineHelper->feb_Id(id).get_identifier32().get_compact();
871  unsigned int coolChannel = 0;
872  if (m_febIdChanMap.getChannel(febId, gain, coolChannel)) {
873  if (coolChannel < m_channelToMultChanCollIndex.size()) {
874  const unsigned int index = m_channelToMultChanCollIndex[coolChannel];
875  Subset* subset = this->at(index);
876  //std::cout << "Inserting correction at regular channel " << subset->channel() << std::endl;
877  subset->insertCorrection(id32, cond);
878  // return StatusCode::SUCCESS;
879  }//end if coolChannel < size
880  else {
881  std::cout << "LArConditionsContainer::insertCorrection: ERROR COOL channel " << coolChannel << " does not exist."
882  << " Can't insert correction." << std::endl;
883  return StatusCode::FAILURE;
884  }
885  }//end if getChannel
886  else {
887  std::cout << "LArConditionsContainer::insertCorrection: ERROR Failed to get COOL channel for gain "
888  << gain << " channel " << id.get_compact() << std::endl;
889  return StatusCode::FAILURE;
890  }
891  }//end else corrChannel
892  return StatusCode::SUCCESS;
893 }
894 
895 
896 
897  ///get iterator over the Undo-Vector for a certain gain
898 template<class T>
899 typename LArConditionsContainer<T>::ConstCorrectionIt
900 LArConditionsContainer<T>::undoCorrBegin(unsigned int gain) const {
901  if (gain<m_correctionsUndo.size())
902  return m_correctionsUndo[gain].begin();
903  else
904  return m_dummyCorrIt;
905 }
906 
907 template<class T>
908 typename LArConditionsContainer<T>::ConstCorrectionIt
909 LArConditionsContainer<T>::undoCorrEnd(unsigned int gain) const {
910  if (gain<m_correctionsUndo.size())
911  return m_correctionsUndo[gain].end();
912  else
913  return m_dummyCorrIt;
914 
915 }
916 
917 
918 template<class T>
919 inline
920 typename LArConditionsContainer<T>::ConstConditionsMapIterator
921 LArConditionsContainer<T>::begin( unsigned int gain ) const
922 {
923  ConstGainMapIterator it = m_cached.find(gain) ;
924  if(it!=m_cached.end() ) {
925  return (*it).second.begin(m_onlineHelper);
926  }
927 
928  return ConstConditionsMapIterator() ;
929 
930 }
931 
932 template<class T>
933 inline
934 typename LArConditionsContainer<T>::ConditionsMapIterator
935 LArConditionsContainer<T>::begin( unsigned int gain )
936 {
937  GainMapIterator it = m_cached.find(gain) ;
938  if(it!=m_cached.end() ) {
939  return (*it).second.begin(m_onlineHelper);
940  }
941 
942  return ConditionsMapIterator() ;
943 
944 }
945 
946 template<class T>
947 inline
948 typename LArConditionsContainer<T>::ConstConditionsMapIterator
949 LArConditionsContainer<T>::begin(unsigned int gain,
950  const std::vector<FebId>& febIds) const
951 {
952 
953  ConstGainMapIterator it = m_cached.find(gain) ;
954  if(it!=m_cached.end() ) {
955  return (*it).second.begin(m_onlineHelper, febIds);
956  }
957 
958  return ConstConditionsMapIterator() ;
959 
960 }
961 
962 template<class T>
963 inline
964 typename LArConditionsContainer<T>::ConditionsMapIterator
965 LArConditionsContainer<T>::begin(unsigned int gain,
966  const std::vector<FebId>& febIds)
967 {
968 
969  GainMapIterator it = m_cached.find(gain) ;
970  if(it!=m_cached.end() ) {
971  return (*it).second.begin(m_onlineHelper, febIds);
972  }
973 
974  return ConditionsMapIterator() ;
975 
976 }
977 
978 template<class T>
979 inline
980 typename LArConditionsContainer<T>::ConstConditionsMapIterator
981 LArConditionsContainer<T>::begin(unsigned int gain,
982  const HWIdentifier& febId) const
983 {
984  std::vector<FebId> febIds { febId.get_identifier32().get_compact() };
985  return begin(gain, febIds);
986 }
987 
988 
989 template<class T>
990 inline
991 typename LArConditionsContainer<T>::ConditionsMapIterator
992 LArConditionsContainer<T>::begin(unsigned int gain,
993  const HWIdentifier& febId)
994 {
995  std::vector<FebId> febIds { febId.get_identifier32().get_compact() };
996  return begin(gain, febIds);
997 }
998 
999 
1000 template<class T>
1001 inline
1002 typename LArConditionsContainer<T>::ConstConditionsMapIterator
1003 LArConditionsContainer<T>::end( unsigned int gain ) const
1004 {
1005  ConstGainMapIterator it = m_cached.find(gain) ;
1006  if(it!=m_cached.end() ) {
1007  return (*it).second.end(m_onlineHelper);
1008  }
1009 
1010  return ConstConditionsMapIterator() ;
1011 }
1012 
1013 template<class T>
1014 inline
1015 typename LArConditionsContainer<T>::ConditionsMapIterator
1016 LArConditionsContainer<T>::end( unsigned int gain )
1017 {
1018  GainMapIterator it = m_cached.find(gain) ;
1019  if(it!=m_cached.end() ) {
1020  return (*it).second.end(m_onlineHelper);
1021  }
1022 
1023  return ConditionsMapIterator() ;
1024 }
1025 
1026 template<class T>
1027 void
1028 LArConditionsContainer<T>::removeConditions()
1029 {
1030  // Remove all subsets NOT in group == 0
1031  for (unsigned int i = 0; i < this->size(); ++i) {
1032  Subset* subset = this->at(i);
1033  if (0 != groupNumber(subset->channel()))delete subset;
1034  }
1035  // Reset cache
1036  m_cached.clear();
1037  // Reset the vector mapping the COOL channel to the DataVector.
1038  m_channelToMultChanCollIndex = std::vector<unsigned int>(m_febIdChanMap.totalChannels(), 9999);
1039 }
1040 
1041 /*
1042  The following methods are commented out because they don't work any more and/or don't
1043  make sense any more since we have now the option to store corrections in the same subsets
1044  as the regular data. (And not used anywhere anyway).
1045 
1046 template<class T>
1047 void
1048 LArConditionsContainer<T>::removeCorrections()
1049 {
1050  // Remove all subsets in group == 0 ONLY FOR OLD CORRECTIONS,
1051  // I.E. THE FIRST THREE CHANNELS
1052  for (unsigned int i = 0; i < this->size(); ++i) {
1053  Subset* subset = this->at(i);
1054  if (0 == groupNumber(subset->channel())) {
1055  delete subset;
1056  this->at(i) = 0;
1057  }
1058  }
1059 
1060  // Remove the new correction subsets for all gains
1061  unsigned int nGains = m_febIdChanMap.nGains();
1062  unsigned int minGain = m_febIdChanMap.minGain();
1063 
1064  for (unsigned int igain = 0; igain < nGains; ++igain) {
1065  unsigned int gain = igain + minGain; // gain value, not index
1066 
1067  // Loop over corrections
1068  std::vector<unsigned int> indexes;
1069  correctionIndexes(gain, indexes);
1070  for (unsigned int i = 0; i < indexes.size(); ++i) {
1071  unsigned int index = indexes[i];
1072  if (index < m_channelToMultChanCollIndex.size()) {
1073  const Subset* subset = this->at(index);
1074  delete subset;
1075  this->at(i) = 0;
1076  }
1077  }
1078  }
1079 }
1080 
1081 */
1082 
1083 template<class T>
1084 void
1085 LArConditionsContainer<T>::removeConditionsChannel(unsigned int coolChannel)
1086 {
1087 
1088  typename MultChanCollection::iterator it=MultChanCollection::begin();
1089  typename MultChanCollection::iterator it_e=MultChanCollection::end();
1090 
1091  for (;it!=it_e && coolChannel!=(*it)->channel();++it)
1092  ; //Search for COOL channel
1093 
1094  if (it!=it_e) { //found the channel
1095  const unsigned int gain = (*it)->gain();
1096  // Loop over FebIds and remove from DB map
1097  GainMapIterator gainMapIt = m_cached.find(gain);
1098  if(gainMapIt != m_cached.end()) {
1099  ConditionsMap& conditionsMap = (*gainMapIt).second;
1100  typename Subset::ConstSubsetIt first = (*it)->subsetBegin();
1101  typename Subset::ConstSubsetIt last = (*it)->subsetEnd();
1102  for (; first != last; ++first) {
1103  conditionsMap.erase((*first).first);
1104  }
1105  }
1106  if ((*it)->channel()<m_channelToMultChanCollIndex.size())
1107  m_channelToMultChanCollIndex[(*it)->channel()] = 9999;
1108  this->erase(it);
1109  }
1110 }
1111 
1112 template<class T>
1113 StatusCode
1114 LArConditionsContainer<T>::initialize()
1115 {
1116  if (!m_isInitialized) {
1117  // if this constainer has already been filled with subsets,
1118  // use them to define the grouping. This is needed when
1119  // subsets are read in
1120  if (this->size() == 0) {
1121  // Setup group mapping
1122  StatusCode sc = initializeBase();
1123  if (sc != StatusCode::SUCCESS) return (sc);
1124  }
1125  else {
1126  // only need to use the first one
1127  Subset* subset = this->at(0);
1128  //m_groupType = (int)subset->groupingType();
1129  if (subset->groupingType() == Unknown) {
1130  m_groupType = Unknown;
1131  }
1132  else if (subset->groupingType() == SingleGroup) {
1133  m_groupType = SingleGroup;
1134  }
1135  else if (subset->groupingType() == SubDetectorGrouping) {
1136  m_groupType = SubDetectorGrouping;
1137  }
1138  else if (subset->groupingType() == FeedThroughGrouping) {
1139  m_groupType = FeedThroughGrouping;
1140  }
1141  else if (subset->groupingType() == ExtendedFTGrouping) {
1142  m_groupType = ExtendedFTGrouping;
1143  }
1144  else if (subset->groupingType() == ExtendedSubDetGrouping) {
1145  m_groupType = ExtendedSubDetGrouping;
1146 
1147  }
1148  else if (subset->groupingType() == SuperCells) {
1149  m_groupType = SuperCells;
1150  }
1151 
1152 
1153  // Setup group mapping
1154  StatusCode sc = initializeBase();
1155  if (sc != StatusCode::SUCCESS) return (sc);
1156  // Setup index map
1157  chan_const_iterator it = chan_begin();
1158  chan_const_iterator itEnd = chan_end ();
1159  for (unsigned int i = 0; it != itEnd; ++i, ++it) {
1160  if ((*it) < m_channelToMultChanCollIndex.size()) {
1161  m_channelToMultChanCollIndex[*it] = i;
1162  }
1163  else {
1164  std::cout << "LArConditionsContainer<T>::initialize() - chan/index map too small - size, cool chan, index "
1165  << m_channelToMultChanCollIndex.size() << " "
1166  << (*it) << " "
1167  << i
1168  << std::endl;
1169  return (StatusCode::FAILURE);
1170  }
1171 
1172  // The conditions map is not yet initialized. For each
1173  // subset, add to the conditions map pointers to the
1174  // non-empty channel vectors and their feb ids.
1175  Subset* subset = this->at(i);
1176  unsigned int gain = subset->gain();
1177 
1178  // Get cached conditions map DB for this gain, create if necessary
1179  GainMapIterator gainMapIt = m_cached.find(gain);
1180  if(gainMapIt == m_cached.end()) {
1181  // Insert new conditions map and set iterator
1182  gainMapIt = (m_cached.insert(GainPair(gain, ConditionsMap(gain)))).first;
1183  }
1184  ConditionsMap& conditionsMap = (*gainMapIt).second;
1185 
1186  typename Subset::SubsetIt first = subset->subsetBegin();
1187  typename Subset::SubsetIt last = subset->subsetEnd();
1188  for (; first != last; ++first) {
1189 
1190  // select non-zero subsets
1191  if ((*first).second.size()) {
1192  // Now add pointer to ChannelVector to Conditions map DB
1193  FebPairReference pair = *first;
1194  conditionsMap.add(pair.first, &pair.second);
1195  }
1196  }
1197  }//end loop over COOL channels
1198  //When reading in from DB we apply corrections at init
1199  // unless explicilty inhibeted. Check static flag first
1200  if (applyCorrectionsAtInit()) {
1201  StatusCode sc=applyCorrections();
1202  if (sc != StatusCode::SUCCESS) return (sc);
1203  }
1204  }//end else have subsets
1205  }//end if isInitialized()
1206 
1207  return (StatusCode::SUCCESS);
1208 }
1209 
1210 
1211 
1212 template<class T>
1213 bool LArConditionsContainer<T>::merge(const LArConditionsContainer<T>& other) {
1214  unsigned nOverwrites=0;
1215  //Loop over gains
1216  for (unsigned gain=0;gain<other.nGains();++gain) {
1217  auto it=other.begin(gain);
1218  auto it_e=other.end(gain);
1219  //Loop over channels
1220  for (;it!=it_e;++it) {
1221  const HWIdentifier hwid=it.channelId();
1222  const T& payload=*it;
1223  if (!payload.isEmpty()) {
1224  const T& currentPayload=const_cast<const LArConditionsContainer<T>* >(this) -> get(hwid,gain);
1225  if (!currentPayload.isEmpty()) {
1226  ++nOverwrites;
1227  }
1228  this->setPdata(hwid,payload,gain);
1229  }
1230  }//end loop over channels
1231  }//end loop over gains
1232  return (nOverwrites!=0);
1233 }