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,37 +14,31 @@
namespace EventBuilder { namespace EventBuilder {
CompassFile::CompassFile() : CompassFile::CompassFile() :
m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_file(std::make_shared<std::ifstream>()), m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_hitsize(0), m_buffersize(0),
m_eofFlag(false) 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) : 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_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_hitsize(0), m_buffersize(0),
m_eofFlag(false) m_file(std::make_shared<std::ifstream>()), m_eofFlag(false)
{ {
m_buffersize = m_bufsizeHits*m_hitsize;
m_hitBuffer.resize(m_buffersize);
Open(filename); Open(filename);
} }
CompassFile::CompassFile(const std::string& filename, uint64_t bsize) : CompassFile::CompassFile(const std::string& filename, int bsize) :
m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_bufsize(bsize), m_hitsize(0),
m_bufsizeHits(bsize), m_file(std::make_shared<std::ifstream>()), m_eofFlag(false) 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); Open(filename);
} }
CompassFile::~CompassFile() CompassFile::~CompassFile()
{ {
Close(); Close();
} }
void CompassFile::Open(const std::string& filename) void CompassFile::Open(const std::string& filename)
{ {
m_eofFlag = false; m_eofFlag = false;
m_hitUsedFlag = true; m_hitUsedFlag = true;
@ -53,47 +47,60 @@ namespace EventBuilder {
m_file->seekg(0, std::ios_base::end); m_file->seekg(0, std::ios_base::end);
m_size = m_file->tellg(); m_size = m_file->tellg();
if(m_size <= 24) if(m_size == 0)
{ {
m_eofFlag = true; m_eofFlag = true;
m_nHits = 0; }
} else
else
{ {
m_file->seekg(0, std::ios_base::beg); m_file->seekg(0, std::ios_base::beg);
m_hitsize = GetHitSize(); ReadHeader();
m_buffersize = m_hitsize*m_bufsizeHits;
m_hitBuffer.resize(m_buffersize);
m_nHits = m_size/m_hitsize; m_nHits = m_size/m_hitsize;
m_buffersize = m_hitsize*m_bufsize;
m_hitBuffer.resize(m_buffersize);
} }
} }
void CompassFile::Close() void CompassFile::Close()
{ {
if(IsOpen()) if(IsOpen())
m_file->close();
}
unsigned int CompassFile::GetHitSize()
{
if(!IsOpen())
{ {
std::cerr<<"Unable to get hit size due to file not being open!"<<std::endl; m_file->close();
return 0;
} }
}
char* firstHit = new char[24]; //A compass hit by default has 24 bytes (at least in our setup) void CompassFile::ReadHeader()
{
m_file->read(firstHit, 24); if(!IsOpen())
{
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);
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;
}
uint32_t nsamples = *((uint32_t*) &firstHit[20]); delete[] header;
m_file->seekg(0, std::ios_base::beg);
delete[] firstHit;
return 24 + nsamples*4;
} }
/* /*
@ -106,13 +113,14 @@ namespace EventBuilder {
*/ */
bool CompassFile::GetNextHit() bool CompassFile::GetNextHit()
{ {
if(!IsOpen()) if(!IsOpen()) return true;
return true;
if((m_bufferIter == nullptr || m_bufferIter == m_bufferEnd) && !IsEOF()) if((m_bufferIter == nullptr || m_bufferIter == m_bufferEnd) && !IsEOF())
{
GetNextBuffer(); GetNextBuffer();
}
if(!IsEOF()) if(!IsEOF())
{ {
ParseNextHit(); ParseNextHit();
m_hitUsedFlag = false; m_hitUsedFlag = false;
@ -128,10 +136,10 @@ namespace EventBuilder {
bit upon pulling the last buffer, but this class waits until that entire bit upon pulling the last buffer, but this class waits until that entire
last buffer is read to singal EOF (the true end of file). last buffer is read to singal EOF (the true end of file).
*/ */
void CompassFile::GetNextBuffer() void CompassFile::GetNextBuffer()
{ {
if(m_file->eof()) if(m_file->eof())
{ {
m_eofFlag = true; m_eofFlag = true;
return; return;
@ -144,7 +152,7 @@ namespace EventBuilder {
} }
void CompassFile::ParseNextHit() void CompassFile::ParseNextHit()
{ {
m_currentHit.board = *((uint16_t*)m_bufferIter); m_currentHit.board = *((uint16_t*)m_bufferIter);
@ -153,32 +161,42 @@ namespace EventBuilder {
m_bufferIter += 2; m_bufferIter += 2;
m_currentHit.timestamp = *((uint64_t*)m_bufferIter); m_currentHit.timestamp = *((uint64_t*)m_bufferIter);
m_bufferIter += 8; m_bufferIter += 8;
m_currentHit.lgate = *((uint16_t*)m_bufferIter); if(IsEnergy())
m_bufferIter += 2; {
m_currentHit.sgate = *((uint16_t*)m_bufferIter); m_currentHit.energy = *((uint16_t*)m_bufferIter);
m_bufferIter += 2; m_bufferIter += 2;
}
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_currentHit.flags = *((uint32_t*)m_bufferIter);
m_bufferIter += 4; m_bufferIter += 4;
m_currentHit.Ns = *((uint32_t*)m_bufferIter); if(IsWaves())
m_bufferIter += 4; {
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) if(m_smap != nullptr)
{ //memory safety { //memory safety
int gchan = m_currentHit.channel + m_currentHit.board*16; int gchan = m_currentHit.channel + m_currentHit.board*16;
m_currentHit.timestamp += m_smap->GetShift(gchan); 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

@ -17,33 +17,39 @@
namespace EventBuilder { namespace EventBuilder {
class CompassFile class CompassFile
{ {
public: public:
CompassFile(); CompassFile();
CompassFile(const std::string& filename); CompassFile(const std::string& filename);
CompassFile(const std::string& filename, uint64_t bsize); CompassFile(const std::string& filename, int bsize);
~CompassFile(); ~CompassFile();
void Open(const std::string& filename); void Open(const std::string& filename);
void Close(); void Close();
bool GetNextHit(); 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 CompassHit GetCurrentHit() const { return m_currentHit; }
inline std::string GetName() { return m_filename; } inline std::string GetName() const { return m_filename; }
inline bool CheckHitHasBeenUsed() { return m_hitUsedFlag; } //query to find out if we've used the current hit 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 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 bool* GetUsedFlagPtr() { return &m_hitUsedFlag; }
inline void AttachShiftMap(ShiftMap* map) { m_smap = map; } inline void AttachShiftMap(ShiftMap* map) { m_smap = map; }
inline uint64_t GetSize() { return m_size; } inline unsigned int GetSize() const { return m_size; }
inline uint64_t GetNumberOfHits() { return m_nHits; } inline unsigned int GetNumberOfHits() const { return m_nHits; }
private: private:
unsigned int GetHitSize(); void ReadHeader();
void ParseNextHit(); void ParseNextHit();
void GetNextBuffer(); 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 Buffer = std::vector<char>;
@ -54,16 +60,26 @@ namespace EventBuilder {
char* m_bufferIter; char* m_bufferIter;
char* m_bufferEnd; char* m_bufferEnd;
ShiftMap* m_smap; //NOT owned by CompassFile. DO NOT delete ShiftMap* m_smap; //NOT owned by CompassFile. DO NOT delete
bool m_hitUsedFlag; bool m_hitUsedFlag;
uint64_t m_bufsizeHits = 200000; //size of the buffer in hits int m_bufsize = 200000; //size of the buffer in hits
uint32_t m_hitsize = 24; //size of a CompassHit in bytes (without alignment padding), sans waveform samples int m_hitsize; //size of a CompassHit in bytes (without alignment padding)
uint64_t m_buffersize; uint16_t m_header;
int m_buffersize;
CompassHit m_currentHit; CompassHit m_currentHit;
FilePointer m_file; FilePointer m_file;
bool m_eofFlag; bool m_eofFlag;
uint64_t m_size; //size of the file in bytes unsigned int m_size; //size of the file in bytes
uint64_t m_nHits; //number of hits in the file (m_size/24) 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

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

View File

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

View File

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

View File

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

View File

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