41template <
typename V1,
typename V2>
bool startsWith(
const V1 &sequence,
const V2 &subSequence) {
42 return std::equal(std::begin(subSequence), std::end(subSequence), std::begin(sequence));
58 const std::string &extn = descriptor.extension();
61 auto &file = descriptor.data();
64 std::getline(file, fileline);
65 if (fileline.find(
"mesytec psd listmode data") != std::string::npos) {
77 const std::vector<std::string> exts{
".mdat"};
79 "A DNS mesydaq listmode event datafile.");
88 "Discards events before first chopper trigger (turn off for elastic)",
92 "Sets all bin boundaries to include all events (can be turned off to save time).",
97 "The name of the output workspace.");
113 outputWS->getAxis(0)->setUnit(
"TOF");
114 outputWS->setYUnit(
"Counts");
120 auto finalEventAccumulator =
parse_File(file, fileName);
123 outputWS->setAllX({0, outputWS->getEventXMax()});
129 static const unsigned EVENTS_PER_PROGRESS = 100;
135 [](
auto l,
auto r) { return l.timestamp > r.timestamp; });
137 std::atomic<unsigned int> oversizedChanelIndexCounterA(0);
138 std::atomic<unsigned int> oversizedPosCounterA(0);
141 for (
int eventIndex = 0; eventIndex < static_cast<int>(finalEventAccumulator.
neutronEvents.size()); ++eventIndex) {
143 unsigned int oversizedChanelIndexCounter = 0;
144 unsigned int oversizedPosCounter = 0;
145 const auto wsIndex = eventIndex;
146 auto &eventList = finalEventAccumulator.
neutronEvents[eventIndex];
147 if (eventList.size() != 0) {
148 std::sort(eventList.begin(), eventList.end(), [](
auto l,
auto r) { return l.timestamp < r.timestamp; });
151 auto chopperIt = finalEventAccumulator.
triggerEvents.cbegin();
153 auto &spectrum = eventWS->getSpectrum(wsIndex);
156 uint64_t numProcessed = 0;
157 for (
const auto &event : eventList) {
159 if (numProcessed % EVENTS_PER_PROGRESS == 0) {
168 event.timestamp, [](
auto l,
auto r) { return l.timestamp > r; });
169 const uint64_t chopperTimestamp = chopperIt != finalEventAccumulator.
triggerEvents.cend()
170 ? chopperIt->timestamp
176 spectrum.addEventQuickly(Types::Event::TofEvent(
double(event.timestamp - chopperTimestamp) / 10.0));
180 oversizedChanelIndexCounterA += oversizedChanelIndexCounter;
181 oversizedPosCounterA += oversizedPosCounter;
185 if (oversizedChanelIndexCounterA > 0) {
186 g_log.
warning() <<
"Bad chanel indices: " << oversizedChanelIndexCounterA << std::endl;
188 if (oversizedPosCounterA > 0) {
189 g_log.
warning() <<
"Bad position values: " << oversizedPosCounterA << std::endl;
197 std::vector<uint8_t> header;
199 std::array<uint8_t,
header_sep.size()> current_window;
201 while (!file.
eof()) {
205 const auto orig_header_size = header.size();
206 header.resize(header.size() + 1);
207 const auto win_data = current_window.data();
208 std::copy(win_data, win_data + 1, header.data() + orig_header_size);
209 const std::array<uint8_t,
header_sep.size()> orig_window = current_window;
210 file.
readRaw(current_window, 1);
211 std::copy(orig_window.data() + 1, orig_window.data() +
header_sep.size(), win_data);
220 const uint64_t chunckSize = std::max(minChunckSize, file.
fileSize() / maxChunckCount);
222 std::vector<std::vector<uint8_t>> result;
224 while (!file.
eof()) {
225 result.push_back(std::vector<uint8_t>());
227 auto &data = result.back();
228 data.resize(chunckSize);
230 file.
readRaw(*data.begin(), chunckSize);
231 }
catch (std::ifstream::failure &) {
232 data.resize(file.
gcount());
237 static const auto windowSize =
block_sep.size();
238 uint8_t *current_window =
nullptr;
239 std::array<uint8_t, windowSize> *windowAsArray =
240 reinterpret_cast<std::array<uint8_t, windowSize> *
>(current_window);
243 data.resize(data.size() + windowSize);
245 current_window = &*(data.end() - windowSize);
246 windowAsArray =
reinterpret_cast<std::array<uint8_t, windowSize> *
>(current_window);
247 file.
readRaw(current_window[0], windowSize);
250 const auto orig_data_size = data.size();
251 data.resize(orig_data_size + 1);
253 current_window = (&data.back() - windowSize + 1);
254 windowAsArray =
reinterpret_cast<std::array<uint8_t, windowSize> *
>(current_window);
255 file.
readRaw(current_window[windowSize - 1], 1);
257 }
catch (std::ifstream::failure &) {
269 if (!
startsWith(header, std::string(
"mesytec psd listmode data"))) {
270 g_log.
error() <<
"This seems not to be a mesytec psd listmode file: " << fileName;
277 std::vector<std::vector<uint8_t>> filechuncks =
split_File(file, threadCount);
278 g_log.
debug() <<
"filechuncks count = " << filechuncks.size() << std::endl;
280 std::vector<EventAccumulator> eventAccumulators(filechuncks.size());
281 for (
auto &evtAcc : eventAccumulators) {
287 for (
int i = 0; i < static_cast<int>(filechuncks.size()); ++i) {
288 auto filechunck = filechuncks[
static_cast<size_t>(i)];
289 g_log.
debug() <<
"filechunck.size() = " << filechunck.size() << std::endl;
300 for (
const auto &v : eventAccumulators) {
302 v.triggerEvents.end());
307 for (
int i = 0; i < static_cast<int>(finalEventAccumulator.
neutronEvents.size()); ++i) {
308 auto &allNeutronEvents = finalEventAccumulator.
neutronEvents[
static_cast<size_t>(i)];
309 for (
const auto &v : eventAccumulators) {
310 allNeutronEvents.insert(allNeutronEvents.end(), v.neutronEvents[
static_cast<size_t>(i)].begin(),
311 v.neutronEvents[
static_cast<size_t>(i)].end());
315 return finalEventAccumulator;
320 while (!file.
eof() && file.
peek() != 0xFF) {
334 throw std::runtime_error(std::string(
"File Integrety LOST. 0x"));
341 const uint16_t dataLength = uint16_t(bufferHeader.bufferLength - 21);
342 const auto event_count = dataLength / 3;
344 for (uint16_t i = 0; i < event_count; i++) {
354 file.
read<2>(header.bufferLength);
355 file.
read<2>(header.bufferVersion);
356 file.
read<2>(header.headerLength);
357 file.
read<2>(header.bufferNumber);
358 file.
read<2>(header.runId);
359 file.
read<1>(header.mcpdId);
360 file.
read<1>(header.deviceStatus);
365 header.timestamp = (uint64_t)ts3 << 32 | (uint64_t)ts2 << 16 | ts1;
375 trigId = (data >> 44) & 0b111;
376 dataId = (data >> 40) & 0b1111;
389 modid = (data >> 44) & 0b111;
390 slotid = (data >> 39) & 0b11111;
409 data = (uint64_t)data3 << 32 | (uint64_t)data2 << 16 | data1;
410 eventId =
static_cast<event_id_e>((data >> 47) & 0b1);
414 if (triggerEvent.isChopperTrigger) {
415 eventAccumulator.
triggerEvents.push_back(triggerEvent.event);
420 eventAccumulator.
neutronEvents[neutronEvent.wsIndex].push_back(neutronEvent.event);
423 g_log.
error() <<
"unknown event id " << eventId <<
"\n";
431 throw std::runtime_error(std::string(
"File Integrety LOST. 0x"));
static constexpr separator_t closing_sig
static constexpr separator_t block_sep
std::array< uint8_t, 8 > separator_t
static constexpr separator_t header_sep
#define PARALLEL_START_INTERRUPT_REGION
Begins a block to skip processing is the algorithm has been interupted Note the end of the block if n...
#define PARALLEL_FOR_NO_WSP_CHECK()
#define PARALLEL_END_INTERRUPT_REGION
Ends a block to skip processing is the algorithm has been interupted Note the start of the block if n...
#define PARALLEL_FOR_IF(condition)
Empty definitions - to enable set your complier to enable openMP.
#define PARALLEL_GET_MAX_THREADS
#define PARALLEL_CHECK_INTERRUPT_REGION
Adds a check after a Parallel region to see if it was interupted.
#define DECLARE_FILELOADER_ALGORITHM(classname)
DECLARE_FILELOADER_ALGORITHM should be used in place of the standard DECLARE_ALGORITHM macro when wri...
FileByteStream & readRaw(T &result, const std::size_t &bytecount)
uint64_t fileSize() const
std::streamsize gcount() const
CancelException is thrown to cancel execution of the algorithm.
void declareProperty(std::unique_ptr< Kernel::Property > p, const std::string &doc="") override
Add a property to the list of managed properties.
std::string getPropertyValue(const std::string &name) const override
Get the value of a property as a string.
TypedValue getProperty(const std::string &name) const override
Get the value of a property.
void progress(double p, const std::string &msg="", double estimatedTime=0.0, int progressPrecision=0)
Sends ProgressNotification.
bool getCancel() const
Returns the cancellation state.
@ Load
allowed here which will be passed to the algorithm
Helper class for reporting progress from algorithms.
A property class for workspaces.
TriggerEvent processTrigger(const uint64_t &data, const LoadDNSEvent::BufferHeader &bufferHeader)
std::vector< uint8_t > parse_Header(FileByteStream &file)
void parse_BlockList(VectorByteStream &file, EventAccumulator &eventAccumulator)
void populate_EventWorkspace(Mantid::DataObjects::EventWorkspace_sptr &eventWS, EventAccumulator &finalEventAccumulator)
void parse_andAddEvent(VectorByteStream &file, const BufferHeader &bufferHeader, EventAccumulator &eventAccumulator)
NeutronEvent processNeutron(const uint64_t &data, const LoadDNSEvent::BufferHeader &bufferHeader)
void exec() override
Run the algorithm.
bool m_discardPreChopperEvents
EventAccumulator parse_File(FileByteStream &file, const std::string &fileName)
void parse_BlockSeparator(VectorByteStream &file)
BufferHeader parse_DataBufferHeader(VectorByteStream &file)
void parse_EndSignature(FileByteStream &file)
void parse_DataBuffer(VectorByteStream &file, EventAccumulator &eventAccumulator)
std::vector< std::vector< uint8_t > > split_File(FileByteStream &file, const unsigned maxChunckCount)
uint32_t m_detectorPixelCount
void init() override
Virtual method - must be overridden by concrete algorithm.
void parse_Block(VectorByteStream &file, EventAccumulator &eventAccumulator)
uint32_t m_chopperChannel
BoundedValidator is a validator that requires the values to be between upper or lower bounds,...
Records the filename and the description of failure.
Defines a wrapper around an open file.
IPropertyManager * setProperty(const std::string &name, const T &value)
Templated method to set the value of a PropertyWithValue.
void debug(const std::string &msg)
Logs at debug level.
void error(const std::string &msg)
Logs at error level.
void warning(const std::string &msg)
Logs at warning level.
static T & Instance()
Return a reference to the Singleton instance, creating it if it does not already exist Creation is do...
VectorByteStream & read(T &result)
VectorByteStream & skip()
VectorByteStream & readRaw(T &result, const std::size_t &bytecount)
Kernel::Logger g_log("ExperimentInfo")
static logger object
bool startsWith(const string &str, const string &prefix)
Returns true if str starts with prefix.
const unsigned int PIXEL_PER_TUBE
const unsigned int MAX_BUFFER_BYTES_SIZE
std::shared_ptr< EventWorkspace > EventWorkspace_sptr
shared pointer to the EventWorkspace class
std::unique_ptr< T > create(const P &parent, const IndexArg &indexArg, const HistArg &histArg)
This is the create() method that all the other create() methods call.
std::enable_if< std::is_pointer< Arg >::value, bool >::type threadSafe(Arg workspace)
Thread-safety check Checks the workspace to ensure it is suitable for multithreaded access.
std::vector< std::vector< CompactEvent > > neutronEvents
std::vector< CompactEvent > triggerEvents
@ Input
An input workspace.
@ Output
An output workspace.