Commit 28a68d9b authored by Felix Weiglhofer's avatar Felix Weiglhofer
Browse files

Reduce size of StsDigi to 8 bytes.

parent eebe8132
......@@ -131,9 +131,18 @@
#pragma link C++ class CbmDigiVector < CbmPsdDsp> + ;
#pragma link C++ class vector < CbmEventStore> + ;
#pragma read sourceClass = "CbmTofDigi" version = "[1-2]" targetClass = "CbmTofDigi" source = \
"UInt_t fuAddress" target = "fuAddress" include = "Logger.h" code = \
"{ UInt_t system = (onfile.fuAddress >> 0) & ((1 << 4) - 1); \
#pragma read sourceClass="CbmStsDigi" version="[7]" targetClass="CbmStsDigi" \
source="Long64_t fTime; Int_t fAddress; UShort_t fChannel; UShort_t fCharge" \
target="" \
include="Logger.h" \
code="{ newObj->SetAddressAndTime(onfile.fAddress, onfile.fTime); \
newObj->SetChannelAndCharge(onfile.fChannel, onfile.fCharge); \
}"
#pragma read sourceClass="CbmTofDigi" version="[1-2]" targetClass="CbmTofDigi" \
source="UInt_t fuAddress" target="fuAddress" \
include="Logger.h" \
code="{ UInt_t system = (onfile.fuAddress >> 0) & ((1 << 4) - 1); \
UInt_t smId = (onfile.fuAddress >> 4) & ((1 << 8) - 1); \
UInt_t smType = (onfile.fuAddress >> 12) & ((1 << 4) - 1); \
UInt_t rpcId = (onfile.fuAddress >> 16) & ((1 << 7) - 1); \
......
......@@ -19,6 +19,7 @@
namespace CbmStsAddress
{
// clang-format off
// ----- Definition of address bit field ------------------------------
const uint16_t kBits[kCurrentVersion + 1][kStsNofLevels] = {
......@@ -66,7 +67,7 @@ namespace CbmStsAddress
{(1 << kBits[1][0]) - 1, (1 << kBits[1][1]) - 1, (1 << kBits[1][2]) - 1, (1 << kBits[1][3]) - 1,
(1 << kBits[1][4]) - 1, (1 << kBits[1][5]) - 1, (1 << kBits[1][6]) - 1}};
// -------------------------------------------------------------------------
// clang-format on
} // Namespace CbmStsAddress
......
......@@ -108,8 +108,8 @@ namespace CbmStsAddress
** @param address Unique element address
** @value Version number
**
** The version is encoded in the last 6 bits (58 to 63).
** The maximal number of versions is 64.
** The version is encoded in the last 4 bits (28 to 31).
** The maximal number of versions is 16.
**/
uint32_t GetVersion(int32_t address);
......@@ -138,6 +138,20 @@ namespace CbmStsAddress
int32_t UnpackDigiAddress(int32_t digiAddress);
/** @brief Strip address to contain only unit, (half)ladder and module.
** @param address Full address
** @return 17 bit address that can be stored in a Digi
**/
int32_t PackDigiAddress(int32_t address);
/** @brief Add version and system to compressed address that's stored in a digi
** @param digiAddress Compressed address from digi
** @return Full address
**/
int32_t UnpackDigiAddress(int32_t digiAddress);
/** @brief String output
** @param address Unique element address
**/
......
......@@ -4,12 +4,17 @@
/** CbmStsDigi.cxx
** @author V.Friese <v.friese@gsi.de>
** @author Felix Weiglhofer <weiglhofer@fias.uni-frankfurt.de>
** @since 28.08.2006
** @version 4.0
**/
#include "CbmStsDigi.h"
#include "CbmStsAddress.h"
#include <algorithm>
#include <cstdlib>
#include <sstream> // for operator<<, basic_ostream, char_traits
using std::string;
......@@ -19,10 +24,29 @@ using std::stringstream;
string CbmStsDigi::ToString() const
{
stringstream ss;
ss << "StsDigi: address " << fAddress << " | channel " << fChannel << " | charge " << fCharge << " | time " << fTime;
ss << "StsDigi: address " << UnpackAddress() << " | channel " << UnpackChannel() << " | charge " << UnpackCharge()
<< " | time " << UnpackTime();
return ss.str();
}
void CbmStsDigi::PackAddressAndTime(int32_t newAddress, uint32_t newTime)
{
int32_t packedAddr = CbmStsAddress::PackDigiAddress(newAddress);
uint32_t highestBitAddr = packedAddr >> kNumLowerAddrBits;
uint32_t lowerAddr = packedAddr & ((1 << kNumLowerAddrBits) - 1);
fAddress = lowerAddr;
fTime = (highestBitAddr << kNumTimestampBits) | newTime;
}
int32_t CbmStsDigi::UnpackAddress() const
{
int32_t highestBitAddr = fTime >> kNumTimestampBits;
int32_t packedAddress = (highestBitAddr << kNumLowerAddrBits) | int32_t(fAddress);
return CbmStsAddress::UnpackDigiAddress(packedAddress);
}
#ifndef NO_ROOT
ClassImp(CbmStsDigi)
#endif
......@@ -4,6 +4,7 @@
/** @file CbmStsDigi.h
** @author V.Friese <v.friese@gsi.de>
** @author Felix Weiglhofer <weiglhofer@fias.uni-frankfurt.de>
** @since 28.08.2006
** @version 6
**/
......@@ -13,6 +14,7 @@
#define CBMSTSDIGI_H 1
#include "CbmDefs.h" // for ECbmModuleId::kSts
#include "CbmStsAddress.h"
#ifndef NO_ROOT
#include <Rtypes.h> // for ClassDef
......@@ -45,23 +47,20 @@ public:
** @param time Measurement time [ns]
** @param charge Charge [ADC units]
**/
CbmStsDigi(int32_t address, int32_t channel, uint64_t time, uint16_t charge)
: fTime(time)
, fAddress(address)
, fChannel(channel)
, fCharge(charge)
CbmStsDigi(int32_t address, int32_t channel, uint32_t time, uint16_t charge)
{
PackAddressAndTime(address, time);
PackChannelAndCharge(channel, charge);
}
/** Destructor **/
~CbmStsDigi() {};
/** Unique detector element address (see CbmStsAddress)
** @value Unique address of readout channel
**/
int32_t GetAddress() const { return fAddress; }
int32_t GetAddress() const { return UnpackAddress(); }
/** @brief Get the desired name of the branch for this obj in the cbm output tree (static)
......@@ -73,7 +72,7 @@ public:
/** @brief Channel number in module
** @value Channel number
**/
uint16_t GetChannel() const { return fChannel; }
uint16_t GetChannel() const { return UnpackChannel(); }
/** @brief Class name (static)
......@@ -85,7 +84,7 @@ public:
/** Charge
** @value Charge [ADC units]
**/
double GetCharge() const { return double(fCharge); }
double GetCharge() const { return static_cast<double>(UnpackCharge()); }
/** System ID (static)
......@@ -97,16 +96,15 @@ public:
/** Time of measurement
** @value Time [ns]
**/
double GetTime() const { return double(fTime); }
double GetTime() const { return static_cast<double>(UnpackTime()); }
template<class Archive>
void serialize(Archive& ar, const unsigned int /*version*/)
{
ar& fTime;
ar& fChannelAndCharge;
ar& fAddress;
ar& fChannel;
ar& fCharge;
}
......@@ -115,11 +113,30 @@ public:
**/
void SetTime(double dNewTime)
{
// Future versions of StsDigi won't be able to store negative timestamps.
assert(dNewTime >= 0);
fTime = dNewTime;
// StsDigi is not able to store negative timestamps.
assert(dNewTime >= 0 && dNewTime <= kMaxTimestamp);
PackTime(dNewTime);
}
void SetChannel(uint16_t channel) { PackChannelAndCharge(channel, UnpackCharge()); }
void SetCharge(uint16_t charge) { PackChannelAndCharge(UnpackChannel(), charge); }
void SetAddress(int32_t address) { PackAddressAndTime(address, UnpackTime()); }
/** Set new channel and charge.
**
** Slightly more efficient than calling both individual setters.
**/
void SetChannelAndCharge(uint16_t channel, uint16_t charge) { PackChannelAndCharge(channel, charge); }
/** Set new address and time at once.
**
** Slightly more efficient than calling both individual setters.
**/
void SetAddressAndTime(int32_t address, uint32_t time) { PackAddressAndTime(address, time); }
/** String output **/
std::string ToString() const;
......@@ -128,14 +145,37 @@ public:
private:
friend class boost::serialization::access;
int64_t fTime = 0.; ///< Time [ns]
int32_t fAddress = 0; ///< Unique element address
uint16_t fChannel = 0; ///< Channel number
uint16_t fCharge = 0; ///< Charge [ADC units]
static constexpr int kNumAdcBits = 5;
static constexpr uint32_t kAdcMask = (1u << kNumAdcBits) - 1u;
static constexpr int kNumLowerAddrBits = 16;
static constexpr int kNumTimestampBits = 31;
static constexpr uint32_t kTimestampMask = (1u << kNumTimestampBits) - 1u;
static constexpr uint32_t kMaxTimestamp = kTimestampMask;
static constexpr uint32_t kTimeAddressBitMask = ~kTimestampMask;
uint32_t fTime = 0; ///< Time [ns] in lower 31 bits, highest bit is the 17th address bit.
uint16_t fChannelAndCharge = 0; ///< Channel number (lower 11 bits) and charge [ADC Units] in upper 5 bits.
uint16_t fAddress = 0; ///< Unique element address (lower 16 bits of 17)
void PackTime(uint32_t newTime) { fTime = (fTime & kTimeAddressBitMask) | (newTime & kTimestampMask); }
uint32_t UnpackTime() const { return fTime & kTimestampMask; }
void PackChannelAndCharge(uint16_t channel, uint16_t charge)
{
fChannelAndCharge = (channel << kNumAdcBits) | charge;
}
uint16_t UnpackChannel() const { return fChannelAndCharge >> kNumAdcBits; }
uint16_t UnpackCharge() const { return fChannelAndCharge & kAdcMask; }
void PackAddressAndTime(int32_t address, uint32_t time);
int32_t UnpackAddress() const;
#ifndef NO_ROOT
ClassDefNV(CbmStsDigi, 7);
ClassDefNV(CbmStsDigi, 8);
#endif
};
......
......@@ -2,61 +2,66 @@
SPDX-License-Identifier: GPL-3.0-only
Authors: Florian Uhlig [committer] */
#include "CbmStsAddress.h"
#include "CbmStsDigi.h"
#include "compareStsDigi.h"
#include "gtest/gtest-spi.h"
#include "gtest/gtest.h"
static const Int_t kTestAddress = CbmStsAddress::GetAddress(5, 6, 1, 8, 0, 0, 1);
TEST(_GTestCbmStsDigi, CheckDefaultConstructor)
{
// Create object
CbmStsDigi test;
compareStsDigiDataMembers(test, 0, 0, 0, ECbmModuleId::kSts, 0);
const Int_t defaultAddr = CbmStsAddress::GetAddress(0, 0, 0, 0, 0, 0, 1);
compareStsDigiDataMembers(test, defaultAddr, 0, 0, ECbmModuleId::kSts, 0);
CbmStsDigi* test1 = new CbmStsDigi();
compareStsDigiDataMembers(*test1, 0, 0, 0, ECbmModuleId::kSts, 0);
compareStsDigiDataMembers(*test1, defaultAddr, 0, 0, ECbmModuleId::kSts, 0);
}
TEST(_GTestCbmStsDigi, CheckStandardConstructor)
{
// Create object
CbmStsDigi test(111, 42, 987654321, 23);
CbmStsDigi test(kTestAddress, 42, 987654321, 23);
compareStsDigiDataMembers(test, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
CbmStsDigi* test1 = new CbmStsDigi(111, 42, 897654321, 23);
CbmStsDigi* test1 = new CbmStsDigi(kTestAddress, 42, 987654321, 23);
compareStsDigiDataMembers(*test1, 111, 23, 42, ECbmModuleId::kSts, 897654321);
compareStsDigiDataMembers(*test1, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
}
TEST(_GTestCbmStsDigi, CheckCopyConstructor)
{
// Create object
CbmStsDigi test(111, 42, 987654321, 23);
CbmStsDigi test(kTestAddress, 42, 987654321, 23);
compareStsDigiDataMembers(test, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
// Create object by copy constructing
// test should be equal to test2 and
// test should not be changed
CbmStsDigi test2 {test};
compareStsDigiDataMembers(test2, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test2, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
// Test if the original object wasn't changed
compareStsDigiDataMembers(test, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
}
TEST(_GTestCbmStsDigi, CheckAssignmentOperator)
{
// Create object
CbmStsDigi test(111, 42, 987654321, 23);
CbmStsDigi test(kTestAddress, 42, 987654321, 23);
compareStsDigiDataMembers(test, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
// Create object by copy assignment
// test should be equal to test2 and
......@@ -64,73 +69,77 @@ TEST(_GTestCbmStsDigi, CheckAssignmentOperator)
CbmStsDigi test2;
test2 = test;
compareStsDigiDataMembers(test2, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test2, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
// Test if the original object wasn't changed
compareStsDigiDataMembers(test, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
}
TEST(_GTestCbmStsDigi, CheckMoveConstructor)
{
// Create object
CbmStsDigi test(111, 42, 987654321, 23);
CbmStsDigi test(kTestAddress, 42, 987654321, 23);
compareStsDigiDataMembers(test, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
// Create object by move constructing
CbmStsDigi test2 {std::move(test)};
compareStsDigiDataMembers(test2, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test2, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
// For objects with simple types move fall back to copy so
// the original object is kept unchanged
compareStsDigiDataMembers(test, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
}
TEST(_GTestCbmStsDigi, CheckAssignmentMoveConstructor)
{
// Create object
CbmStsDigi test(111, 42, 987654321, 23);
CbmStsDigi test(kTestAddress, 42, 987654321, 23);
compareStsDigiDataMembers(test, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
// Create object by move constructing
CbmStsDigi test2 {};
test2 = std::move(test);
compareStsDigiDataMembers(test2, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test2, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
// For objects with simple types move fall back to copy so
// the original object is kept unchanged
compareStsDigiDataMembers(test, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
}
TEST(_GTestCbmStsDigi, CheckSetTime)
{
// Create object
CbmStsDigi test(111, 42, 987654321, 23);
CbmStsDigi test(kTestAddress, 42, 987654321, 23);
compareStsDigiDataMembers(test, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
test.SetTime(897654321.0);
compareStsDigiDataMembers(test, 111, 23, 42, ECbmModuleId::kSts, 897654321);
compareStsDigiDataMembers(test, kTestAddress, 23, 42, ECbmModuleId::kSts, 897654321);
}
TEST(_GTestCbmStsDigi, CheckToString)
{
CbmStsDigi test(111, 42, 987654321, 23);
CbmStsDigi test(kTestAddress, 42, 987654321, 23);
compareStsDigiDataMembers(test, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
EXPECT_STREQ("StsDigi: address 111 | channel 42 | charge 23 | time 987654321", test.ToString().c_str());
std::string expected =
"StsDigi: address " + std::to_string(kTestAddress) + " | channel 42 | charge 23 | time 987654321";
EXPECT_STREQ(expected.c_str(), test.ToString().c_str());
}
TEST(_GTestCbmStsDigi, CheckGetClassName)
{
CbmStsDigi test(111, 42, 987654321, 23);
CbmStsDigi test(kTestAddress, 42, 987654321, 23);
compareStsDigiDataMembers(test, 111, 23, 42, ECbmModuleId::kSts, 987654321);
compareStsDigiDataMembers(test, kTestAddress, 23, 42, ECbmModuleId::kSts, 987654321);
EXPECT_STREQ("CbmStsDigi", test.GetClassName());
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment