diff --git a/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Decoder.h b/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Decoder.h index 87150e0c552cf97a02eefa15ff912eeaa433ff3f..91d82bc2fc97e07e11e66318354ab2591d17902b 100644 --- a/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Decoder.h +++ b/TileCalorimeter/TileSvc/TileByteStream/TileByteStream/TileROD_Decoder.h @@ -10,6 +10,7 @@ #include <string> #include <iostream> #include <cassert> +#include <atomic> #include <stdint.h> // Gaudi includes @@ -53,6 +54,35 @@ class TileCellBuilder; class TileL2Builder; class TileHid2RESrcID; +namespace TileROD_Helper { + + +// Helper to find the Tile container type corresponding to a container. +template <class COLLECTION> +struct ContainerForCollection {}; + +template <> +struct ContainerForCollection<TileBeamElemCollection> +{ + typedef TileBeamElemContainer type; +}; + +template <> +struct ContainerForCollection<TileDigitsCollection> +{ + typedef TileDigitsContainer type; +}; + +template <> +struct ContainerForCollection<TileRawChannelCollection> +{ + typedef TileRawChannelContainer type; +}; + + +} // namespace TileROD_Helper + + /** * * @class TileROD_Decoder @@ -113,7 +143,9 @@ class TileROD_Decoder: public AthAlgTool { /** This method calls the unpacking methods to decode the ROD data and fills the TileDigitsContainer and/or the TileRawChannelContainer */ - void fillCollection(const ROBData * rob, COLLECTION& v); + void fillCollection(const ROBData * rob, + COLLECTION& v, + typename TileROD_Helper::ContainerForCollection<COLLECTION>::type* container = nullptr); uint32_t fillCollectionHLT(const ROBData * rob, TileCellCollection & v, D0CellsHLT& d0cells); void fillCollectionL2(const ROBData * rob, TileL2Container & v); @@ -140,8 +172,6 @@ class TileROD_Decoder: public AthAlgTool { void mergeD0cellsHLT (const D0CellsHLT& d0cells, TileCellCollection&); - // Set Pointer to container with raw channels - inline void PtrRChContainer(TileRawChannelContainer * container) { m_container = container; } void loadRw2Pmt(const int section, const std::vector<int>& vec) { for (unsigned int i = 0; i < vec.size(); ++i) { // std::cout << vec[i] << std::endl; @@ -149,6 +179,7 @@ class TileROD_Decoder: public AthAlgTool { } } + // Error reporting void printErrorCounter(bool printIfNoError); int getErrorCounter(); @@ -417,24 +448,28 @@ class TileROD_Decoder: public AthAlgTool { DigitsMetaData_t& digitsMetaData, RawChannelMetaData_t& rawchannelMetaData, const ROBData * rob, pDigiVec & pDigits, pRwChVec & pChannel, - TileBeamElemCollection& v) const; + TileBeamElemCollection& v, + TileBeamElemContainer* container) const; inline void make_copy(uint32_t bsflags, TileFragHash::TYPE rChType, TileRawChannelUnit::UNIT rChUnit, DigitsMetaData_t& digitsMetaData, RawChannelMetaData_t& rawchannelMetaData, const ROBData * rob, pDigiVec & pDigits, pRwChVec & pChannel, - TileDigitsCollection& v) const; + TileDigitsCollection& v, + TileDigitsContainer* container) const; inline void make_copy(uint32_t bsflags, TileFragHash::TYPE rChType, TileRawChannelUnit::UNIT rChUnit, DigitsMetaData_t& digitsMetaData, RawChannelMetaData_t& rawchannelMetaData, const ROBData * rob, pDigiVec & pDigits, pRwChVec & pChannel, - TileRawChannelCollection& v) const; + TileRawChannelCollection& v, + TileRawChannelContainer* container) const; uint32_t make_copyHLT(bool of2, TileRawChannelUnit::UNIT rChUnit, + bool correctAmplitude, pFRwChVec & pChannel, TileCellCollection& v, const uint16_t DQuality, D0CellsHLT& d0cells); @@ -520,9 +555,6 @@ class TileROD_Decoder: public AthAlgTool { bool m_of2Default; - // TileRawChannelContainer - TileRawChannelContainer * m_container; - bool m_maskBadDigits; // Pointer to a MBTS cell collection TileCellCollection* m_MBTS; @@ -538,9 +570,8 @@ class TileROD_Decoder: public AthAlgTool { TileL2Builder* m_L2Builder; std::string m_TileDefaultL2Builder; - int m_WarningCounter; - int m_ErrorCounter; - bool m_correctAmplitude; + mutable std::atomic<int> m_WarningCounter; + mutable std::atomic<int> m_ErrorCounter; TileHid2RESrcID * m_hid2re; TileHid2RESrcID * m_hid2reHLT; @@ -574,7 +605,7 @@ class TileROD_Decoder: public AthAlgTool { max_allowed_size = 0; if (size < 3 && size > 0) { if (rob->rod_source_id() > 0x50ffff) error |= 0x10000; // indicate error in frag size, but ignore error in laser ROD - if (m_WarningCounter < (m_maxWarningPrint--)) { + if (m_WarningCounter++ < m_maxWarningPrint) { ATH_MSG_WARNING("ROB " << MSG::hex << rob->source_id() << " ROD " << rob->rod_source_id() << MSG::dec << " has unexpected data size: " << size << " - assuming zero size " ); @@ -582,7 +613,7 @@ class TileROD_Decoder: public AthAlgTool { return 0; } else if (rob->rod_header_size_word() >= rob->rod_fragment_size_word()) { if (rob->rod_source_id() > 0x50ffff) error |= 0x10000; // indicate error in frag size, but ignore error in laser ROD - if (m_WarningCounter < (m_maxWarningPrint--)) { + if (m_WarningCounter++ < m_maxWarningPrint) { ATH_MSG_WARNING("ROB " << MSG::hex << rob->source_id() << " ROD " << rob->rod_source_id() << MSG::dec << " has unexpected header size: " << rob->rod_header_size_word() @@ -655,7 +686,9 @@ void TileROD_Decoder::make_copy(uint32_t /*bsflags*/, DigitsMetaData_t& digitsMetaData, RawChannelMetaData_t& /*rawchannelMetaData*/, const ROBData * rob, pDigiVec & pDigits, pRwChVec & pChannel, - TileDigitsCollection & v) const { + TileDigitsCollection & v, + TileDigitsContainer* /*container*/) const +{ copy_vec(pDigits, v); // Digits stored if (pChannel.size() > 0) { // RawChannels deleted @@ -705,15 +738,16 @@ void TileROD_Decoder::make_copy(uint32_t bsflags, DigitsMetaData_t& /*digitsMetaData*/, RawChannelMetaData_t& rawchannelMetaData, const ROBData * rob, pDigiVec & pDigits, pRwChVec & pChannel, - TileRawChannelCollection & v) const { + TileRawChannelCollection & v, + TileRawChannelContainer* container) const { if (pChannel.size() > 0) { // take available raw channels // and store in collection - if (m_container) { + if (container) { ATH_MSG_VERBOSE( "RawChannel unit is " << rChUnit << " - setting unit in TileRawChannelContainer " ); - m_container->set_unit(rChUnit); - m_container->set_type(rChType); - m_container->set_bsflags(bsflags); + container->set_unit(rChUnit); + container->set_type(rChType); + container->set_bsflags(bsflags); } else { ATH_MSG_ERROR( "Can't set unit=" << rChUnit << " in TileRawChannelContainer" ); } @@ -788,8 +822,10 @@ void TileROD_Decoder::make_copy(uint32_t /*bsflags*/, TileRawChannelUnit::UNIT /*rChUnit*/, DigitsMetaData_t& /*digitsMetaData*/, RawChannelMetaData_t& /*rawchannelMetaData*/, - const ROBData * /* rob */, pDigiVec & pDigits - , pRwChVec & pChannel, TileBeamElemCollection &) const { + const ROBData * /* rob */, pDigiVec & pDigits, + pRwChVec & pChannel, TileBeamElemCollection &, + TileBeamElemContainer* /*container*/) const +{ // do nothing delete_vec(pDigits); delete_vec(pChannel); @@ -835,7 +871,10 @@ void TileROD_Decoder::make_copy(const ROBData * /* rob */, pBeamVec & pBeam, from a BLOCK of integers */ template<class COLLECTION> -void TileROD_Decoder::fillCollection(const ROBData * rob, COLLECTION & v) { +void TileROD_Decoder::fillCollection(const ROBData * rob, + COLLECTION & v, + typename TileROD_Helper::ContainerForCollection<COLLECTION>::type* container /*= nullptr*/) +{ // // get info from ROD header // @@ -1098,7 +1137,7 @@ void TileROD_Decoder::fillCollection(const ROBData * rob, COLLECTION & v) { } // end of all frags make_copy(bsflags, rChType, rChUnit, digitsMetaData, rawchannelMetaData, - rob, pDigits, pChannel, v); + rob, pDigits, pChannel, v, container); } return; diff --git a/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Decoder.cxx b/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Decoder.cxx index b53400efa7625766b225dd605ba52318215b0379..549197768eeb1922eaa21090094784c1ed257558 100644 --- a/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Decoder.cxx +++ b/TileCalorimeter/TileSvc/TileByteStream/src/TileROD_Decoder.cxx @@ -67,13 +67,11 @@ TileROD_Decoder::TileROD_Decoder(const std::string& type, const std::string& nam declareProperty("AllowedTimeMax", m_allowedTimeMax = 50.); // set amp to zero if time is above allowed time max declareProperty("fullTileMode", m_fullTileRODs); // run from which to take the cabling (for the moment, either 320000 - full 2017 mode - or 0 - 2016 mode) - m_correctAmplitude = false; updateAmpThreshold(15.); m_timeMinThresh = -25; m_timeMaxThresh = 25; - + m_of2Default = true; - m_container = 0; m_MBTS = NULL; m_cell2Double.reserve(23); // Maximum number of cells in a drawer m_WarningCounter = 0; @@ -3288,6 +3286,7 @@ uint32_t TileROD_Decoder::fillCollectionHLT(const ROBData * rob, TileCellCollect } } bool of2 = m_of2Default; + bool correctAmplitude = false; TileRawChannelUnit::UNIT rChUnit = TileRawChannelUnit::ADCcounts; uint16_t DQuality = 0x0; bool fragFound = false; @@ -3332,13 +3331,13 @@ uint32_t TileROD_Decoder::fillCollectionHLT(const ROBData * rob, TileCellCollect case 2: fragFound = true; DQfragMissing = false; - m_correctAmplitude = false; + correctAmplitude = false; unpack_frag2HLT(version, sizeOverhead, p, m_pRwChVec); break; case 3: fragFound = true; DQfragMissing = false; - m_correctAmplitude = false; + correctAmplitude = false; unpack_frag3HLT(version, sizeOverhead, p, m_pRwChVec); break; case 4: @@ -3352,13 +3351,13 @@ uint32_t TileROD_Decoder::fillCollectionHLT(const ROBData * rob, TileCellCollect of2 = ((idAndType & 0x4000000) != 0); int nIter = (idAndType & 0x3000000) >> 24; - m_correctAmplitude = (!nIter); // automatic detection of nIter + correctAmplitude = (!nIter); // automatic detection of nIter rChUnit = (TileRawChannelUnit::UNIT) (unit + TileRawChannelUnit::OnlineOffset); // Online units in real data } else { // simulated data DQfragMissing = false; - m_correctAmplitude = false; + correctAmplitude = false; rChUnit = (TileRawChannelUnit::UNIT) (unit); // Offline units in simulated data } @@ -3372,7 +3371,7 @@ uint32_t TileROD_Decoder::fillCollectionHLT(const ROBData * rob, TileCellCollect int unit = (idAndType & 0xC0000000) >> 30; of2 = ((idAndType & 0x4000000) != 0); - m_correctAmplitude = true; // fragment 5 will appear only if there is no iterations, so correction required + correctAmplitude = true; // fragment 5 will appear only if there is no iterations, so correction required rChUnit = (TileRawChannelUnit::UNIT) (unit + TileRawChannelUnit::OnlineOffset); unpack_frag5HLT(version, sizeOverhead, unit, p, m_pRwChVec); @@ -3399,7 +3398,8 @@ uint32_t TileROD_Decoder::fillCollectionHLT(const ROBData * rob, TileCellCollect if (fragFound) { if (masked_drawer) DQuality = 0x0; - error |= make_copyHLT(of2, rChUnit, m_pRwChVec, v, DQuality, d0cells); + error |= make_copyHLT(of2, rChUnit, correctAmplitude, + m_pRwChVec, v, DQuality, d0cells); } else if (!masked_drawer) error |= 0x20000; return error; @@ -3407,6 +3407,7 @@ uint32_t TileROD_Decoder::fillCollectionHLT(const ROBData * rob, TileCellCollect uint32_t TileROD_Decoder::make_copyHLT(bool of2, TileRawChannelUnit::UNIT rChUnit, + bool correctAmplitude, pFRwChVec & pChannel, TileCellCollection & v, const uint16_t DQuality, D0CellsHLT& d0cells) { @@ -3476,7 +3477,7 @@ uint32_t TileROD_Decoder::make_copyHLT(bool of2, TileRawChannelUnit::MegaElectronVolts); } // parabolic correction for good but slightly out-of-time signals - if (m_correctAmplitude) { + if (correctAmplitude) { if (time<m_allowedTimeMin || time>m_allowedTimeMax) { ener = 0.0F; time = 0.0F; @@ -3533,7 +3534,7 @@ uint32_t TileROD_Decoder::make_copyHLT(bool of2, TileRawChannelUnit::MegaElectronVolts); } // parabolic correction for good but slightly out-of-time signals - if (m_correctAmplitude) { + if (correctAmplitude) { if (time<m_allowedTimeMin || time>m_allowedTimeMax) { ener = 0.0F; time = 0.0F; @@ -3590,7 +3591,7 @@ uint32_t TileROD_Decoder::make_copyHLT(bool of2, rChUnit, TileRawChannelUnit::PicoCoulombs); } // parabolic correction for good but slightly out-of-time signals - if (m_correctAmplitude) { + if (correctAmplitude) { if (time<m_allowedTimeMin || time>m_allowedTimeMax) { ener = 0.0F; time = 0.0F; diff --git a/TileCalorimeter/TileSvc/TileByteStream/src/TileRawChannelContByteStreamCnv.cxx b/TileCalorimeter/TileSvc/TileByteStream/src/TileRawChannelContByteStreamCnv.cxx index 9606fec1e4d97cf879198d4785d53f9d6e9ed83f..9b22d6beb86e4a80b203b66fa0b1e84cc015ace1 100644 --- a/TileCalorimeter/TileSvc/TileByteStream/src/TileRawChannelContByteStreamCnv.cxx +++ b/TileCalorimeter/TileSvc/TileByteStream/src/TileRawChannelContByteStreamCnv.cxx @@ -80,7 +80,6 @@ StatusCode TileRawChannelContByteStreamCnv::initialize() { unit = TileRawChannelUnit::ADCcounts; m_containers[0] = new TileRawChannelContainer(true, type, unit); m_containers[0]->addRef(); // make sure it's not deleted at the end of event - m_decoder->PtrRChContainer( m_containers[0] ); type = TileFragHash::MF; unit = TileRawChannelUnit::ADCcounts; @@ -147,7 +146,7 @@ StatusCode TileRawChannelContByteStreamCnv::createObj(IOpaqueAddress* pAddr, Dat if (isTMDB) {// reid for TMDB 0x5x010x m_decoder->fillCollection_TileMuRcv_RawChannel(robf[0], *rawChannelCollection); } else { - m_decoder->fillCollection(robf[0], *rawChannelCollection); + m_decoder->fillCollection(robf[0], *rawChannelCollection, m_containers[icnt]); } } else { rawChannelCollection->setFragGlobalCRC(TileROD_Decoder::NO_ROB); diff --git a/TileCalorimeter/TileSvc/TileByteStream/test/TileROD_Decoder_test.cxx b/TileCalorimeter/TileSvc/TileByteStream/test/TileROD_Decoder_test.cxx index 276a313e66160d9bb5034f65a1b3ef28a5c8e9e6..3f928b283108b30861e25632d2140d60d39a9907 100644 --- a/TileCalorimeter/TileSvc/TileByteStream/test/TileROD_Decoder_test.cxx +++ b/TileCalorimeter/TileSvc/TileByteStream/test/TileROD_Decoder_test.cxx @@ -148,8 +148,7 @@ void test1 (TileROD_Decoder* decoder) { TileRawChannelContainer cont; TileRawChannelCollection coll (256); - decoder->PtrRChContainer (&cont); - decoder->fillCollection (&data01.rob(), coll); + decoder->fillCollection (&data01.rob(), coll, &cont); std::cout << "TileRawChannelCollection: " << coll.size() << " " << cont.get_unit() << " " << cont.get_type() << " "