// Copyright (2019-2022) Paul Scherrer Institute // SPDX-License-Identifier: GPL-3.0-or-later #include #include "AcquisitionOnlineCounters.h" #include "../../common/JFJochException.h" AcquisitionOnlineCounters::AcquisitionOnlineCounters() : head(max_modules, 0), slowest_head(0) {} void AcquisitionOnlineCounters::Reset(const DiffractionExperiment &experiment, uint16_t data_stream) { std::unique_lock ul(m); acquisition_finished = false; slowest_head = 0; if ((experiment.GetDetectorMode() == DetectorMode::PedestalG0) || (experiment.GetDetectorMode() == DetectorMode::PedestalG1) || (experiment.GetDetectorMode() == DetectorMode::PedestalG2)) expected_frames = experiment.GetFrameNum(); else expected_frames = experiment.GetImageNum() * experiment.GetSummation(); nmodules = experiment.GetModulesNum(data_stream); if (nmodules > max_modules) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "Acquisition counter cannot support that many modules"); for (int i = 0; i < max_modules; i++) head[i] = 0; handle_for_frame = std::vector((expected_frames+1) * nmodules, HandleNotFound); full_module_collected = std::vector(expected_frames * nmodules); bunch_id = std::vector(expected_frames * nmodules); jf_info = std::vector(expected_frames * nmodules); timestamp = std::vector(expected_frames * nmodules); exptime = std::vector(expected_frames * nmodules); } void AcquisitionOnlineCounters::UpdateCounters(const Completion *c) { std::unique_lock ul(m); if (c->module >= nmodules) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "UpdateCounters wrong module number: " + std::to_string(c->module) + " for frame " + std::to_string(c->frame_number)); if (c->frame_number >= expected_frames) throw JFJochException(JFJochExceptionCategory::InputParameterInvalid, "UpdateCounters frame number is out of bounds"); else { if (head.at(c->module) < c->frame_number) head.at(c->module) = c->frame_number; if (c->frame_number > slowest_head) { slowest_head = head[0]; for (int i = 1; i < nmodules; i++) if (head[i] < slowest_head) slowest_head = head[i]; } full_module_collected.at(c->frame_number * nmodules + c->module) = (c->packet_count == expected_packets_per_module); handle_for_frame.at(c->frame_number * nmodules + c->module) = c->handle; bunch_id.at(c->frame_number * nmodules + c->module) = c->bunchid; jf_info.at(c->frame_number * nmodules + c->module) = c->debug; timestamp.at(c->frame_number * nmodules + c->module) = c->timestamp; exptime.at(c->frame_number * nmodules + c->module) = c->exptime; } data_updated.notify_all(); } void AcquisitionOnlineCounters::SetAcquisitionFinished() { std::unique_lock ul(m); acquisition_finished = true; data_updated.notify_all(); } uint64_t AcquisitionOnlineCounters::GetBufferHandle(size_t frame, uint16_t module_number) const { if (frame >= expected_frames) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "GetBufferHandle Wrong frame number: " + std::to_string(frame)); if (module_number >= nmodules) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "GetBufferHandle Wrong module number: " + std::to_string(module_number) + " for frame " + std::to_string(frame)); return handle_for_frame.at(frame * nmodules + module_number); } uint64_t AcquisitionOnlineCounters::GetBufferHandleAndClear(size_t frame, uint16_t module_number) { std::unique_lock ul(m); if (frame >= expected_frames) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "GetBufferHandleAndClear Wrong frame number: " + std::to_string(frame)); if (module_number >= nmodules) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "GetBufferHandleAndClear Wrong module number: " + std::to_string(module_number) + " for frame " + std::to_string(frame)); uint64_t ret_val = handle_for_frame.at(frame * nmodules + module_number); handle_for_frame.at(frame * nmodules + module_number) = HandleNotFound; return ret_val; } uint64_t AcquisitionOnlineCounters::GetHead(uint16_t module_number) const { if (module_number >= max_modules) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "GetHead Wrong module number: " + std::to_string(module_number)); return head[module_number]; } uint64_t AcquisitionOnlineCounters::GetSlowestHead() const { return slowest_head; } void AcquisitionOnlineCounters::WaitForFrame(size_t curr_frame, uint16_t module_number) const { uint64_t slowest_head_tmp = (module_number == UINT16_MAX) ? GetSlowestHead() : GetHead(module_number); while (!acquisition_finished && (slowest_head_tmp < curr_frame)) { std::this_thread::sleep_for(std::chrono::microseconds(100)); slowest_head_tmp = (module_number == UINT16_MAX) ? GetSlowestHead() : GetHead(module_number); } } int64_t AcquisitionOnlineCounters::CalculateDelay(size_t curr_frame, uint16_t module_number) const { uint64_t slowest_head_tmp; if (module_number == UINT16_MAX) slowest_head_tmp = GetSlowestHead(); else slowest_head_tmp = GetHead(module_number); return slowest_head_tmp - curr_frame; } bool AcquisitionOnlineCounters::IsAcquisitionFinished() const { return acquisition_finished; } bool AcquisitionOnlineCounters::IsFullModuleCollected(size_t frame, uint16_t module_number) const { if (frame >= expected_frames) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "IsFullModuleCollected Wrong frame number: " + std::to_string(frame)); if (module_number >= nmodules) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "IsFullModuleCollected Wrong module number: " + std::to_string(module_number) + " for frame " + std::to_string(frame)); return full_module_collected[frame * nmodules + module_number]; } uint64_t AcquisitionOnlineCounters::GetBunchID(size_t frame, uint16_t module_number) const { if (frame >= expected_frames) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "GetBunchID Wrong frame number: " + std::to_string(frame)); if (module_number >= nmodules) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "GetBunchID Wrong module number: " + std::to_string(module_number) + " for frame " + std::to_string(frame)); return bunch_id[frame * nmodules + module_number]; } uint32_t AcquisitionOnlineCounters::GetExptime(size_t frame, uint16_t module_number) const { if (frame >= expected_frames) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "GetExptime Wrong frame number: " + std::to_string(frame)); if (module_number >= nmodules) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "GetExptime Wrong module number: " + std::to_string(module_number) + " for frame " + std::to_string(frame)); return exptime[frame * nmodules + module_number]; } uint32_t AcquisitionOnlineCounters::GetJFInfo(size_t frame, uint16_t module_number) const { if (frame >= expected_frames) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "GetJFInfo Wrong frame number: " + std::to_string(frame)); if (module_number >= nmodules) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "GetJFInfo Wrong module number: " + std::to_string(module_number) + " for frame " + std::to_string(frame)); return jf_info[frame * nmodules + module_number]; } uint64_t AcquisitionOnlineCounters::GetTimestamp(size_t frame, uint16_t module_number) const { if (frame >= expected_frames) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "GetTimestamp Wrong frame number: " + std::to_string(frame)); if (module_number >= nmodules) throw JFJochException(JFJochExceptionCategory::ArrayOutOfBounds, "GetTimestamp Wrong module number: " + std::to_string(module_number) + " for frame " + std::to_string(frame)); return timestamp[frame * nmodules + module_number]; }