/* * VetrocWord.hh * * Created on: Nov 7, 2017 * Author: Hovanes Egiyan */ #ifndef VETROCAPP_SRC_VETROCWORD_HH_ #define VETROCAPP_SRC_VETROCWORD_HH_ #include #include #include #include #include #include #include #include #include #include #include extern "C" { #include "jvme.h" #include "vetrocLib.h" } #include "VetrocWordInterface.hh" class VetrocWordBase: virtual public VetrocWordInterface { protected: // Actual data word from VETROC uint32_t word; // Positions of the smallest bits for various mask related to the data type stored in a map. // The key of the map is the mask itself, the value is the location of least bit set. // This is stored in a map to prevent calculations hoping that map access is shorter than finding LSP. static std::map lspForWordTypeMap; static std::map assignLspMap(); // Return the lowest bit position that is not zero. static unsigned leastBitPosition( uint32_t swappedWord ) { for ( unsigned pos = 0; pos < sizeof(uint32_t) * 8; pos++ ) { uint32_t bitMask = 1 << pos; if ( (swappedWord & bitMask) != 0 ) return pos; } return 0; } public: // Constructor. The data is copied from uint32_t word into the data member after byte swapping . VetrocWordBase( const uint32_t& swappedWord ) : word( swappedWord ) { // std::cout << "Created VetrocWordBase " << std::hex << std::showbase << word << std::dec // << std::endl; return; } VetrocWordBase( const VetrocWordBase& w ) : VetrocWordInterface(), word( w.word ) { } virtual ~VetrocWordBase() { } VetrocWordBase& operator=( const VetrocWordBase& w ) { word = w.word; return *this; } friend std::ostream& operator<<( std::ostream& out, const VetrocWordBase& w ) { return (out << boost::format( "Word type is 0x%02s , <%16s>, and data is 0x%08X " ) % w.getType() % VetrocWordInterface::getDataTypeName( w.getType() ) % w.getWord()); } virtual bool isDataTypeDefinitionFromBits() const { return isDataTypeDefinitionFromBits( word ); } static bool isDataTypeDefinitionFromBits( const uint32_t& swappedWord ) { return ((swappedWord & VETROC_DATA_TYPE_DEFINE) != 0); } // Look at the bits and return the type of data in this word virtual dataType getTypeFromBits() const { return getTypeFromBits( word ); } // Look at the bits and return the type of data in this word static dataType getTypeFromBits( const uint32_t& swappedWord ) { if ( isDataTypeDefinitionFromBits( swappedWord ) ) { return static_cast( (swappedWord & VETROC_DATA_TYPE_MASK) >> lspForWordTypeMap[VETROC_DATA_TYPE_MASK] ); } return UndefinedType; } static std::map getLspWordTypeMap() { return lspForWordTypeMap; } uint32_t getWord() const { return word; } uint32_t setWord( uint32_t swappedWord ) { return (this->word = swappedWord); } }; template class VetrocWord: public VetrocWordBase { public: // Constructor. The data is copied from uint32_t word into the data member. VetrocWord( const uint32_t& swappedWord ) : VetrocWordBase( swappedWord ) { } VetrocWord( const VetrocWord& w ) : VetrocWordBase( w ) { } virtual ~VetrocWord() { } VetrocWord& operator=( const VetrocWord& w ) { *dynamic_cast( this ) = w; return *this; } virtual dataType getType() const { return TYPE; } virtual bool isDataTypeDefinition() const { return TYPE_DEF; } // Static method to generate instances of data words based on what in the data and what's in // lastDataType. If the words type is data defining type then set the data type for this word. // Also this will be used to set for the consecutive words that get constructed with the second // argument referencing this word. Otherwise use lastDataType hoping that the caller follows this // instructions. static VetrocWordBase* createInstance( const uint32_t& swappedWord, const dataType lastDataType ) { if ( isDataTypeDefinitionFromBits( swappedWord ) ) { dataType type = static_cast( ((swappedWord & VETROC_DATA_TYPE_MASK) >> lspForWordTypeMap[VETROC_DATA_TYPE_MASK]) ); switch ( type ) { case (BlockHeaderType): return new VetrocWord( BlockHeaderType ), true>( swappedWord ); case (BlockTrailerType): return new VetrocWord( BlockTrailerType ), true>( swappedWord ); case (EventHeaderType): return new VetrocWord( EventHeaderType ), true>( swappedWord ); case (TriggerTimeType): return new VetrocWord( TriggerTimeType ), true>( swappedWord ); case (TDCHitType): return new VetrocWord( TDCHitType ), true>( swappedWord ); case (Profiler2DType): return new VetrocWord( Profiler2DType ), true>( swappedWord ); case (Profiler1DType): return new VetrocWord( Profiler1DType ), true>( swappedWord ); case (EmptyModuleType): return new VetrocWord( EmptyModuleType ), true>( swappedWord ); case (FillerWordType): return new VetrocWord( FillerWordType ), true>( swappedWord ); case (UndefinedType): return new VetrocWord( UndefinedType ), true>( swappedWord ); } } else { switch ( lastDataType ) { case (BlockHeaderType): return new VetrocWord( BlockHeaderType ), false>( swappedWord ); case (BlockTrailerType): return new VetrocWord( BlockTrailerType ), false>( swappedWord ); case (EventHeaderType): return new VetrocWord( EventHeaderType ), false>( swappedWord ); case (TriggerTimeType): return new VetrocWord( TriggerTimeType ), false>( swappedWord ); case (TDCHitType): return new VetrocWord( TDCHitType ), false>( swappedWord ); case (Profiler2DType): return new VetrocWord( Profiler2DType ), false>( swappedWord ); case (Profiler1DType): return new VetrocWord( Profiler1DType ), false>( swappedWord ); case (EmptyModuleType): return new VetrocWord( EmptyModuleType ), false>( swappedWord ); case (FillerWordType): return new VetrocWord( FillerWordType ), false>( swappedWord ); case (UndefinedType): return new VetrocWord( UndefinedType ), false>( swappedWord ); } } return 0; } }; template<> class VetrocWord : public VetrocWordBase { protected: // Define masks static const uint32_t blockNumberMask; static const uint32_t blockSizeMask; public: // Constructor. The data is copied from uint32_t word into the data member. VetrocWord( const uint32_t& swappedWord ) : VetrocWordBase( swappedWord ) { } VetrocWord( const VetrocWord& w ) : VetrocWordBase( w ) { } virtual ~VetrocWord() { } VetrocWord& operator=( const VetrocWord& w ) { if ( this != &w ) { *dynamic_cast( this ) = w; } return *this; } virtual dataType getType() const { return VetrocWordInterface::BlockHeaderType; } virtual bool isDataTypeDefinition() const { return true; } virtual unsigned long getBlockNumber() const { return ((word & blockNumberMask) >> lspForWordTypeMap[blockNumberMask]); } virtual unsigned long getBlockSize() const { return (word & blockSizeMask); } static const uint32_t getBlockNumberMask() { return blockNumberMask; } static const uint32_t getBlockSizeMask() { return blockSizeMask; } }; template<> class VetrocWord : public VetrocWordBase { protected: // Define masks static const uint32_t triggerNumberMask; public: // Constructor. The data is copied from uint32_t word into the data member. VetrocWord( const uint32_t& swappedWord ) : VetrocWordBase( swappedWord ) { } VetrocWord( const VetrocWord& w ) : VetrocWordBase( w ) { } virtual ~VetrocWord() { } VetrocWord& operator=( const VetrocWord& w ) { if ( this != &w ) { *dynamic_cast( this ) = w; } return *this; } virtual dataType getType() const { return VetrocWordInterface::EventHeaderType; } virtual bool isDataTypeDefinition() const { return true; } virtual unsigned long getEventNumber() const { return (word & triggerNumberMask); } static const uint32_t getTriggerNumberMask() { return triggerNumberMask; } }; template<> class VetrocWord : public VetrocWordBase { protected: // Define masks static const uint32_t scalerValueMask; static const uint32_t binIdMask; public: // Constructor. The data is copied from uint32_t word into the data member. VetrocWord( const uint32_t& swappedWord ) : VetrocWordBase( swappedWord ) { } VetrocWord( const VetrocWord& w ) : VetrocWordBase( w ) { } virtual ~VetrocWord() { } VetrocWord& operator=( const VetrocWord& w ) { if ( this != &w ) { *dynamic_cast( this ) = w; } return *this; } virtual uint32_t getScalerCounts() const { return ( word & scalerValueMask ); } virtual uint32_t getBinID() const { return ( (word & binIdMask) >> lspForWordTypeMap[binIdMask] ); } virtual dataType getType() const { return VetrocWordInterface::Profiler1DType; } virtual bool isDataTypeDefinition() const { return false; } static const uint32_t getBinIdMask() { return binIdMask; } static const uint32_t getScalerValueMask() { return scalerValueMask; } }; template<> class VetrocWord : public VetrocWordBase { protected: // Define masks static const uint32_t accidentalMask; public: // Constructor. The data is copied from uint32_t word into the data member. VetrocWord( const uint32_t& swappedWord ) : VetrocWordBase( swappedWord ) { } VetrocWord( const VetrocWord& w ) : VetrocWordBase( w ) { } virtual ~VetrocWord() { } VetrocWord& operator=( const VetrocWord& w ) { if ( this != &w ) { *dynamic_cast( this ) = w; } return *this; } virtual bool isAccidental() const { return ( (word & accidentalMask) == 1 ); } virtual dataType getType() const { return VetrocWordInterface::Profiler2DType; } virtual bool isDataTypeDefinition() const { return true; } static const uint32_t getAccidentalMask() { return accidentalMask; } }; template<> class VetrocWord : public VetrocWordBase { protected: // Define masks static const uint32_t scalerValueMask; static const uint32_t binXMask; static const uint32_t binYMask; public: // Constructor. The data is copied from uint32_t word into the data member. VetrocWord( const uint32_t& swappedWord ) : VetrocWordBase( swappedWord ) { } VetrocWord( const VetrocWord& w ) : VetrocWordBase( w ) { } virtual ~VetrocWord() { } VetrocWord& operator=( const VetrocWord& w ) { if ( this != &w ) { *dynamic_cast( this ) = w; } return *this; } virtual uint32_t getScalerCounts() const { return ( word & scalerValueMask ); } virtual uint32_t getBinX() const { return ( (word & binXMask) >> lspForWordTypeMap[binXMask] ); } virtual uint32_t getBinY() const { return ( (word & binYMask) >> lspForWordTypeMap[binYMask] ); } virtual dataType getType() const { return VetrocWordInterface::Profiler2DType; } virtual bool isDataTypeDefinition() const { return false; } static const uint32_t getBinXMask() { return binXMask; } static const uint32_t getBinYMask() { return binYMask; } static const uint32_t getScalerValueMask() { return scalerValueMask; } }; template<> class VetrocWord : public VetrocWordBase { protected: // Define masks static const uint32_t triggerTimeMask; public: // Constructor. The data is copied from uint32_t word into the data member. VetrocWord( const uint32_t& swappedWord ) : VetrocWordBase( swappedWord ) { } VetrocWord( const VetrocWord& w ) : VetrocWordBase( w ) { } virtual ~VetrocWord() { } VetrocWord& operator=( const VetrocWord& w ) { if ( this != &w ) { *dynamic_cast( this ) = w; } return *this; } virtual uint32_t getTriggerTime() const { return (word & triggerTimeMask); } virtual dataType getType() const { return VetrocWordInterface::TriggerTimeType; } virtual bool isDataTypeDefinition() const { return true; } static const uint32_t getTriggerTimeMask() { return triggerTimeMask; } }; template<> class VetrocWord : public VetrocWordBase { protected: // Define masks static const uint32_t triggerTimeMask; public: // Constructor. The data is copied from uint32_t word into the data member. VetrocWord( const uint32_t& swappedWord ) : VetrocWordBase( swappedWord ) { } VetrocWord( const VetrocWord& w ) : VetrocWordBase( w ) { } virtual ~VetrocWord() { } VetrocWord& operator=( const VetrocWord& w ) { if ( this != &w ) { *dynamic_cast( this ) = w; } return *this; } virtual uint32_t getTriggerTime() const { return (word & triggerTimeMask); } virtual dataType getType() const { return VetrocWordInterface::TriggerTimeType; } virtual bool isDataTypeDefinition() const { return false; } static const uint32_t getTriggerTimeMask() { return triggerTimeMask; } }; #endif /* VETROCAPP_SRC_VETROCWORD_HH_ */