satdump/plugins/proba_support/proba/instruments/swap/swap_reader.cpp

125 lines
6.6 KiB
C++
Raw Permalink Normal View History

2021-02-15 21:20:05 +01:00
#include "swap_reader.h"
#include <fstream>
#include <iostream>
#include <map>
#include <filesystem>
#include "logger.h"
#include "image/image.h"
#include "image/jpeg_utils.h"
#include "image/io.h"
#include "image/processing.h"
#include "core/resources.h"
2021-07-03 01:26:24 +02:00
#include "common/ccsds/ccsds_time.h"
2021-02-15 21:20:05 +01:00
2024-05-09 01:16:08 +02:00
#define WRITE_IMAGE_LOCAL(img, path) \
{ \
std::string newPath = path; \
2024-05-11 14:46:56 -04:00
image::append_ext(&newPath); \
2024-05-09 01:16:08 +02:00
image::save_img(img, std::string(newPath).c_str()); \
all_images.push_back(newPath); \
}
2021-02-15 21:20:05 +01:00
namespace proba
{
2021-04-17 22:33:48 +02:00
2021-02-15 21:20:05 +01:00
namespace swap
{
SWAPReader::SWAPReader(std::string &outputfolder)
{
count = 0;
output_folder = outputfolder;
}
2021-07-02 01:03:35 +02:00
void SWAPReader::work(ccsds::CCSDSPacket &packet)
2021-02-15 21:20:05 +01:00
{
if (packet.payload.size() < 65530)
return;
2021-10-16 19:33:15 +02:00
time_t timestamp = ccsds::parseCCSDSTime(packet, 18630) + 4 * 3600;
2021-02-15 21:20:05 +01:00
// Start new image
2021-07-03 01:26:24 +02:00
if (currentOuts.find(timestamp) == currentOuts.end())
2021-02-15 21:20:05 +01:00
{
2021-07-03 01:26:24 +02:00
std::tm *timeReadable = gmtime(&timestamp);
std::string timestamp_str = (timeReadable->tm_mday > 9 ? std::to_string(timeReadable->tm_mday) : "0" + std::to_string(timeReadable->tm_mday)) + "/" +
(timeReadable->tm_mon + 1 > 9 ? std::to_string(timeReadable->tm_mon + 1) : "0" + std::to_string(timeReadable->tm_mon + 1)) + "/" +
std::to_string(timeReadable->tm_year + 1900) + " " +
(timeReadable->tm_hour > 9 ? std::to_string(timeReadable->tm_hour) : "0" + std::to_string(timeReadable->tm_hour)) + ":" +
(timeReadable->tm_min > 9 ? std::to_string(timeReadable->tm_min) : "0" + std::to_string(timeReadable->tm_min)) + ":" +
(timeReadable->tm_sec > 9 ? std::to_string(timeReadable->tm_sec) : "0" + std::to_string(timeReadable->tm_sec));
logger->info("Found new SWAP image! Saving as SWAP-" + std::to_string(count) + ".jpeg. Timestamp " + timestamp_str);
std::string utc_filename = "SWAP_" + // Instrument name
std::to_string(timeReadable->tm_year + 1900) + // Year yyyy
(timeReadable->tm_mon + 1 > 9 ? std::to_string(timeReadable->tm_mon + 1) : "0" + std::to_string(timeReadable->tm_mon + 1)) + // Month MM
(timeReadable->tm_mday > 9 ? std::to_string(timeReadable->tm_mday) : "0" + std::to_string(timeReadable->tm_mday)) + "T" + // Day dd
(timeReadable->tm_hour > 9 ? std::to_string(timeReadable->tm_hour) : "0" + std::to_string(timeReadable->tm_hour)) + // Hour HH
(timeReadable->tm_min > 9 ? std::to_string(timeReadable->tm_min) : "0" + std::to_string(timeReadable->tm_min)) + // Minutes mm
(timeReadable->tm_sec > 9 ? std::to_string(timeReadable->tm_sec) : "0" + std::to_string(timeReadable->tm_sec)) + "Z"; // Seconds ss
currentOuts.insert(std::pair<time_t, std::pair<int, std::pair<std::string, std::vector<uint8_t>>>>(timestamp, std::pair<int, std::pair<std::string, std::vector<uint8_t>>>(0, std::pair<std::string, std::vector<uint8_t>>(utc_filename, std::vector<uint8_t>()))));
2021-02-15 21:20:05 +01:00
count++;
}
2021-07-03 01:26:24 +02:00
int &currentFrameCount = currentOuts[timestamp].first;
std::vector<uint8_t> &currentOutVec = currentOuts[timestamp].second.second;
2024-07-03 16:10:30 -04:00
currentOutVec.insert(currentOutVec.end(), &packet.payload[currentFrameCount == 0 ? 14 + 78 : 14], &packet.payload.back());
2021-02-15 21:20:05 +01:00
currentFrameCount++;
}
void SWAPReader::save()
{
2021-05-28 18:38:54 +02:00
// This is temporary code until a resource system is implemented everywhere.
2024-05-09 01:16:08 +02:00
image::Image adc_mask, ffc_mask;
2021-05-28 18:38:54 +02:00
bool masks_found = false;
2021-05-28 18:57:15 +02:00
if (resources::resourceExists("proba/swap/adc_mask.png") && resources::resourceExists("proba/swap/ffc_mask.png"))
2021-05-28 18:38:54 +02:00
{
2024-05-09 01:16:08 +02:00
image::load_png(adc_mask, resources::getResourcePath("proba/swap/adc_mask.png"));
image::load_png(ffc_mask, resources::getResourcePath("proba/swap/ffc_mask.png"));
2021-05-28 18:38:54 +02:00
masks_found = true;
}
else
{
logger->error("Necessary resources were not found, no correction will be applied!");
}
2021-07-03 01:26:24 +02:00
for (std::pair<const time_t, std::pair<int, std::pair<std::string, std::vector<uint8_t>>>> &currentPair : currentOuts)
2021-02-15 21:20:05 +01:00
{
2023-08-05 21:15:31 -04:00
std::string extension = "";
2021-02-15 21:20:05 +01:00
std::string filename = currentPair.second.second.first;
2021-04-17 22:33:48 +02:00
std::vector<uint8_t> &currentOutVec = currentPair.second.second.second;
2021-02-15 21:20:05 +01:00
logger->info("Decompressing " + filename + "...");
2024-05-09 01:16:08 +02:00
image::Image img = image::decompress_jpeg(currentOutVec.data(), currentOutVec.size());
2021-04-17 22:33:48 +02:00
if (img.size() == 0)
2021-02-15 21:20:05 +01:00
{
2021-04-17 22:33:48 +02:00
logger->info("Error! Skipping...");
2021-02-15 21:20:05 +01:00
continue;
}
2021-05-28 18:38:54 +02:00
if (masks_found)
{
2022-05-12 18:19:01 +02:00
for (size_t i = 0; i < img.height() * img.width(); i++)
2021-05-28 18:38:54 +02:00
{
// This was checked against official Proba-2 data
2024-07-03 16:10:30 -04:00
img.setf(i, std::max<float>(0, img.getf(i) - adc_mask.getf(i) * 2.8)); // ADC Bias correction
img.setf(i, std::max<float>(0, img.getf(i) - ffc_mask.getf(i) * 2.8)); // Flat field correction
2021-05-28 18:38:54 +02:00
}
}
// Despeckle
2024-05-09 12:34:06 +02:00
image::simple_despeckle(img, 20);
2024-05-11 14:46:56 -04:00
image::append_ext(&extension);
2023-08-05 21:15:31 -04:00
if (std::filesystem::exists(output_folder + "/" + filename + extension))
2023-05-12 08:19:09 +02:00
{
int i = 0;
2023-08-05 21:15:31 -04:00
while (std::filesystem::exists(output_folder + "/" + filename + "-" + std::to_string(i) + extension))
2023-05-12 08:19:09 +02:00
i++;
filename = filename + "-" + std::to_string(i);
}
2023-08-03 13:04:50 -04:00
WRITE_IMAGE_LOCAL(img, output_folder + "/" + filename);
2021-02-15 21:20:05 +01:00
}
}
} // namespace swap
} // namespace proba