Skip to content
Snippets Groups Projects

Modernize CaloFutureFillRawBuffer

Merged Jean-Francois Marchand requested to merge jmarchan-modernizeCaloFutureFillRawBuffer into master
@@ -9,446 +9,278 @@
* or submit itself to any jurisdiction. *
\*****************************************************************************/
#include "CaloDet/DeCalorimeter.h"
#include "CaloFutureUtils/CaloFutureAlgUtils.h"
#include "Event/CaloAdc.h"
#include "Event/RawEvent.h"
#include "GaudiAlg/GaudiAlgorithm.h"
#include "LHCbAlgs/Consumer.h"
//-----------------------------------------------------------------------------
// Implementation file for class : CaloFutureFillRawBuffer
// Implementation file for class : FillRawBuffer
//
// 2004-12-17 : Olivier Callot
//-----------------------------------------------------------------------------
/** @class CaloFutureFillRawBuffer CaloFutureFillRawBuffer.h
/** @class FillRawBuffer
* Fills the Raw Buffer banks for the calorimeter
*
* @author Olivier Callot
* @date 2004-12-17
*/
class CaloFutureFillRawBuffer : public GaudiAlgorithm {
public:
/// Standard constructor
CaloFutureFillRawBuffer( const std::string& name, ISvcLocator* pSvcLocator );
StatusCode initialize() override; ///< Algorithm initialization
StatusCode execute() override; ///< Algorithm execution
StatusCode finalize() override; ///< Algorithm finalization
protected:
void fillDataBankShort();
void fillPackedBank();
void fillBank( bool isLittleEndian );
private:
std::string m_inputBank;
std::string m_triggerBank;
std::string m_detectorName = "None";
std::string m_detectorLocation;
LHCb::RawBank::BankType m_bankType = LHCb::RawBank::LastType;
LHCb::RawBank::BankType m_triggerBankType = LHCb::RawBank::LastType;
int m_numberOfBanks = 1;
Gaudi::Property<int> m_dataCodingType{this, "DataCodingType", 1, [this]( auto& ) {
if ( 0 >= m_dataCodingType )
throw std::invalid_argument( "Invalid Data Coding Type" );
}};
DeCalorimeter* m_calo = nullptr;
// Statistics
double m_totDataSize = 0;
std::vector<double> m_dataSize;
double m_totTrigSize = 0;
int m_nbEvents = 0;
std::vector<std::vector<unsigned int>> m_banks;
std::vector<int> m_banks_sourceID;
std::vector<std::vector<unsigned int>> m_trigBanks;
bool m_pin = false;
};
DECLARE_COMPONENT( CaloFutureFillRawBuffer )
//=============================================================================
// Standard constructor, initializes variables
//=============================================================================
CaloFutureFillRawBuffer::CaloFutureFillRawBuffer( const std::string& name, ISvcLocator* pSvcLocator )
: GaudiAlgorithm( name, pSvcLocator ) {
//=== Default values according to the name of the algorithm !
if ( "Ecal" == name.substr( 0, 4 ) ) {
m_detectorName = "Ecal";
m_detectorLocation = DeCalorimeterLocation::Ecal;
m_inputBank = LHCb::CaloAdcLocation::Ecal;
m_bankType = ( m_dataCodingType == 4 || m_dataCodingType == 5 ) ? LHCb::RawBank::Calo : LHCb::RawBank::EcalE;
m_triggerBankType = LHCb::RawBank::EcalTrig;
} else if ( "Hcal" == name.substr( 0, 4 ) ) {
m_detectorName = "Hcal";
m_detectorLocation = DeCalorimeterLocation::Hcal;
m_inputBank = LHCb::CaloAdcLocation::Hcal;
m_bankType = ( m_dataCodingType == 4 || m_dataCodingType == 5 ) ? LHCb::RawBank::Calo : LHCb::RawBank::HcalE;
m_triggerBankType = LHCb::RawBank::HcalTrig;
}
declareProperty( "InputBank", m_inputBank );
namespace LHCb::Calo {
declareProperty( "FillWithPin", m_pin = false );
}
class FillRawBuffer : public LHCb::Algorithm::Consumer<void( const LHCb::CaloAdcs&, const DeCalorimeter& ),
LHCb::DetDesc::usesConditions<DeCalorimeter>> {
//=============================================================================
// Initialization
//=============================================================================
StatusCode CaloFutureFillRawBuffer::initialize() {
StatusCode sc = GaudiAlgorithm::initialize(); // must be executed first
if ( sc.isFailure() ) return sc; // error printed already by GaudiAlgorithm
public:
// Standard constructor
FillRawBuffer( const std::string& name, ISvcLocator* pSvcLocator );
if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Initialize" << endmsg;
// Algorithm execution
void operator()( const LHCb::CaloAdcs&, const DeCalorimeter& ) const override;
if ( "None" == m_detectorName ) { return Error( "Invalid algorithm name" + name(), StatusCode::FAILURE ); }
private:
void fillPackedBank( const LHCb::CaloAdcs& digs, const DeCalorimeter& calo, LHCb::RawEvent& rawEvent ) const;
void fillBank( const LHCb::CaloAdcs& digs, const DeCalorimeter& calo, LHCb::RawEvent& rawEvent ) const;
m_calo = getDet<DeCalorimeter>( m_detectorLocation );
std::string m_triggerBank;
Gaudi::Property<int> m_dataCodingType{this, "DataCodingType", 1, [this]( auto& ) {
if ( 0 >= m_dataCodingType )
throw std::invalid_argument( "Invalid Data Coding Type" );
}};
if ( 2 == m_dataCodingType ) {
//== TELL1 coding format: packed data, starting from Full banks
m_numberOfBanks = m_calo->nTell1s();
if ( "Ecal" == m_detectorName ) {
m_bankType = LHCb::RawBank::EcalPacked;
m_inputBank = LHCb::CaloAdcLocation::FullEcal;
} else {
m_bankType = LHCb::RawBank::HcalPacked;
m_inputBank = LHCb::CaloAdcLocation::FullHcal;
}
info() << "DataCodingType==2 - Processing " << m_calo->nCards() << " FE-Cards and " << m_calo->nTell1s()
<< " TELL1" << endmsg;
}
// This is actually an update handle, in the sense that the RawEvent will be modified
DataObjectReadHandle<RawEvent> m_raw{this, "RawEvent", LHCb::RawEventLocation::Default};
if ( 3 == m_dataCodingType ) {
//== TELL1 coding format: packed data, starting from Full banks
m_numberOfBanks = m_calo->nTell1s();
if ( "Ecal" == m_detectorName ) {
m_bankType = LHCb::RawBank::EcalPacked;
m_inputBank = LHCb::CaloAdcLocation::FullEcal;
} else {
m_bankType = LHCb::RawBank::HcalPacked;
m_inputBank = LHCb::CaloAdcLocation::FullHcal;
}
info() << "DataCodingType==3 - Processing " << m_calo->nCards() << " FE-Cards and " << m_calo->nTell1s()
<< " TELL1" << endmsg;
}
Gaudi::Property<bool> m_pin{this, "FillWithPin", false};
if ( 4 == m_dataCodingType || 5 == m_dataCodingType ) {
//== TELL40 coding format: packed data, starting from Full banks
m_numberOfBanks = 2 * m_calo->nTell1s(); // 2 source_ids per tell40
if ( "Ecal" == m_detectorName ) {
m_bankType = LHCb::RawBank::Calo;
m_inputBank = LHCb::CaloAdcLocation::FullEcal;
} else {
m_bankType = LHCb::RawBank::Calo;
m_inputBank = LHCb::CaloAdcLocation::FullHcal;
}
info() << "DataCodingType==" << m_dataCodingType << " - Processing " << m_calo->nCards() << " FE-Cards and "
<< m_calo->nTell1s() << " TELL40" << endmsg;
}
// Statistics
mutable Gaudi::Accumulators::StatCounter<> m_totDataSize{this, "# totData"};
mutable Gaudi::Accumulators::StatCounter<> m_totTrigSize{this, "# totData"};
};
m_nbEvents = 0;
m_totDataSize = 0;
m_totTrigSize = 0;
DECLARE_COMPONENT_WITH_ID( FillRawBuffer, "CaloFutureFillRawBuffer" )
std::vector<unsigned int> a;
a.reserve( 500 );
for ( int kk = 0; m_numberOfBanks > kk; kk++ ) {
m_banks.push_back( a );
m_trigBanks.push_back( a );
m_dataSize.push_back( 0. );
}
// Standard constructor, initializes variables
FillRawBuffer::FillRawBuffer( const std::string& name, ISvcLocator* pSvcLocator )
: Consumer( name, pSvcLocator,
{KeyValue{"InputBank", LHCb::CaloAdcLocation::FullEcal},
KeyValue{"DetectorLocation", DeCalorimeterLocation::Ecal}} ) {}
info() << "Data coding type " << m_dataCodingType << endmsg;
// Main execution
void FillRawBuffer::operator()( const LHCb::CaloAdcs& digs, const DeCalorimeter& calo ) const {
return sc;
}
if ( !m_raw.exist() ) m_raw.put( std::make_unique<RawEvent>() );
//=============================================================================
// Main execution
//=============================================================================
StatusCode CaloFutureFillRawBuffer::execute() {
if ( msgLevel( MSG::DEBUG ) ) debug() << "==> Execute" << endmsg;
for ( int kk = 0; m_numberOfBanks > kk; kk++ ) {
m_banks[kk].clear();
m_trigBanks[kk].clear();
if ( m_dataCodingType < 3 ) // Old run 2 encoding
fillPackedBank( digs, calo, *m_raw.get() );
else if ( m_dataCodingType == 4 || m_dataCodingType == 5 )
fillBank( digs, calo, *m_raw.get() );
else
error() << "CodingType " << m_dataCodingType << " not supported" << endmsg;
}
//== Build the data banks
switch ( m_dataCodingType ) {
case 1: {
//=========================================================================
// Fill the calorimeter data bank, simple structure: ID (upper 16 bits) + ADC
//=========================================================================
LHCb::CaloAdcs* digs = get<LHCb::CaloAdcs>( m_inputBank );
std::transform( digs->begin(), digs->end(), std::back_inserter( m_banks[0] ),
[]( const auto& dig ) { return ( dig->cellID().all() << 16 ) | ( dig->adc() & 0xFFFF ); } );
break;
}
case 2: {
fillPackedBank();
break;
}
case 4: {
fillBank( false ); // BigEndian
break;
}
case 5: {
fillBank( true ); // LittleEndian
break;
}
default:
ASSUME( false );
}
// Packed data format, trigger and data in the same bank. Process ALL digits
void FillRawBuffer::fillPackedBank( const LHCb::CaloAdcs& digs, const DeCalorimeter& calo,
LHCb::RawEvent& rawEvent ) const {
LHCb::RawBank::BankType bankType = LHCb::RawBank::LastType;
LHCb::RawBank::BankType triggerBankType = LHCb::RawBank::LastType;
int numberOfBanks = 1;
if ( m_dataCodingType == 2 ) {
//== TELL1 coding format: packed data, starting from Full banks
numberOfBanks = calo.nTell1s();
bankType = ( calo.index() == Detector::Calo::CellCode::Index::EcalCalo ) ? LHCb::RawBank::EcalPacked
: LHCb::RawBank::HcalPacked;
} else {
bankType =
( calo.index() == Detector::Calo::CellCode::Index::EcalCalo ) ? LHCb::RawBank::EcalE : LHCb::RawBank::HcalE;
}
triggerBankType = ( calo.index() == Detector::Calo::CellCode::Index::EcalCalo ) ? LHCb::RawBank::EcalTrig
: LHCb::RawBank::HcalTrig;
int totDataSize = 0;
int totTrigSize = 0;
std::vector<int> banks_sourceID;
std::vector<std::vector<unsigned int>> banks;
for ( int kk = 0; numberOfBanks > kk; kk++ ) { banks.emplace_back().reserve( 500 ); }
LHCb::RawEvent* rawEvent = get<LHCb::RawEvent>( LHCb::RawEventLocation::Default );
if ( m_dataCodingType == 1 ) {
if ( m_dataCodingType == 4 || m_dataCodingType == 5 ) {
if ( m_banks_sourceID.size() < m_banks.size() )
throw GaudiException( "Coding type doesn't match DB", this->name(), StatusCode::FAILURE );
for ( unsigned int kk = 0; m_banks.size() > kk; kk++ ) {
rawEvent->addBank( m_banks_sourceID[kk], m_bankType, m_dataCodingType, m_banks[kk] );
totDataSize += m_banks[kk].size();
m_dataSize[kk] += m_banks[kk].size();
}
} else {
for ( unsigned int kk = 0; m_banks.size() > kk; kk++ ) {
rawEvent->addBank( kk, m_bankType, m_dataCodingType, m_banks[kk] );
totDataSize += m_banks[kk].size();
m_dataSize[kk] += m_banks[kk].size();
if ( 1 == m_dataCodingType ) {
rawEvent->addBank( kk, m_triggerBankType, 0, m_trigBanks[kk] );
totTrigSize += m_trigBanks[kk].size();
}
}
}
std::vector<std::vector<unsigned int>> trigBanks;
for ( int kk = 0; numberOfBanks > kk; kk++ ) { trigBanks.emplace_back().reserve( 500 ); }
m_totDataSize += totDataSize;
m_totTrigSize += totTrigSize;
m_nbEvents++;
std::transform( digs.begin(), digs.end(), std::back_inserter( banks[0] ),
[]( const auto& dig ) { return ( dig->cellID().all() << 16 ) | ( dig->adc() & 0xFFFF ); } );
for ( unsigned int kk = 0; banks.size() > kk; kk++ ) {
rawEvent.addBank( kk, bankType, m_dataCodingType, banks[kk] );
m_totDataSize += banks[kk].size();
rawEvent.addBank( kk, triggerBankType, 0, trigBanks[kk] );
m_totTrigSize += trigBanks[kk].size();
}
if ( msgLevel( MSG::DEBUG ) ) {
debug() << "Bank sizes: ";
for ( unsigned int kk = 0; m_banks.size() > kk; kk++ ) {
debug() << format( "%2d:%4d+%4d ", kk, m_banks[kk].size(), m_trigBanks[kk].size() );
}
debug() << endmsg << "Total Data bank size " << totDataSize << " + trigger " << totTrigSize << endmsg;
}
} else {
if ( msgLevel( MSG::VERBOSE ) ) {
if ( m_dataCodingType == 4 ) {
for ( unsigned int kk = 0; m_banks.size() > kk; kk++ ) {
int kl = 0;
for ( auto itW : m_banks[kk] ) {
verbose() << format( " %8x ", itW );
kl++;
if ( 0 == kl % 4 ) verbose() << endmsg;
int m_numberOfBanks = calo.nTell1s();
for ( int kTell1 = 0; m_numberOfBanks > kTell1; kTell1++ ) {
for ( auto cardNum : calo.tell1ToCards( kTell1 ) ) {
if ( calo.isPinCard( cardNum ) && !m_pin ) continue; // No sub-bank for PIN-FEB if not explicitely requested
int sizeIndex = banks[kTell1].size();
banks[kTell1].push_back( calo.cardCode( cardNum ) << 14 );
std::vector<LHCb::Detector::Calo::CellID> ids = calo.cardChannels( cardNum );
//=== The trigger part is first
int patternIndex = banks[kTell1].size();
int patTrig = 0;
banks[kTell1].push_back( patTrig );
int word = 0;
int offset = 0;
int bNum = 0;
int sizeTrig = 4 * ( banks[kTell1].size() - patternIndex ); // in byte
//== If no trigger at all, remove even the pattern...
if ( 4 == sizeTrig ) {
banks[kTell1].pop_back();
sizeTrig = 0;
} else {
banks[kTell1][patternIndex] = patTrig;
}
//=== Now the ADCs
patternIndex = banks[kTell1].size();
int pattern = 0;
banks[kTell1].push_back( pattern );
word = 0;
offset = 0;
bNum = 0;
for ( LHCb::Detector::Calo::CellID id : ids ) {
LHCb::CaloAdc* dig = digs.object( id );
int adc = ( dig ? std::clamp( dig->adc() + 256, 0, 4095 ) : 256 ); //== Default if non existing cell.
if ( 248 <= adc && adc < 264 ) { //... store short
adc -= 248;
word |= adc << offset;
offset += 4;
} else { //... store long
word |= adc << offset;
pattern += ( 1 << bNum );
offset += 12;
}
if ( 32 <= offset ) { //== Have we a full word or more ? Store it
banks[kTell1].push_back( word );
offset -= 32;
word = adc >> ( 12 - offset ); //== upper bits if needed
}
bNum++;
}
if ( 0 != offset ) banks[kTell1].push_back( word );
int sizeAdc = 4 * ( banks[kTell1].size() - patternIndex );
banks[kTell1][patternIndex] = pattern;
banks[kTell1][sizeIndex] |= ( sizeAdc << 7 ) + sizeTrig;
m_totTrigSize += sizeTrig;
if ( msgLevel( MSG::DEBUG ) )
debug() << format( "Tell1 %2d card %3d pattern %8x patTrig %8x size Adc %2d Trig %2d", kTell1, cardNum,
pattern, patTrig, sizeAdc, sizeTrig )
<< endmsg;
}
}
} else {
for ( unsigned int kk = 0; m_banks.size() > kk; kk++ ) {
verbose() << "DATA bank : " << kk << endmsg;
int kl = 0;
for ( auto itW : m_banks[kk] ) {
verbose() << format( " %8x %11d ", itW, itW );
kl++;
if ( 0 == kl % 4 ) verbose() << endmsg;
}
verbose() << endmsg << "TRIGGER bank size=" << m_trigBanks[kk].size() << " " << endmsg;
kl = 0;
for ( auto itW : m_trigBanks[kk] ) {
verbose() << format( " %8x ", itW );
kl++;
if ( 0 == kl % 8 ) verbose() << endmsg;
}
verbose() << endmsg;
for ( unsigned int kk = 0; banks.size() > kk; kk++ ) {
rawEvent.addBank( kk, bankType, m_dataCodingType, banks[kk] );
m_totDataSize += banks[kk].size();
}
}
}
return StatusCode::SUCCESS;
}
//=============================================================================
// Finalize
//=============================================================================
StatusCode CaloFutureFillRawBuffer::finalize() {
if ( 0 < m_nbEvents ) {
m_totDataSize /= m_nbEvents;
m_totTrigSize /= m_nbEvents;
info() << "Average event size : " << format( "%7.1f words, %7.1f for trigger", m_totDataSize, m_totTrigSize );
double meanSize = 0.;
double maxSize = 0.;
for ( auto& ds : m_dataSize ) {
ds /= m_nbEvents;
meanSize += ds;
if ( maxSize < ds ) maxSize = ds;
}
meanSize /= m_dataSize.size();
info() << format( " Mean bank size %7.1f, maximum size %7.1f", meanSize, maxSize ) << endmsg;
}
// New (run 3) data format. Process ALL digits
void FillRawBuffer::fillBank( const LHCb::CaloAdcs& digs, const DeCalorimeter& calo,
LHCb::RawEvent& rawEvent ) const {
return GaudiAlgorithm::finalize(); // must be called after all other actions
}
//=========================================================================
// Packed data format, trigger and data in the same bank. Process ALL digits
//=========================================================================
void CaloFutureFillRawBuffer::fillPackedBank() {
LHCb::CaloAdcs* digs = get<LHCb::CaloAdcs>( m_inputBank );
for ( int kTell1 = 0; m_numberOfBanks > kTell1; kTell1++ ) {
for ( auto cardNum : m_calo->tell1ToCards( kTell1 ) ) {
if ( m_calo->isPinCard( cardNum ) && !m_pin ) continue; // No sub-bank for PIN-FEB if not explicitely requested
int sizeIndex = m_banks[kTell1].size();
m_banks[kTell1].push_back( m_calo->cardCode( cardNum ) << 14 );
std::vector<LHCb::Detector::Calo::CellID> ids = m_calo->cardChannels( cardNum );
//=== The trigger part is first
int patternIndex = m_banks[kTell1].size();
int patTrig = 0;
m_banks[kTell1].push_back( patTrig );
int word = 0;
int offset = 0;
int bNum = 0;
if ( 0 != offset ) { m_banks[kTell1].push_back( word ); }
int sizeTrig = 4 * ( m_banks[kTell1].size() - patternIndex ); // in byte
//== If no trigger at all, remove even the pattern...
if ( 4 == sizeTrig ) {
m_banks[kTell1].pop_back();
sizeTrig = 0;
} else {
m_banks[kTell1][patternIndex] = patTrig;
}
//== TELL40 coding format: packed data, starting from Full banks
int numberOfBanks = 2 * calo.nTell1s(); // 2 source_ids per tell40
//=== Now the ADCs
patternIndex = m_banks[kTell1].size();
int pattern = 0;
m_banks[kTell1].push_back( pattern );
word = 0;
offset = 0;
bNum = 0;
for ( LHCb::Detector::Calo::CellID id : ids ) {
LHCb::CaloAdc* dig = digs->object( id );
int adc = ( dig ? std::clamp( dig->adc() + 256, 0, 4095 ) : 256 ); //== Default if non existing cell.
if ( 248 <= adc && adc < 264 ) { //... store short
adc -= 248;
word |= adc << offset;
offset += 4;
} else { //... store long
word |= adc << offset;
pattern += ( 1 << bNum );
offset += 12;
}
if ( 32 <= offset ) { //== Have we a full word or more ? Store it
m_banks[kTell1].push_back( word );
offset -= 32;
word = adc >> ( 12 - offset ); //== upper bits if needed
}
bNum++;
}
if ( 0 != offset ) m_banks[kTell1].push_back( word );
if ( msgLevel( MSG::DEBUG ) )
debug() << "DataCodingType==" << m_dataCodingType << " - Processing " << calo.nCards() << " FE-Cards and "
<< calo.nTell1s() << " TELL40 - BankType: LHCb::RawBank::Calo" << endmsg;
int sizeAdc = 4 * ( m_banks[kTell1].size() - patternIndex );
m_banks[kTell1][patternIndex] = pattern;
std::vector<int> banks_sourceID;
std::vector<std::vector<unsigned int>> banks;
for ( int kk = 0; numberOfBanks > kk; kk++ ) { banks.emplace_back().reserve( 500 ); }
m_banks[kTell1][sizeIndex] |= ( sizeAdc << 7 ) + sizeTrig;
m_totTrigSize += sizeTrig;
bool isLittleEndian = m_dataCodingType == 5 ? true : false;
if ( msgLevel( MSG::DEBUG ) )
debug() << format( "Tell1 %2d card %3d pattern %8x patTrig %8x size Adc %2d Trig %2d", kTell1, cardNum, pattern,
patTrig, sizeAdc, sizeTrig )
<< endmsg;
}
}
}
//=========================================================================
// New (run 3) data format. Process ALL digits
//=========================================================================
void CaloFutureFillRawBuffer::fillBank( bool isLittleEndian ) {
LHCb::CaloAdcs* digs = get<LHCb::CaloAdcs>( m_inputBank );
std::map<int, std::vector<int>> map = m_calo->getSourceIDsMap();
std::map<int, std::vector<int>>::iterator itr;
int kSourceID = 0;
for ( itr = map.begin(); itr != map.end(); ++itr ) {
m_banks_sourceID.push_back( itr->first );
//=== The LLT part is first
int LLT1 = 0, LLT2 = 0, LLT3 = 0;
m_banks[kSourceID].push_back( LLT1 );
m_banks[kSourceID].push_back( LLT2 );
m_banks[kSourceID].push_back( LLT3 );
for ( auto cardNum : itr->second ) {
if ( cardNum == 0 ) {
if ( msgLevel( MSG::DEBUG ) )
debug() << "cardnum == 0 fill 12 empty words of 32 bits (32 cells of 12 bits)" << endmsg;
for ( int i = 0; i < 12; i++ ) m_banks[kSourceID].push_back( 0 );
continue;
}
if ( m_calo->isPinCard( cardNum ) && !m_pin ) {
for ( int i = 0; i < 12; i++ ) m_banks[kSourceID].push_back( 0 );
continue; // No sub-bank for PIN-FEB if not explicitely requested
}
std::map<int, std::vector<int>> map = calo.getSourceIDsMap();
std::map<int, std::vector<int>>::iterator itr;
int kSourceID = 0;
for ( itr = map.begin(); itr != map.end(); ++itr ) {
std::vector<LHCb::Detector::Calo::CellID> ids = m_calo->cardChannels( cardNum );
banks_sourceID.push_back( itr->first );
unsigned int word = 0;
int offset = 0;
//=== The LLT part is first
int LLT1 = 0, LLT2 = 0, LLT3 = 0;
banks[kSourceID].push_back( LLT1 );
banks[kSourceID].push_back( LLT2 );
banks[kSourceID].push_back( LLT3 );
if ( 0 != offset ) {
if ( !isLittleEndian )
word = ( ( word >> 24 ) & 0x000000FF ) | ( ( word >> 8 ) & 0x0000FF00 ) | ( ( word << 8 ) & 0x00FF0000 ) |
( ( word << 24 ) & 0xFF000000 );
m_banks[kSourceID].push_back( word );
}
for ( auto cardNum : itr->second ) {
if ( cardNum == 0 ) {
if ( msgLevel( MSG::DEBUG ) )
debug() << "cardnum == 0 fill 12 empty words of 32 bits (32 cells of 12 bits)" << endmsg;
for ( int i = 0; i < 12; i++ ) banks[kSourceID].push_back( 0 );
continue;
}
if ( calo.isPinCard( cardNum ) && !m_pin ) {
for ( int i = 0; i < 12; i++ ) banks[kSourceID].push_back( 0 );
continue; // No sub-bank for PIN-FEB if not explicitely requested
}
//=== Now the ADCs
for ( LHCb::Detector::Calo::CellID id : ids ) {
LHCb::CaloAdc* dig = digs->object( id );
unsigned int adc = ( dig ? std::clamp( dig->adc() + 256, 0, 4095 ) : 256 ); //== Default if non existing cell.
std::vector<LHCb::Detector::Calo::CellID> ids = calo.cardChannels( cardNum );
offset += 12;
if ( offset < 32 ) {
word |= adc << ( 32 - offset );
} else {
word |= adc >> abs( 32 - offset );
unsigned int word = 0;
int offset = 0;
//=== Now the ADCs
for ( LHCb::Detector::Calo::CellID id : ids ) {
LHCb::CaloAdc* dig = digs.object( id );
unsigned int adc = ( dig ? std::clamp( dig->adc() + 256, 0, 4095 ) : 256 ); //== Default if non existing cell.
offset += 12;
if ( offset < 32 ) {
word |= adc << ( 32 - offset );
} else {
word |= adc >> abs( 32 - offset );
if ( !isLittleEndian )
word = ( ( word >> 24 ) & 0x000000FF ) | ( ( word >> 8 ) & 0x0000FF00 ) | ( ( word << 8 ) & 0x00FF0000 ) |
( ( word << 24 ) & 0xFF000000 );
banks[kSourceID].push_back( word );
if ( offset > 32 )
word = adc << ( 32 - abs( 32 - offset ) ); //== upper bits if needed
else
word = 0;
offset = abs( 32 - offset );
}
}
if ( 0 != offset ) {
if ( !isLittleEndian )
word = ( ( word >> 24 ) & 0x000000FF ) | ( ( word >> 8 ) & 0x0000FF00 ) | ( ( word << 8 ) & 0x00FF0000 ) |
( ( word << 24 ) & 0xFF000000 );
m_banks[kSourceID].push_back( word );
if ( offset > 32 )
word = adc << ( 32 - abs( 32 - offset ) ); //== upper bits if needed
else
word = 0;
offset = abs( 32 - offset );
banks[kSourceID].push_back( word );
}
if ( msgLevel( MSG::DEBUG ) ) debug() << format( "source_id %2d card %3d", kSourceID, cardNum ) << endmsg;
}
if ( 0 != offset ) {
if ( !isLittleEndian )
word = ( ( word >> 24 ) & 0x000000FF ) | ( ( word >> 8 ) & 0x0000FF00 ) | ( ( word << 8 ) & 0x00FF0000 ) |
( ( word << 24 ) & 0xFF000000 );
m_banks[kSourceID].push_back( word );
}
kSourceID++;
}
if ( msgLevel( MSG::DEBUG ) ) debug() << format( "source_id %2d card %3d", kSourceID, cardNum ) << endmsg;
if ( banks_sourceID.size() < banks.size() )
throw GaudiException( "Coding type doesn't match DB", this->name(), StatusCode::FAILURE );
for ( unsigned int kk = 0; banks.size() > kk; kk++ ) {
rawEvent.addBank( banks_sourceID[kk], LHCb::RawBank::Calo, m_dataCodingType, banks[kk] );
m_totDataSize += banks[kk].size();
}
kSourceID++;
}
}
} // namespace LHCb::Calo
Loading