Preparing for update to newer CoMPASS version. Binary file format changed to reflect the state of optional data (i.e. energyShort, energyCal, waves). Tested using small data from CoMPASS 2.01.0

This commit is contained in:
Gordon McCann 2022-05-19 14:52:20 -04:00
parent 3ee10767bf
commit 0b00f0e422
7 changed files with 141 additions and 101 deletions

View File

@ -14,28 +14,22 @@
namespace EventBuilder {
CompassFile::CompassFile() :
m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_file(std::make_shared<std::ifstream>()),
m_eofFlag(false)
m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_hitsize(0), m_buffersize(0),
m_file(std::make_shared<std::ifstream>()), m_eofFlag(false)
{
m_buffersize = m_bufsizeHits*m_hitsize;
m_hitBuffer.resize(m_buffersize);
}
CompassFile::CompassFile(const std::string& filename) :
m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_file(std::make_shared<std::ifstream>()),
m_eofFlag(false)
m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_hitsize(0), m_buffersize(0),
m_file(std::make_shared<std::ifstream>()), m_eofFlag(false)
{
m_buffersize = m_bufsizeHits*m_hitsize;
m_hitBuffer.resize(m_buffersize);
Open(filename);
}
CompassFile::CompassFile(const std::string& filename, uint64_t bsize) :
m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true),
m_bufsizeHits(bsize), m_file(std::make_shared<std::ifstream>()), m_eofFlag(false)
CompassFile::CompassFile(const std::string& filename, int bsize) :
m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_bufsize(bsize), m_hitsize(0),
m_buffersize(0), m_file(std::make_shared<std::ifstream>()), m_eofFlag(false)
{
m_buffersize = m_bufsizeHits*m_hitsize;
m_hitBuffer.resize(m_buffersize);
Open(filename);
}
@ -53,47 +47,60 @@ namespace EventBuilder {
m_file->seekg(0, std::ios_base::end);
m_size = m_file->tellg();
if(m_size <= 24)
if(m_size == 0)
{
m_eofFlag = true;
m_nHits = 0;
}
else
{
m_file->seekg(0, std::ios_base::beg);
m_hitsize = GetHitSize();
m_buffersize = m_hitsize*m_bufsizeHits;
m_hitBuffer.resize(m_buffersize);
ReadHeader();
m_nHits = m_size/m_hitsize;
m_buffersize = m_hitsize*m_bufsize;
m_hitBuffer.resize(m_buffersize);
}
}
void CompassFile::Close()
{
if(IsOpen())
{
m_file->close();
}
}
unsigned int CompassFile::GetHitSize()
void CompassFile::ReadHeader()
{
if(!IsOpen())
{
std::cerr<<"Unable to get hit size due to file not being open!"<<std::endl;
return 0;
EVB_WARN("Unable to read header from file. State not validated", m_filename);
return;
}
char* header = new char[2];
m_file->read(header, 2);
m_header = *((uint16_t*)header);
m_hitsize = 16; //default hitsize of 16 bytes
if(IsEnergy())
m_hitsize += 2;
if(IsEnergyCalibrated())
m_hitsize += 8;
if(IsEnergyShort())
m_hitsize += 2;
if(IsWaves())
{
m_hitsize += 5;
char* firstHit = new char[24]; //A compass hit by default has 24 bytes (at least in our setup)
m_file->read(firstHit, 24);
uint32_t nsamples = *((uint32_t*) &firstHit[20]);
firstHit += m_hitsize - 4;
uint32_t nsamples = *((uint32_t*) firstHit);
m_hitsize += nsamples * 2; //Each sample is a 2 byte data value
m_file->seekg(0, std::ios_base::beg);
m_file->read(header, 2);
delete[] firstHit;
}
return 24 + nsamples*4;
delete[] header;
}
/*
@ -106,11 +113,12 @@ namespace EventBuilder {
*/
bool CompassFile::GetNextHit()
{
if(!IsOpen())
return true;
if(!IsOpen()) return true;
if((m_bufferIter == nullptr || m_bufferIter == m_bufferEnd) && !IsEOF())
{
GetNextBuffer();
}
if(!IsEOF())
{
@ -153,14 +161,35 @@ namespace EventBuilder {
m_bufferIter += 2;
m_currentHit.timestamp = *((uint64_t*)m_bufferIter);
m_bufferIter += 8;
m_currentHit.lgate = *((uint16_t*)m_bufferIter);
if(IsEnergy())
{
m_currentHit.energy = *((uint16_t*)m_bufferIter);
m_bufferIter += 2;
m_currentHit.sgate = *((uint16_t*)m_bufferIter);
}
if(IsEnergyCalibrated())
{
m_currentHit.energyCalibrated = *((uint64_t*)m_bufferIter);
m_bufferIter += 8;
}
if(IsEnergyShort())
{
m_currentHit.energyShort = *((uint16_t*)m_bufferIter);
m_bufferIter += 2;
}
m_currentHit.flags = *((uint32_t*)m_bufferIter);
m_bufferIter += 4;
if(IsWaves())
{
m_currentHit.waveCode = *((uint8_t*)m_bufferIter);
m_bufferIter += 1;
m_currentHit.Ns = *((uint32_t*)m_bufferIter);
m_bufferIter += 4;
for(uint32_t i=0; i<m_currentHit.Ns; i++)
{
m_currentHit.samples.push_back(*(uint16_t*)m_bufferIter);
m_bufferIter += 2;
}
}
if(m_smap != nullptr)
{ //memory safety
@ -168,17 +197,6 @@ namespace EventBuilder {
m_currentHit.timestamp += m_smap->GetShift(gchan);
}
/*
if(m_currentHit.Ns*2 + 24 != hitsize) {
std::cerr<<"WARNING! Hit size does not match current value of samples... Try to proceed, but expect seg fault."<<std::endl;
return;
}
*/
for(unsigned int i=0; i<m_currentHit.Ns; i++)
{
m_currentHit.samples.push_back(*((uint16_t*)m_bufferIter));
m_bufferIter += 2;
}
}
}

View File

@ -19,32 +19,38 @@ namespace EventBuilder {
class CompassFile
{
public:
CompassFile();
CompassFile(const std::string& filename);
CompassFile(const std::string& filename, uint64_t bsize);
CompassFile(const std::string& filename, int bsize);
~CompassFile();
void Open(const std::string& filename);
void Close();
bool GetNextHit();
inline bool IsOpen() { return m_file->is_open(); }
inline bool IsOpen() const { return m_file->is_open(); };
inline CompassHit GetCurrentHit() const { return m_currentHit; }
inline std::string GetName() { return m_filename; }
inline bool CheckHitHasBeenUsed() { return m_hitUsedFlag; } //query to find out if we've used the current hit
inline std::string GetName() const { return m_filename; }
inline bool CheckHitHasBeenUsed() const { return m_hitUsedFlag; } //query to find out if we've used the current hit
inline void SetHitHasBeenUsed() { m_hitUsedFlag = true; } //flip the flag to indicate the current hit has been used
inline bool IsEOF() { return m_eofFlag; }; //see if we've read all available data
inline bool IsEOF() const { return m_eofFlag; } //see if we've read all available data
inline bool* GetUsedFlagPtr() { return &m_hitUsedFlag; }
inline void AttachShiftMap(ShiftMap* map) { m_smap = map; }
inline uint64_t GetSize() { return m_size; }
inline uint64_t GetNumberOfHits() { return m_nHits; }
inline unsigned int GetSize() const { return m_size; }
inline unsigned int GetNumberOfHits() const { return m_nHits; }
private:
unsigned int GetHitSize();
void ReadHeader();
void ParseNextHit();
void GetNextBuffer();
inline bool IsEnergy() { return (m_header & CoMPASSHeaders::Energy) != 0; }
inline bool IsEnergyCalibrated() { return (m_header & CoMPASSHeaders::EnergyCalibrated) != 0; }
inline bool IsEnergyShort() { return (m_header & CoMPASSHeaders::EnergyShort) != 0; }
inline bool IsWaves() { return (m_header & CoMPASSHeaders::Waves) != 0; }
using Buffer = std::vector<char>;
using FilePointer = std::shared_ptr<std::ifstream>; //to make this class copy/movable
@ -54,16 +60,26 @@ namespace EventBuilder {
char* m_bufferIter;
char* m_bufferEnd;
ShiftMap* m_smap; //NOT owned by CompassFile. DO NOT delete
bool m_hitUsedFlag;
uint64_t m_bufsizeHits = 200000; //size of the buffer in hits
uint32_t m_hitsize = 24; //size of a CompassHit in bytes (without alignment padding), sans waveform samples
uint64_t m_buffersize;
int m_bufsize = 200000; //size of the buffer in hits
int m_hitsize; //size of a CompassHit in bytes (without alignment padding)
uint16_t m_header;
int m_buffersize;
CompassHit m_currentHit;
FilePointer m_file;
bool m_eofFlag;
uint64_t m_size; //size of the file in bytes
uint64_t m_nHits; //number of hits in the file (m_size/24)
unsigned int m_size; //size of the file in bytes
unsigned int m_nHits; //number of hits in the file (m_size/24)
enum CoMPASSHeaders
{
Energy = 0x0001,
EnergyCalibrated = 0x0002,
EnergyShort = 0x0004,
Waves = 0x0008,
};
};

View File

@ -8,12 +8,15 @@ namespace EventBuilder {
uint16_t board = 400;
uint16_t channel = 400;
uint64_t timestamp = 0;
uint16_t lgate = 0;
uint16_t sgate = 0;
uint16_t energy = 0;
uint64_t energyCalibrated = 0;
uint16_t energyShort = 0;
uint32_t flags = 0;
uint8_t waveCode = 0;
uint32_t Ns = 0;
std::vector<uint16_t> samples;
};
}
#endif

View File

@ -47,7 +47,7 @@ namespace EventBuilder {
while(input>>filename)
{
input>>varname;
filename = directory+filename+"_run_"+std::to_string(runNum)+".bin";
filename = directory+filename+"_run_"+std::to_string(runNum)+".BIN";
m_scaler_map[filename] = TParameter<int64_t>(varname.c_str(), init);
}
input.close();
@ -56,7 +56,7 @@ namespace EventBuilder {
bool CompassRun::GetBinaryFiles()
{
std::string prefix = "";
std::string suffix = ".bin"; //binaries
std::string suffix = ".BIN"; //binaries
RunCollector grabber(directory, prefix, suffix);
grabber.GrabAllFiles();
@ -165,10 +165,13 @@ namespace EventBuilder {
outtree->Branch("Board", &hit.board);
outtree->Branch("Channel", &hit.channel);
outtree->Branch("Energy", &hit.lgate);
outtree->Branch("EnergyShort", &hit.sgate);
outtree->Branch("Energy", &hit.energy);
outtree->Branch("EnergyShort", &hit.energyShort);
outtree->Branch("EnergyCal", &hit.energyCalibrated);
outtree->Branch("Timestamp", &hit.timestamp);
outtree->Branch("Flags", &hit.flags);
outtree->Branch("Ns", &hit.Ns);
outtree->Branch("Samples", &hit.samples);
if(!m_smap.IsSet())
{

View File

@ -104,7 +104,6 @@ namespace EventBuilder {
void EVBApp::Convert2RawRoot()
{
int sys_return;
std::string rawroot_dir = m_workspace+"/raw_root/";
std::string unpack_dir = m_workspace+"/temp_binary/";
std::string binary_dir = m_workspace+"/raw_binary/";
@ -131,11 +130,11 @@ namespace EventBuilder {
EVB_INFO("Converting file {0}...", binfile);
rawfile = rawroot_dir + "compass_run_"+ std::to_string(i) + ".root";
unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
wipe_command = "rm -r "+unpack_dir+"*.bin";
wipe_command = "rm -r "+unpack_dir+"*.BIN";
sys_return = system(unpack_command.c_str());
system(unpack_command.c_str());
converter.Convert2RawRoot(rawfile);
sys_return = system(wipe_command.c_str());
system(wipe_command.c_str());
}
EVB_INFO("Conversion complete.");
@ -161,7 +160,6 @@ namespace EventBuilder {
void EVBApp::Convert2SortedRoot()
{
int sys_return;
std::string sortroot_dir = m_workspace+"/sorted/";
std::string unpack_dir = m_workspace+"/temp_binary/";
std::string binary_dir = m_workspace+"/raw_binary/";
@ -191,11 +189,11 @@ namespace EventBuilder {
sortfile = sortroot_dir +"run_"+std::to_string(i)+ ".root";
unpack_command = "tar -xzf "+binfile+" --directory "+unpack_dir;
wipe_command = "rm -r "+unpack_dir+"*.bin";
wipe_command = "rm -r "+unpack_dir+"*.BIN";
sys_return = system(unpack_command.c_str());
system(unpack_command.c_str());
converter.Convert2SortedRoot(sortfile, m_SlowWindow);
sys_return = system(wipe_command.c_str());
system(wipe_command.c_str());
count++;
}
if(count==0)

View File

@ -31,8 +31,9 @@ namespace EventBuilder {
{
DPPChannel curHit;
curHit.Timestamp = mhit.timestamp/1.0e3; //convert to ns for easier drawing
curHit.Energy = mhit.lgate;
curHit.EnergyShort = mhit.sgate;
curHit.Energy = mhit.energy;
curHit.EnergyShort = mhit.energyShort;
curHit.EnergyCal = mhit.energyCalibrated;
curHit.Channel = mhit.channel;
curHit.Board = mhit.board;
curHit.Flags = mhit.flags;

View File

@ -13,6 +13,7 @@ struct DPPChannel
{
double Timestamp;
int Channel, Board, Energy, EnergyShort;
uint64_t EnergyCal;
int Flags;
std::vector<uint16_t> Samples;
};