RaptorEagleV/raptor_eagle_acqproc.cpp
Timur A. Fatkhullin 719e2ec7e7 ...
2024-12-10 22:52:50 +03:00

139 lines
5.1 KiB
C++

#include <fitsio.h>
#include <cmath>
#include "raptor_eagle_ccd.h"
/*******************************************************************************/
/* ======= RaptorEagleCCD::AcquisitionProcess CLASS IMPLEMENTATION ======= */
/*******************************************************************************/
RaptorEagleCCD::AcquisitionProcess::AcquisitionProcess(RaptorEagleCCD* manager) : _manager(manager)
{
std::stringstream st;
st << std::this_thread::get_id();
_manager->logDebug("Create acquisition process (thread id: {})", st.str());
}
RaptorEagleCCD::AcquisitionProcess::~AcquisitionProcess()
{
std::stringstream st;
st << std::this_thread::get_id();
_manager->logDebug("Delete acquisition process (thread id: {})", st.str());
}
void RaptorEagleCCD::AcquisitionProcess::start(const std::shared_ptr<acq_params_t>& params)
{
// _acqParams = std::move(params);
_acqParams = params;
_acqParams->abortTime = std::chrono::utc_clock::time_point(); // to ensure the time point is in past
_snapAndCopyFuture = std::async(std::launch::async, [self = shared_from_this(), this]() {
std::chrono::milliseconds timeout =
CAMERA_CAPTURE_TIMEOUT_ADD_CONSTANT +
std::chrono::milliseconds(static_cast<std::chrono::milliseconds::rep>(_acqParams->expTime * 1000));
static char color_space[] = "Grey";
std::stringstream st;
st << std::this_thread::get_id();
_manager->logDebug("Arm grabber and wait for acquisition starting trigger (thread id: {}) ...", st.str());
_manager->xclibApiCall(pxd_doSnap(_manager->_cameraUnitmap, 1, timeout.count()),
std::format("pxd_doSnap({},1,{})", _manager->_cameraUnitmap, timeout.count()));
_manager->logDebug("Capture is finished (thread id: {})!", st.str());
if ((_acqParams->abortTime > _acqParams->startTime) &&
!_acqParams->saveInAbort) { // abort acquisition was occured! hust exit
_manager->logInfo("It seems the acquisition was aborted! Do not save acquired image!");
return;
}
_manager->logDebug("Copy image from grabber to buffer (thread id: {}) ...", st.str());
size_t npix = _acqParams->roiWidth * _acqParams->roiHeight;
_imageBufferRows = static_cast<size_t>(std::ceil(npix / _manager->_dimCCD[0]));
size_t sz = _imageBufferRows * npix;
if (_imageBufferSize < sz) {
_imageBufferSize = sz;
_imageBuffer.reset(new ushort[sz]); // may thow std::bad_alloc here!
}
auto log_str = std::format("pxd_readushort({}, 1, 0, 0, -1, {}, {}, {}, \"{}\")", _manager->_cameraUnitmap,
_imageBufferRows, (void*)_imageBuffer.get(), _imageBufferSize, color_space);
_manager->xclibApiCall(pxd_readushort(_manager->_cameraUnitmap, 1, 0, 0, -1, _imageBufferRows,
_imageBuffer.get(), _imageBufferSize, (char*)color_space),
log_str);
isAcqInProgress = false;
// save to FITS file
_manager->logInfo("Try to save FITS file with name '{}'", _acqParams->filename);
fitsfile* fitsFilePtr;
int status = 0;
int naxis = 2;
long naxes[naxis];
naxes[0] = _acqParams->roiWidth;
naxes[1] = _acqParams->roiHeight;
char err_str[100];
fits_clear_errmsg();
fits_create_file(&fitsFilePtr, _acqParams->filename.c_str(), &status);
// keywords from user template file
if (_acqParams->templateFilename.size() && !status) {
_manager->logDebug("Copy keywords from '{}' template file", _acqParams->templateFilename);
fits_write_key_template(fitsFilePtr, _acqParams->templateFilename.c_str(), &status);
if (status) { // ignore possible errors
fits_get_errstatus(status, err_str);
_manager->logWarn(
"An error occured while copy keywords from the template file '{}' (err = {}, msg = {})! Ignore!",
_acqParams->templateFilename, status, err_str);
status = 0;
}
}
// the keywords
fits_update_key_str(fitsFilePtr, "ORIGIN", "SAO RAS", NULL, &status);
fits_update_key_str(fitsFilePtr, "CREATOR", "RaptorEagleV control software", NULL, &status);
fits_close_file(fitsFilePtr, &status);
fits_get_errstatus(status, err_str);
_manager->logInfo("FITS file '{}' is saved", _acqParams->filename);
});
}
void RaptorEagleCCD::AcquisitionProcess::stop(bool save)
{
if (isAcqInProgress) {
_manager->logInfo("Abort current acquisition process!");
auto bytes = _manager->readRegisters({0xD4}); // trigger mode register
bytes[0] |= CL_ABORT_CURRENT_EXP; // set abort acquisition bit
_manager->writeRegisters({0xD4}, bytes);
_acqParams->abortTime = std::chrono::utc_clock::now();
_acqParams->saveInAbort = save;
} else {
_manager->logWarn("There was no active acquisition process! Ignore!");
}
}