From 0b00f0e422459f55f4e16ccedcdb32b73c5c5c9d Mon Sep 17 00:00:00 2001 From: Gordon McCann Date: Thu, 19 May 2022 14:52:20 -0400 Subject: [PATCH] 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 --- src/evb/CompassFile.cpp | 154 +++++++++++++++++++++----------------- src/evb/CompassFile.h | 48 ++++++++---- src/evb/CompassHit.h | 9 ++- src/evb/CompassRun.cpp | 11 ++- src/evb/EVBApp.cpp | 14 ++-- src/evb/SlowSort.cpp | 5 +- src/evbdict/DataStructs.h | 1 + 7 files changed, 141 insertions(+), 101 deletions(-) diff --git a/src/evb/CompassFile.cpp b/src/evb/CompassFile.cpp index 5fd9c72..939a7bf 100644 --- a/src/evb/CompassFile.cpp +++ b/src/evb/CompassFile.cpp @@ -14,37 +14,31 @@ namespace EventBuilder { CompassFile::CompassFile() : - m_filename(""), m_bufferIter(nullptr), m_bufferEnd(nullptr), m_smap(nullptr), m_hitUsedFlag(true), m_file(std::make_shared()), - 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()), 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()), - 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()), 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()), 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()), m_eofFlag(false) { - m_buffersize = m_bufsizeHits*m_hitsize; - m_hitBuffer.resize(m_buffersize); Open(filename); } - CompassFile::~CompassFile() + CompassFile::~CompassFile() { Close(); } - void CompassFile::Open(const std::string& filename) + void CompassFile::Open(const std::string& filename) { m_eofFlag = false; m_hitUsedFlag = true; @@ -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 + } + 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() + void CompassFile::Close() { - if(IsOpen()) - m_file->close(); - } - - unsigned int CompassFile::GetHitSize() - { - if(!IsOpen()) + if(IsOpen()) { - std::cerr<<"Unable to get hit size due to file not being open!"<close(); } + } - char* firstHit = new char[24]; //A compass hit by default has 24 bytes (at least in our setup) - - m_file->read(firstHit, 24); + void CompassFile::ReadHeader() + { + 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]); - - m_file->seekg(0, std::ios_base::beg); - - delete[] firstHit; - - return 24 + nsamples*4; - + delete[] header; } /* @@ -106,13 +113,14 @@ namespace EventBuilder { */ bool CompassFile::GetNextHit() { - if(!IsOpen()) - return true; + if(!IsOpen()) return true; - if((m_bufferIter == nullptr || m_bufferIter == m_bufferEnd) && !IsEOF()) + if((m_bufferIter == nullptr || m_bufferIter == m_bufferEnd) && !IsEOF()) + { GetNextBuffer(); + } - if(!IsEOF()) + if(!IsEOF()) { ParseNextHit(); m_hitUsedFlag = false; @@ -128,10 +136,10 @@ namespace EventBuilder { 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). */ - void CompassFile::GetNextBuffer() + void CompassFile::GetNextBuffer() { - if(m_file->eof()) + if(m_file->eof()) { m_eofFlag = true; return; @@ -144,7 +152,7 @@ namespace EventBuilder { } - void CompassFile::ParseNextHit() + void CompassFile::ParseNextHit() { m_currentHit.board = *((uint16_t*)m_bufferIter); @@ -153,32 +161,42 @@ namespace EventBuilder { m_bufferIter += 2; m_currentHit.timestamp = *((uint64_t*)m_bufferIter); m_bufferIter += 8; - m_currentHit.lgate = *((uint16_t*)m_bufferIter); - m_bufferIter += 2; - m_currentHit.sgate = *((uint16_t*)m_bufferIter); - m_bufferIter += 2; + if(IsEnergy()) + { + m_currentHit.energy = *((uint16_t*)m_bufferIter); + 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_bufferIter += 4; - m_currentHit.Ns = *((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; iGetShift(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."<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; @@ -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, + }; }; diff --git a/src/evb/CompassHit.h b/src/evb/CompassHit.h index 9aa3f60..59b30e1 100644 --- a/src/evb/CompassHit.h +++ b/src/evb/CompassHit.h @@ -3,17 +3,20 @@ namespace EventBuilder { - struct CompassHit + struct CompassHit { 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 samples; }; } + #endif diff --git a/src/evb/CompassRun.cpp b/src/evb/CompassRun.cpp index 40b49de..41c912d 100644 --- a/src/evb/CompassRun.cpp +++ b/src/evb/CompassRun.cpp @@ -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(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()) { diff --git a/src/evb/EVBApp.cpp b/src/evb/EVBApp.cpp index db4534a..3704673 100644 --- a/src/evb/EVBApp.cpp +++ b/src/evb/EVBApp.cpp @@ -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) diff --git a/src/evb/SlowSort.cpp b/src/evb/SlowSort.cpp index 39f616c..a18702a 100644 --- a/src/evb/SlowSort.cpp +++ b/src/evb/SlowSort.cpp @@ -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; diff --git a/src/evbdict/DataStructs.h b/src/evbdict/DataStructs.h index 5016a4c..d28a09f 100644 --- a/src/evbdict/DataStructs.h +++ b/src/evbdict/DataStructs.h @@ -13,6 +13,7 @@ struct DPPChannel { double Timestamp; int Channel, Board, Energy, EnergyShort; + uint64_t EnergyCal; int Flags; std::vector Samples; };