#include "module_proba_instruments.h" #include "common/ccsds/ccsds_tm/demuxer.h" #include "common/ccsds/ccsds_tm/vcdu.h" #include "core/exception.h" #include "image/io.h" #include "imgui/imgui.h" #include "instruments/vegetation/vegx_reader.h" #include "logger.h" #include "products/dataset.h" #include "products/image/channel_transform.h" #include "products/image_product.h" #include #include #include namespace proba { namespace instruments { PROBAInstrumentsDecoderModule::PROBAInstrumentsDecoderModule(std::string input_file, std::string output_file_hint, nlohmann::json parameters) : satdump::pipeline::base::FileStreamToFileStreamModule(input_file, output_file_hint, parameters) { if (parameters["satellite"] == "proba1") d_satellite = PROBA_1; else if (parameters["satellite"] == "proba2") d_satellite = PROBA_2; else if (parameters["satellite"] == "probaV") d_satellite = PROBA_V; else if (parameters["satellite"] == "proba3") d_satellite = PROBA_3; else throw satdump_exception("Proba Instruments Decoder : Proba satellite \"" + parameters["satellite"].get() + "\" is not valid!"); fsfsm_enable_output = false; } void PROBAInstrumentsDecoderModule::process() { uint8_t cadu[1279]; // Demuxers ccsds::ccsds_tm::Demuxer demuxer_vcid1(1103, false); ccsds::ccsds_tm::Demuxer demuxer_vcid2(1103, false); ccsds::ccsds_tm::Demuxer demuxer_vcid3(1103, false); ccsds::ccsds_tm::Demuxer demuxer_vcid4(1103, false); // std::ofstream output("file.ccsds"); // Products dataset satdump::products::DataSet dataset; if (d_satellite == PROBA_1) dataset.satellite_name = "PROBA-1"; else if (d_satellite == PROBA_2) dataset.satellite_name = "PROBA-2"; else if (d_satellite == PROBA_V) dataset.satellite_name = "PROBA-V"; else if (d_satellite == PROBA_3) dataset.satellite_name = "PROBA-3"; dataset.timestamp = time(0); // avg_overflowless(avhrr_reader.timestamps); // Init readers if (d_satellite == PROBA_1) { std::string chris_directory = d_output_file_hint.substr(0, d_output_file_hint.rfind('/')) + "/CHRIS"; std::string hrc_directory = d_output_file_hint.substr(0, d_output_file_hint.rfind('/')) + "/HRC"; if (!std::filesystem::exists(chris_directory)) std::filesystem::create_directory(chris_directory); if (!std::filesystem::exists(hrc_directory)) std::filesystem::create_directory(hrc_directory); chris_reader = std::make_unique(chris_directory, dataset); hrc_reader = std::make_unique(hrc_directory); } else if (d_satellite == PROBA_2) { std::string swap_directory = d_output_file_hint.substr(0, d_output_file_hint.rfind('/')) + "/SWAP"; if (!std::filesystem::exists(swap_directory)) std::filesystem::create_directory(swap_directory); swap_reader = std::make_unique(swap_directory); } else if (d_satellite == PROBA_V) { std::string vegs_directory = d_output_file_hint.substr(0, d_output_file_hint.rfind('/')) + "/Vegetation-S"; if (!std::filesystem::exists(vegs_directory)) std::filesystem::create_directory(vegs_directory); std::string vegx_directory = d_output_file_hint.substr(0, d_output_file_hint.rfind('/')) + "/Vegetation-X"; if (!std::filesystem::exists(vegx_directory)) std::filesystem::create_directory(vegx_directory); for (int i = 0; i < 3; i++) { vegs_readers[i][0] = std::make_unique(7818, 5200); vegs_readers[i][1] = std::make_unique(7818, 5200); vegs_readers[i][2] = std::make_unique(7818, 5200); vegs_readers[i][3] = std::make_unique(1554, 1024); vegs_readers[i][4] = std::make_unique(1554, 1024); vegs_readers[i][5] = std::make_unique(1554, 1024); for (int y = 0; y < 6; y++) vegs_status[i][y] = DECODING; } gps_ascii_reader = std::make_unique(d_output_file_hint.substr(0, d_output_file_hint.rfind('/')) + "/gps_logs.txt"); } int i = 0; // bool is_pv_x = true; vegetation::VegetationX vegx_reader1(352, 128, 15); vegetation::VegetationX vegx_reader2(352, 128, 3); vegetation::VegetationX vegx_reader3(352, 128, 3); vegetation::VegetationX vegx_reader4(352, 128, 3); vegetation::VegetationX vegx_reader5(352, 128, 15); vegetation::VegetationX vegx_reader6(352, 128, 15); vegetation::VegetationX vegx_reader7(352, 128, 15); vegetation::VegetationX vegx_reader8(352, 128, 15); vegetation::VegetationX vegx_reader9(352, 128, 3); vegetation::VegetationX vegx_reader10(352, 128, 3); vegetation::VegetationX vegx_reader11(352, 128, 3); vegetation::VegetationX vegx_reader12(352, 128, 15); vegetation::VegetationX vegx_reader13(352, 128, 15); vegetation::VegetationX vegx_reader14(352, 128, 15); vegetation::VegetationX vegx_reader15(352, 128, 15); vegetation::VegetationX vegx_reader16(352, 128, 3); vegetation::VegetationX vegx_reader17(352, 128, 3); vegetation::VegetationX vegx_reader18(352, 128, 3); while (should_run()) { // Read buffer read_data((uint8_t *)&cadu, 1279); // Parse this transport frame ccsds::ccsds_tm::VCDU vcdu = ccsds::ccsds_tm::parseVCDU(cadu); // logger->info(pkt.header.apid); // logger->info(vcdu.vcid); // printf("VCID %d\n", vcdu.vcid); if (vcdu.vcid == 1) // Replay VCID { std::vector ccsdsFrames = demuxer_vcid1.work(cadu); for (ccsds::CCSDSPacket &pkt : ccsdsFrames) { if (d_satellite == PROBA_1) { if (pkt.header.apid == 0) { int mode_marker = pkt.payload[9] & 0x03; // pkt.payload.resize(16000); // output.write((char *)pkt.payload.data(), 16000); if (mode_marker == 1 || mode_marker == 2) hrc_reader->work(pkt); else chris_reader->work(pkt); } } else if (d_satellite == PROBA_V) { if (pkt.header.apid == 18) // GPS ASCII Logs gps_ascii_reader->work(pkt); } } } else if (vcdu.vcid == 2) // IDK VCID { #if 0 std::vector ccsdsFrames = demuxer_vcid2.work(cadu); for (ccsds::CCSDSPacket &pkt : ccsdsFrames) { if (d_satellite == PROBA_V) { printf("APID %d\n", pkt.header.apid); if (pkt.header.apid == 7) { pkt.payload.resize(16000); output.write((char *)pkt.payload.data(), 16000); } } // if (pkt.header.apid != 2047) // logger->info("%d, %d", pkt.header.apid, pkt.payload.size()); // if (pkt.header.apid == 103) // { // pkt.payload.resize(16000); // output.write((char *)pkt.payload.data(), 16000); // } // if (pkt.header.apid != 2047) // logger->info("%d, %d", pkt.header.apid, pkt.payload.size()); // if (pkt.header.apid == 18) //{ // pkt.payload.resize(16000); // output.write((char *)pkt.payload.data(), 16000); // } } #endif } else if (vcdu.vcid == 3) // SWAP VCID { std::vector ccsdsFrames = demuxer_vcid3.work(cadu); for (ccsds::CCSDSPacket &pkt : ccsdsFrames) { if (d_satellite == PROBA_2) if (pkt.header.apid == 20) swap_reader->work(pkt); } } else if (vcdu.vcid == 4) // Idk VCID { std::vector ccsdsFrames = demuxer_vcid4.work(cadu); for (ccsds::CCSDSPacket &pkt : ccsdsFrames) { if (d_satellite == PROBA_V) { // if (!is_pv_x) { // Vegs-1 if (pkt.header.apid == 289) vegs_readers[1][0]->work(pkt); else if (pkt.header.apid == 273) vegs_readers[1][1]->work(pkt); else if (pkt.header.apid == 321) vegs_readers[1][2]->work(pkt); else if (pkt.header.apid == 281) vegs_readers[1][3]->work(pkt); else if (pkt.header.apid == 297) vegs_readers[1][4]->work(pkt); else if (pkt.header.apid == 329) vegs_readers[1][5]->work(pkt); // Vegs-2 else if (pkt.header.apid == 290) vegs_readers[0][0]->work(pkt); else if (pkt.header.apid == 274) vegs_readers[0][1]->work(pkt); else if (pkt.header.apid == 322) vegs_readers[0][2]->work(pkt); else if (pkt.header.apid == 282) vegs_readers[0][3]->work(pkt); else if (pkt.header.apid == 298) vegs_readers[0][4]->work(pkt); else if (pkt.header.apid == 330) vegs_readers[0][5]->work(pkt); // Vegs-3 else if (pkt.header.apid == 292) vegs_readers[2][0]->work(pkt); else if (pkt.header.apid == 276) vegs_readers[2][1]->work(pkt); else if (pkt.header.apid == 324) vegs_readers[2][2]->work(pkt); else if (pkt.header.apid == 284) vegs_readers[2][3]->work(pkt); else if (pkt.header.apid == 300) vegs_readers[2][4]->work(pkt); else if (pkt.header.apid == 332) vegs_readers[2][5]->work(pkt); else logger->critical(pkt.header.apid); } // else { if (pkt.header.apid == 324) vegx_reader1.work(pkt); else if (pkt.header.apid == 330) vegx_reader2.work(pkt); else if (pkt.header.apid == 298) vegx_reader3.work(pkt); else if (pkt.header.apid == 329) vegx_reader4.work(pkt); else if (pkt.header.apid == 289) vegx_reader5.work(pkt); else if (pkt.header.apid == 273) vegx_reader6.work(pkt); else if (pkt.header.apid == 321) vegx_reader7.work(pkt); else if (pkt.header.apid == 290) vegx_reader8.work(pkt); else if (pkt.header.apid == 282) vegx_reader9.work(pkt); else if (pkt.header.apid == 297) vegx_reader10.work(pkt); else if (pkt.header.apid == 281) vegx_reader11.work(pkt); else if (pkt.header.apid == 274) vegx_reader12.work(pkt); else if (pkt.header.apid == 322) vegx_reader13.work(pkt); else if (pkt.header.apid == 292) vegx_reader14.work(pkt); else if (pkt.header.apid == 276) vegx_reader15.work(pkt); else if (pkt.header.apid == 332) vegx_reader16.work(pkt); else if (pkt.header.apid == 300) vegx_reader17.work(pkt); else if (pkt.header.apid == 284) vegx_reader18.work(pkt); else logger->info("%d, %d", pkt.header.apid, pkt.payload.size()); } } else if (d_satellite == PROBA_3) {} } } } cleanup(); // CHRIS if (d_satellite == PROBA_1) { chris_status = SAVING; logger->info("----------- CHRIS"); logger->info("Images : %d", chris_reader->cnt()); chris_reader->save(); chris_status = DONE; } // HRC if (d_satellite == PROBA_1) { hrc_status = SAVING; logger->info("----------- HRC"); logger->info("Images : %d", hrc_reader->getCount()); hrc_reader->save(); hrc_status = DONE; } // SWAP if (d_satellite == PROBA_2) { swap_status = SAVING; logger->info("----------- SWAP"); logger->info("Images : %d", swap_reader->count); swap_reader->save(); swap_status = DONE; } // VegS if (d_satellite == PROBA_V) { for (int i = 0; i < 3; i++) { for (int y = 0; y < 6; y++) vegs_status[i][y] = SAVING; // if (!is_pv_x) { std::string vegs_directory = d_output_file_hint.substr(0, d_output_file_hint.rfind('/')) + "/Vegetation-S"; logger->info("----------- Vegetation %d", i + 1); logger->info("Lines (1) : %d", vegs_readers[i][0]->lines); logger->info("Lines (2) : %d", vegs_readers[i][1]->lines); logger->info("Lines (3) : %d", vegs_readers[i][2]->lines); logger->info("Lines (4) : %d", vegs_readers[i][3]->lines); logger->info("Lines (5) : %d", vegs_readers[i][4]->lines); logger->info("Lines (6) : %d", vegs_readers[i][5]->lines); auto img = vegs_readers[i][0]->getImg(); image::save_img(img, vegs_directory + "/Vegetation" + std::to_string(i + 1) + "_1"); img = vegs_readers[i][1]->getImg(); image::save_img(img, vegs_directory + "/Vegetation" + std::to_string(i + 1) + "_2"); auto img3 = vegs_readers[i][2]->getImg(); img3.mirror(true, false); image::save_img(img3, vegs_directory + "/Vegetation" + std::to_string(i + 1) + "_3"); img3.clear(); img = vegs_readers[i][3]->getImg(); image::save_img(img, vegs_directory + "/Vegetation" + std::to_string(i + 1) + "_4"); img = vegs_readers[i][4]->getImg(); image::save_img(img, vegs_directory + "/Vegetation" + std::to_string(i + 1) + "_5"); img = vegs_readers[i][5]->getImg(); image::save_img(img, vegs_directory + "/Vegetation" + std::to_string(i + 1) + "_6"); } // else { std::string vegs_directory = d_output_file_hint.substr(0, d_output_file_hint.rfind('/')) + "/Vegetation-X"; for (auto &tocorr_inst : (std::vector>){ {&vegx_reader1, &vegx_reader14, &vegx_reader15}, // {&vegx_reader8, &vegx_reader12, &vegx_reader13}, // {&vegx_reader5, &vegx_reader6, &vegx_reader7}, // // {&vegx_reader16, &vegx_reader17, &vegx_reader18}, // {&vegx_reader2, &vegx_reader3, &vegx_reader9}, // {&vegx_reader4, &vegx_reader10, &vegx_reader11}, // }) { std::vector to_corr; for (auto &veg : tocorr_inst) for (auto &seg : veg->img_segments) if (std::find(to_corr.begin(), to_corr.end(), seg.first) == to_corr.end()) to_corr.push_back(seg.first); std::sort(to_corr.begin(), to_corr.end()); for (auto &veg : tocorr_inst) { auto vegcpy = veg->img_segments; veg->img_segments.erase(veg->img_segments.begin(), veg->img_segments.end()); for (auto &line : to_corr) { if (vegcpy.count(line)) veg->img_segments.insert_or_assign(line, vegcpy.find(line)->second); else veg->img_segments.insert_or_assign(line, std::array()); } } } { std::string directory = d_output_file_hint.substr(0, d_output_file_hint.rfind('/')) + "/Vegetation-X/Vegetation_1"; if (!std::filesystem::exists(directory)) std::filesystem::create_directories(directory); satdump::products::ImageProduct ocm_products; ocm_products.instrument_name = "probav_vegetation_hd"; ocm_products.images.push_back({0, "Vegetation-1", "1", vegx_reader1.getImg(), 12}); auto img = vegx_reader14.getImg(); img.mirror(1, 0); ocm_products.images.push_back({1, "Vegetation-2", "2", img, 12, satdump::ChannelTransform().init_affine_slantx(0.996000, 1, -70.000000, -160.000000, 0, 0.022000)}); img = vegx_reader15.getImg(); img.mirror(1, 0); ocm_products.images.push_back({2, "Vegetation-3", "3", img, 12, satdump::ChannelTransform().init_affine(1, 1, -80.098282, -66.785806)}); ocm_products.save(directory); } { std::string directory = d_output_file_hint.substr(0, d_output_file_hint.rfind('/')) + "/Vegetation-X/Vegetation_2"; if (!std::filesystem::exists(directory)) std::filesystem::create_directories(directory); satdump::products::ImageProduct ocm_products; ocm_products.instrument_name = "probav_vegetation_hd"; ocm_products.images.push_back({0, "Vegetation-1", "1", vegx_reader13.getImg(), 12}); auto img = vegx_reader12.getImg(); img.mirror(1, 0); ocm_products.images.push_back({1, "Vegetation-2", "2", img, 12, satdump::ChannelTransform().init_affine(1, 1, -80.021092, -53.112902)}); img = vegx_reader8.getImg(); img.mirror(1, 0); ocm_products.images.push_back({2, "Vegetation-3", "3", img, 12, satdump::ChannelTransform().init_affine(1, 1, -81.243169, -159.856325)}); ocm_products.save(directory); } { std::string directory = d_output_file_hint.substr(0, d_output_file_hint.rfind('/')) + "/Vegetation-X/Vegetation_3"; if (!std::filesystem::exists(directory)) std::filesystem::create_directories(directory); satdump::products::ImageProduct ocm_products; ocm_products.instrument_name = "probav_vegetation_hd"; ocm_products.images.push_back({0, "Vegetation-1", "1", vegx_reader7.getImg(), 12}); auto img = vegx_reader6.getImg(); img.mirror(1, 0); ocm_products.images.push_back({1, "Vegetation-2", "2", img, 12, satdump::ChannelTransform().init_affine_slantx(0.999000, 1, -76.000000, -93.000000, 0, -0.007500)}); img = vegx_reader5.getImg(); img.mirror(1, 0); ocm_products.images.push_back({2, "Vegetation-3", "3", img, 12, satdump::ChannelTransform().init_affine_slantx(0.996500, 1, -69.000000, -276.000000, 0, -0.023500)}); ocm_products.save(directory); } logger->info("----------- Vegetation-X"); auto img = vegx_reader1.getImg(); image::save_img(img, vegs_directory + "/Vegetation_1.png"); img = vegx_reader2.getImg(); image::save_img(img, vegs_directory + "/Vegetation_2.png"); img = vegx_reader3.getImg(); image::save_img(img, vegs_directory + "/Vegetation_3.png"); img = vegx_reader4.getImg(); image::save_img(img, vegs_directory + "/Vegetation_4.png"); img = vegx_reader5.getImg(); image::save_img(img, vegs_directory + "/Vegetation_5.png"); img = vegx_reader6.getImg(); image::save_img(img, vegs_directory + "/Vegetation_6.png"); img = vegx_reader7.getImg(); image::save_img(img, vegs_directory + "/Vegetation_7.png"); img = vegx_reader8.getImg(); image::save_img(img, vegs_directory + "/Vegetation_8.png"); img = vegx_reader9.getImg(); image::save_img(img, vegs_directory + "/Vegetation_9.png"); img = vegx_reader10.getImg(); image::save_img(img, vegs_directory + "/Vegetation_10.png"); img = vegx_reader11.getImg(); image::save_img(img, vegs_directory + "/Vegetation_11.png"); img = vegx_reader12.getImg(); image::save_img(img, vegs_directory + "/Vegetation_12.png"); img = vegx_reader13.getImg(); image::save_img(img, vegs_directory + "/Vegetation_13.png"); img = vegx_reader14.getImg(); image::save_img(img, vegs_directory + "/Vegetation_14.png"); img = vegx_reader15.getImg(); image::save_img(img, vegs_directory + "/Vegetation_15.png"); img = vegx_reader16.getImg(); image::save_img(img, vegs_directory + "/Vegetation_16.png"); img = vegx_reader17.getImg(); image::save_img(img, vegs_directory + "/Vegetation_17.png"); img = vegx_reader18.getImg(); image::save_img(img, vegs_directory + "/Vegetation_18.png"); } for (int y = 0; y < 6; y++) vegs_status[i][y] = DONE; } } if (d_satellite == PROBA_1) dataset.save(d_output_file_hint.substr(0, d_output_file_hint.rfind('/'))); } void PROBAInstrumentsDecoderModule::drawUI(bool window) { ImGui::Begin("Proba Instruments Decoder", NULL, window ? 0 : NOWINDOW_FLAGS); if (ImGui::BeginTable("##probainstrumentstable", 3, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::Text("Instrument"); ImGui::TableSetColumnIndex(1); ImGui::Text("Images / Frames"); ImGui::TableSetColumnIndex(2); ImGui::Text("Status"); if (d_satellite == PROBA_1) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::Text("CHRIS"); ImGui::TableSetColumnIndex(1); ImGui::TextColored(style::theme.green, "%d", chris_reader->cnt()); ImGui::TableSetColumnIndex(2); drawStatus(chris_status); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::Text("HRC"); ImGui::TableSetColumnIndex(1); ImGui::TextColored(style::theme.green, "%d", hrc_reader->getCount()); ImGui::TableSetColumnIndex(2); drawStatus(hrc_status); } if (d_satellite == PROBA_2) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::Text("SWAP"); ImGui::TableSetColumnIndex(1); ImGui::TextColored(style::theme.green, "%d", swap_reader->count); ImGui::TableSetColumnIndex(2); drawStatus(swap_status); } if (d_satellite == PROBA_V) { for (int i = 0; i < 3; i++) { ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::Text("Vegetation %d Ch1", i + 1); ImGui::TableSetColumnIndex(1); ImGui::TextColored(style::theme.green, "%d", vegs_readers[i][0]->lines); ImGui::TableSetColumnIndex(2); drawStatus(vegs_status[i][0]); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::Text("Vegetation %d Ch2", i + 1); ImGui::TableSetColumnIndex(1); ImGui::TextColored(style::theme.green, "%d", vegs_readers[i][1]->lines); ImGui::TableSetColumnIndex(2); drawStatus(vegs_status[i][1]); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::Text("Vegetation %d Ch2", i + 1); ImGui::TableSetColumnIndex(1); ImGui::TextColored(style::theme.green, "%d", vegs_readers[i][2]->lines); ImGui::TableSetColumnIndex(2); drawStatus(vegs_status[i][2]); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::Text("Vegetation %d Ch4", i + 1); ImGui::TableSetColumnIndex(1); ImGui::TextColored(style::theme.green, "%d", vegs_readers[i][3]->lines); ImGui::TableSetColumnIndex(2); drawStatus(vegs_status[i][3]); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::Text("Vegetation %d Ch5", i + 1); ImGui::TableSetColumnIndex(1); ImGui::TextColored(style::theme.green, "%d", vegs_readers[i][4]->lines); ImGui::TableSetColumnIndex(2); drawStatus(vegs_status[i][4]); ImGui::TableNextRow(); ImGui::TableSetColumnIndex(0); ImGui::Text("Vegetation %d Ch6", i + 1); ImGui::TableSetColumnIndex(1); ImGui::TextColored(style::theme.green, "%d", vegs_readers[i][5]->lines); ImGui::TableSetColumnIndex(2); drawStatus(vegs_status[i][5]); } } ImGui::EndTable(); } drawProgressBar(); ImGui::End(); } std::string PROBAInstrumentsDecoderModule::getID() { return "proba_instruments"; } std::shared_ptr PROBAInstrumentsDecoderModule::getInstance(std::string input_file, std::string output_file_hint, nlohmann::json parameters) { return std::make_shared(input_file, output_file_hint, parameters); } } // namespace instruments } // namespace proba