2022-03-15 01:01:03 +01:00
# include "module_jpss_instruments.h"
2025-05-31 20:26:47 +02:00
# include "common/calibration.h"
# include "common/ccsds/ccsds_aos/demuxer.h"
2024-08-10 15:50:25 +02:00
# include "common/ccsds/ccsds_aos/vcdu.h"
2022-03-15 01:01:03 +01:00
# include "common/utils.h"
2025-05-25 14:30:24 +02:00
# include "core/resources.h"
2025-05-31 20:26:47 +02:00
# include "image/bowtie.h"
2025-05-25 14:30:24 +02:00
# include "image/io.h"
2025-05-31 20:26:47 +02:00
# include "imgui/imgui.h"
2025-09-26 10:25:46 +02:00
# include "init.h"
2025-01-09 20:34:51 +01:00
# include "instruments/viirs/viirs_viewang.h"
2025-05-31 20:26:47 +02:00
# include "jpss.h"
# include "logger.h"
# include "nlohmann/json_utils.h"
# include <cstdint>
# include <filesystem>
# include <fstream>
2025-01-09 20:34:51 +01:00
# include "common/tracking/tle.h"
2025-07-23 12:21:02 +02:00
# include "products/dataset.h"
# include "products/image_product.h"
2025-05-26 19:21:10 +01:00
# include "utils/stats.h"
2023-10-30 20:58:44 +01:00
2022-03-15 01:01:03 +01:00
namespace jpss
{
namespace instruments
{
JPSSInstrumentsDecoderModule : : JPSSInstrumentsDecoderModule ( std : : string input_file , std : : string output_file_hint , nlohmann : : json parameters )
2025-05-31 20:26:47 +02:00
: satdump : : pipeline : : base : : FileStreamToFileStreamModule ( input_file , output_file_hint , parameters ) , npp_mode ( parameters [ " npp_mode " ] . get < bool > ( ) )
2022-03-15 01:01:03 +01:00
{
2025-05-31 20:26:47 +02:00
fsfsm_enable_output = false ;
2022-03-15 01:01:03 +01:00
}
void JPSSInstrumentsDecoderModule : : process ( )
{
uint8_t cadu [ 1279 ] ; // Oversized for NPP, but not a big deal
int mpdu_size = npp_mode ? 884 : 1094 ;
int insert_zone_size = npp_mode ? 0 : 9 ;
// Demuxers
2024-08-10 15:50:25 +02:00
ccsds : : ccsds_aos : : Demuxer demuxer_vcid0 ( mpdu_size , true , insert_zone_size ) ;
ccsds : : ccsds_aos : : Demuxer demuxer_vcid1 ( mpdu_size , true , insert_zone_size ) ;
ccsds : : ccsds_aos : : Demuxer demuxer_vcid6 ( mpdu_size , true , insert_zone_size ) ;
ccsds : : ccsds_aos : : Demuxer demuxer_vcid11 ( mpdu_size , true , insert_zone_size ) ;
ccsds : : ccsds_aos : : Demuxer demuxer_vcid16 ( mpdu_size , true , insert_zone_size ) ;
2022-03-15 01:01:03 +01:00
std : : vector < uint8_t > jpss_scids ;
2025-05-31 20:26:47 +02:00
while ( should_run ( ) )
2022-03-15 01:01:03 +01:00
{
// Read buffer
2025-05-31 20:26:47 +02:00
read_data ( ( uint8_t * ) & cadu , npp_mode ? 1024 : 1279 ) ;
2022-03-15 01:01:03 +01:00
// Parse this transport frame
2024-08-10 15:50:25 +02:00
ccsds : : ccsds_aos : : VCDU vcdu = ccsds : : ccsds_aos : : parseVCDU ( cadu ) ;
2022-03-15 01:01:03 +01:00
2025-05-31 20:26:47 +02:00
if ( vcdu . spacecraft_id = = SNPP_SCID | | vcdu . spacecraft_id = = JPSS1_SCID | | vcdu . spacecraft_id = = JPSS2_SCID /*||
vcdu . spacecraft_id = = JPSS3_SCID | |
vcdu . spacecraft_id = = JPSS4_SCID */
2022-05-12 18:19:01 +02:00
)
2022-03-15 01:01:03 +01:00
jpss_scids . push_back ( vcdu . spacecraft_id ) ;
2023-10-25 19:31:53 +02:00
if ( vcdu . vcid = = 0 ) // HK/TM
{
std : : vector < ccsds : : CCSDSPacket > ccsdsFrames = demuxer_vcid0 . work ( cadu ) ;
for ( ccsds : : CCSDSPacket & pkt : ccsdsFrames )
if ( pkt . header . apid = = 11 )
att_ephem . work ( pkt ) ;
}
else if ( vcdu . vcid = = 1 ) // ATMS
2022-03-15 01:01:03 +01:00
{
std : : vector < ccsds : : CCSDSPacket > ccsdsFrames = demuxer_vcid1 . work ( cadu ) ;
for ( ccsds : : CCSDSPacket & pkt : ccsdsFrames )
if ( pkt . header . apid = = 528 )
atms_reader . work ( pkt ) ;
2023-10-27 13:34:53 +02:00
else if ( pkt . header . apid = = 515 )
atms_reader . work_calib ( pkt ) ;
2023-10-28 18:56:15 +02:00
else if ( pkt . header . apid = = 530 )
atms_reader . work_hotcal ( pkt ) ;
else if ( pkt . header . apid = = 531 )
atms_reader . work_eng ( pkt ) ;
2022-03-15 01:01:03 +01:00
}
2022-03-15 15:49:47 +01:00
else if ( vcdu . vcid = = 6 ) // CrIS
{
// std::vector<ccsds::CCSDSPacket> ccsdsFrames = demuxer_vcid6.work(cadu);
// for (ccsds::CCSDSPacket &pkt : ccsdsFrames)
// if (pkt.header.apid == 1340)
// {
// logger->info(pkt.payload.size() + 6);
// }
}
2022-03-15 01:01:03 +01:00
else if ( vcdu . vcid = = 11 ) // OMPS
{
std : : vector < ccsds : : CCSDSPacket > ccsdsFrames = demuxer_vcid11 . work ( cadu ) ;
for ( ccsds : : CCSDSPacket & pkt : ccsdsFrames )
if ( pkt . header . apid = = 616 | | pkt . header . apid = = 560 )
omps_nadir_reader . work ( pkt ) ;
else if ( pkt . header . apid = = 617 | | pkt . header . apid = = 561 )
omps_limb_reader . work ( pkt ) ;
}
else if ( vcdu . vcid = = 16 ) // VIIRS
{
std : : vector < ccsds : : CCSDSPacket > ccsdsFrames = demuxer_vcid16 . work ( cadu ) ;
for ( ccsds : : CCSDSPacket & pkt : ccsdsFrames )
{
/*
Feeding all readers directly that way certainly is
not the absolute best way , but since APID selection
could change , it doesn ' t really impact anything that
much anyway .
*/
// Moderate resolution channels
for ( int i = 0 ; i < 16 ; i + + )
viirs_reader_moderate [ i ] . feed ( pkt ) ;
// Imaging channels
for ( int i = 0 ; i < 5 ; i + + )
viirs_reader_imaging [ i ] . feed ( pkt ) ;
// DNB channels
for ( int i = 0 ; i < 3 ; i + + )
viirs_reader_dnb [ i ] . feed ( pkt ) ;
}
}
}
2025-05-31 20:26:47 +02:00
cleanup ( ) ;
2022-03-15 01:01:03 +01:00
2025-05-26 19:21:10 +01:00
int scid = satdump : : most_common ( jpss_scids . begin ( ) , jpss_scids . end ( ) , 0 ) ;
2022-03-15 01:01:03 +01:00
jpss_scids . clear ( ) ;
std : : string sat_name = " Unknown JPSS " ;
if ( scid = = SNPP_SCID )
sat_name = " Suomi NPP " ;
else if ( scid = = JPSS1_SCID )
sat_name = " NOAA 20 (JPSS-1) " ;
2022-12-12 15:28:27 +01:00
else if ( scid = = JPSS2_SCID )
sat_name = " NOAA 21 (JPSS-2) " ;
2022-03-15 01:01:03 +01:00
int norad = 0 ;
if ( scid = = SNPP_SCID )
norad = SNPP_NORAD ;
else if ( scid = = JPSS1_SCID )
norad = JPSS1_NORAD ;
2022-03-15 01:06:43 +01:00
else if ( scid = = JPSS2_SCID )
norad = JPSS2_NORAD ;
else if ( scid = = JPSS3_SCID )
norad = JPSS3_NORAD ;
else if ( scid = = JPSS4_SCID )
norad = JPSS4_NORAD ;
2022-03-15 01:01:03 +01:00
2022-04-27 23:10:22 +02:00
// Products dataset
2025-01-09 20:34:51 +01:00
satdump : : products : : DataSet dataset ;
2022-04-27 23:10:22 +02:00
dataset . satellite_name = sat_name ;
2025-05-26 19:21:10 +01:00
dataset . timestamp = satdump : : get_median ( atms_reader . timestamps ) ;
2022-04-27 23:10:22 +02:00
2025-09-26 10:25:46 +02:00
std : : optional < satdump : : TLE > satellite_tle = satdump : : db_tle - > get_from_norad_time ( norad , dataset . timestamp ) ;
2024-05-24 23:19:50 +02:00
2022-03-15 01:01:03 +01:00
// Satellite ID
{
logger - > info ( " ----------- Satellite " ) ;
logger - > info ( " NORAD : " + std : : to_string ( norad ) ) ;
logger - > info ( " Name : " + sat_name ) ;
}
// ATMS
{
atms_status = SAVING ;
std : : string directory = d_output_file_hint . substr ( 0 , d_output_file_hint . rfind ( ' / ' ) ) + " /ATMS " ;
if ( ! std : : filesystem : : exists ( directory ) )
std : : filesystem : : create_directory ( directory ) ;
logger - > info ( " ----------- ATMS " ) ;
logger - > info ( " Lines : " + std : : to_string ( atms_reader . lines ) ) ;
2025-01-09 20:34:51 +01:00
satdump : : products : : ImageProduct atms_products ;
2022-04-27 23:10:22 +02:00
atms_products . instrument_name = " atms " ;
2023-10-25 19:31:53 +02:00
auto proj_cfg = loadJsonFile ( resources : : getResourcePath ( " projections_settings/jpss_atms.json " ) ) ;
2023-10-26 00:05:11 +02:00
if ( d_parameters [ " use_ephemeris " ] . get < bool > ( ) )
proj_cfg [ " ephemeris " ] = att_ephem . getEphem ( ) ;
2025-01-09 20:34:51 +01:00
atms_products . set_proj_cfg_tle_timestamps ( proj_cfg , satellite_tle , atms_reader . timestamps ) ;
2022-04-27 23:10:22 +02:00
2022-03-15 01:01:03 +01:00
for ( int i = 0 ; i < 22 ; i + + )
2025-01-09 20:34:51 +01:00
atms_products . images . push_back ( { i , " ATMS- " + std : : to_string ( i + 1 ) , std : : to_string ( i + 1 ) , atms_reader . getChannel ( i ) , 16 } ) ;
2022-04-27 23:10:22 +02:00
2023-10-30 22:39:22 +01:00
nlohmann : : json calib_coefs = loadCborFile ( resources : : getResourcePath ( " calibration/ATMS.cbor " ) ) ;
if ( calib_coefs . contains ( sat_name ) )
2023-10-28 18:56:15 +02:00
{
2023-10-30 22:39:22 +01:00
atms : : ATMS_SDR_CC sdr_cc = calib_coefs [ sat_name ] ;
nlohmann : : json calib_cfg ;
calib_cfg [ " vars " ] = atms_reader . getCalib ( ) ;
calib_cfg [ " sdr_cc " ] = calib_coefs [ sat_name ] ;
2025-01-09 20:34:51 +01:00
atms_products . set_calibration ( " jpss_atms " , calib_cfg ) ;
2023-10-30 22:39:22 +01:00
for ( int c = 0 ; c < 22 ; c + + )
{
2025-01-12 20:25:45 +01:00
atms_products . set_channel_unit ( c , CALIBRATION_ID_EMISSIVE_RADIANCE ) ;
2025-01-09 20:34:51 +01:00
atms_products . set_channel_frequency ( c , sdr_cc . centralFrequency [ c ] ) ;
2023-10-30 22:39:22 +01:00
}
2023-10-28 18:56:15 +02:00
}
2023-10-30 22:39:22 +01:00
else
logger - > warn ( " (ATMS) Calibration data for " + sat_name + " not found. Calibration will not be performed " ) ;
2023-10-28 18:56:15 +02:00
2022-04-27 23:10:22 +02:00
atms_products . save ( directory ) ;
dataset . products_list . push_back ( " ATMS " ) ;
2022-03-15 01:01:03 +01:00
atms_status = DONE ;
}
// OMPS NADIR
{
omps_nadir_status = SAVING ;
std : : string directory = d_output_file_hint . substr ( 0 , d_output_file_hint . rfind ( ' / ' ) ) + " /OMPS/Nadir " ;
if ( ! std : : filesystem : : exists ( directory ) )
std : : filesystem : : create_directories ( directory ) ;
logger - > info ( " ----------- OMPS-NADIR " ) ;
logger - > info ( " Lines : " + std : : to_string ( omps_nadir_reader . lines ) ) ;
for ( int i = 0 ; i < 339 ; i + + )
{
2024-05-08 17:28:11 +02:00
auto img = omps_nadir_reader . getChannel ( i ) ;
2024-05-09 01:16:08 +02:00
image : : save_img ( img , directory + " /OMPS-NADIR- " + std : : to_string ( i + 1 ) ) ;
2022-03-15 01:01:03 +01:00
}
omps_nadir_status = DONE ;
}
// OMPS LIMB
{
omps_limb_status = SAVING ;
std : : string directory = d_output_file_hint . substr ( 0 , d_output_file_hint . rfind ( ' / ' ) ) + " /OMPS/Limb " ;
if ( ! std : : filesystem : : exists ( directory ) )
std : : filesystem : : create_directories ( directory ) ;
logger - > info ( " ----------- OMPS-NADIR " ) ;
logger - > info ( " Lines : " + std : : to_string ( omps_nadir_reader . lines ) ) ;
for ( int i = 0 ; i < 135 ; i + + )
{
2024-05-08 17:28:11 +02:00
auto img = omps_limb_reader . getChannel ( i ) ;
2024-05-09 01:16:08 +02:00
image : : save_img ( img , directory + " /OMPS-LIMB- " + std : : to_string ( i + 1 ) ) ;
2022-03-15 01:01:03 +01:00
}
omps_limb_status = DONE ;
}
// VIIRS
{
viirs_dnb_status = PROCESSING ;
for ( int i = 0 ; i < 16 ; i + + )
{
viirs_moderate_status [ i ] = PROCESSING ;
if ( i < 5 )
viirs_imaging_status [ i ] = PROCESSING ;
}
std : : string directory = d_output_file_hint . substr ( 0 , d_output_file_hint . rfind ( ' / ' ) ) + " /VIIRS " ;
2023-10-16 01:38:29 +02:00
std : : string directory_dnb = d_output_file_hint . substr ( 0 , d_output_file_hint . rfind ( ' / ' ) ) + " /VIIRS-DNB " ;
2022-03-15 01:01:03 +01:00
if ( ! std : : filesystem : : exists ( directory ) )
std : : filesystem : : create_directories ( directory ) ;
2023-10-16 01:38:29 +02:00
if ( ! std : : filesystem : : exists ( directory_dnb ) )
std : : filesystem : : create_directories ( directory_dnb ) ;
2022-03-15 01:01:03 +01:00
logger - > info ( " ----------- VIIRS " ) ;
for ( int i = 0 ; i < 5 ; i + + )
logger - > info ( " I " + std : : to_string ( i + 1 ) + " Segments : " + std : : to_string ( viirs_reader_imaging [ i ] . segments . size ( ) ) ) ;
2023-10-31 20:23:49 +01:00
for ( int i = 0 ; i < 16 ; i + + )
logger - > info ( " M " + std : : to_string ( i + 1 ) + " Segments : " + std : : to_string ( viirs_reader_moderate [ i ] . segments . size ( ) ) ) ;
2022-03-15 01:01:03 +01:00
logger - > info ( " DNB Segments : " + std : : to_string ( viirs_reader_dnb [ 0 ] . segments . size ( ) ) ) ;
process_viirs_channels ( ) ; // Differential decoding!
// BowTie values
const float alpha = 1.0 / 1.9 ;
const float beta = 0.52333 ; // 1.0 - alpha;
2023-10-16 01:38:29 +02:00
// Normal channels
2025-01-09 20:34:51 +01:00
satdump : : products : : ImageProduct viirs_products ;
2022-04-20 15:57:17 +02:00
viirs_products . instrument_name = " viirs " ;
2023-10-16 00:46:04 +02:00
2025-01-09 20:34:51 +01:00
nlohmann : : json proj_cfg_all ;
2023-10-15 12:05:41 +02:00
if ( scid = = SNPP_SCID )
2025-01-09 20:34:51 +01:00
proj_cfg_all = loadJsonFile ( resources : : getResourcePath ( " projections_settings/npp_viirs.json " ) ) ;
2023-10-15 12:05:41 +02:00
else if ( scid = = JPSS1_SCID )
2025-01-09 20:34:51 +01:00
proj_cfg_all = loadJsonFile ( resources : : getResourcePath ( " projections_settings/jpss1_viirs.json " ) ) ;
2023-10-15 12:05:41 +02:00
else if ( scid = = JPSS2_SCID )
2025-01-09 20:34:51 +01:00
proj_cfg_all = loadJsonFile ( resources : : getResourcePath ( " projections_settings/jpss2_viirs.json " ) ) ;
2022-04-20 15:57:17 +02:00
2025-01-09 20:34:51 +01:00
auto proj_cfg = proj_cfg_all [ " proj " ] ;
auto norm_cfg = proj_cfg_all [ " normal " ] ;
auto dnb_cfg = proj_cfg_all [ " dnb " ] ;
2023-10-16 01:38:29 +02:00
2023-10-26 00:05:11 +02:00
if ( d_parameters [ " use_ephemeris " ] . get < bool > ( ) )
proj_cfg [ " ephemeris " ] = att_ephem . getEphem ( ) ;
2025-01-09 20:34:51 +01:00
viirs_products . set_proj_cfg_tle_timestamps ( proj_cfg , satellite_tle , viirs_reader_imaging [ 0 ] . timestamps ) ; // All the same now. Merge to a single "timestamps"?
2025-05-31 20:26:47 +02:00
auto points_viirs_normal_ch =
viirs : : calculateVIIRSViewAnglePoints ( false , getValueOrDefault ( norm_cfg [ " is_n20 " ] , false ) , norm_cfg [ " scan_angle " ] , getValueOrDefault ( norm_cfg [ " roll_offset " ] , 0.0 ) ) ;
auto points_viirs_dnb_ch =
viirs : : calculateVIIRSViewAnglePoints ( true , getValueOrDefault ( dnb_cfg [ " is_n20 " ] , false ) , dnb_cfg [ " scan_angle " ] , getValueOrDefault ( dnb_cfg [ " roll_offset " ] , 0.0 ) ) ;
2023-10-16 01:38:29 +02:00
2022-03-15 01:01:03 +01:00
for ( int i = 0 ; i < 5 ; i + + )
{
if ( viirs_reader_imaging [ i ] . segments . size ( ) > 0 )
{
logger - > info ( " I " + std : : to_string ( i + 1 ) + " ... " ) ;
2024-05-09 01:16:08 +02:00
image : : Image viirs_image = viirs_reader_imaging [ i ] . getImage ( ) ;
viirs_image = image : : bowtie : : correctGenericBowTie ( viirs_image , 1 , viirs_reader_imaging [ i ] . channelSettings . zoneHeight , alpha , beta ) ;
2022-03-15 01:01:03 +01:00
viirs_imaging_status [ i ] = SAVING ;
2022-04-20 15:57:17 +02:00
2025-05-31 20:26:47 +02:00
viirs_products . images . push_back (
{ i , " VIIRS-I " + std : : to_string ( i + 1 ) , " i " + std : : to_string ( i + 1 ) , viirs_image , 16 , satdump : : ChannelTransform ( ) . init_affine_interpx ( 1 , 1 , 0 , 0 , points_viirs_normal_ch ) } ) ;
2022-03-15 01:01:03 +01:00
}
viirs_imaging_status [ i ] = DONE ;
}
2023-10-31 20:23:49 +01:00
for ( int i = 0 ; i < 16 ; i + + )
{
if ( viirs_reader_moderate [ i ] . segments . size ( ) > 0 )
{
logger - > info ( " M " + std : : to_string ( i + 1 ) + " ... " ) ;
2024-05-09 01:16:08 +02:00
image : : Image viirs_image = viirs_reader_moderate [ i ] . getImage ( ) ;
viirs_image = image : : bowtie : : correctGenericBowTie ( viirs_image , 1 , viirs_reader_moderate [ i ] . channelSettings . zoneHeight , alpha , beta ) ;
2023-10-31 20:23:49 +01:00
viirs_moderate_status [ i ] = SAVING ;
2025-05-31 20:26:47 +02:00
viirs_products . images . push_back ( { i + 5 , " VIIRS-M " + std : : to_string ( i + 1 ) , " m " + std : : to_string ( i + 1 ) , viirs_image , 16 ,
2025-01-09 20:34:51 +01:00
satdump : : ChannelTransform ( ) . init_affine_interpx ( 2 , 2 , 0 , 0 , points_viirs_normal_ch ) } ) ;
2023-10-31 20:23:49 +01:00
}
viirs_moderate_status [ i ] = DONE ;
}
2022-03-15 01:01:03 +01:00
viirs_dnb_status = SAVING ;
if ( viirs_reader_dnb [ 0 ] . segments . size ( ) > 0 )
{
logger - > info ( " DNB... " ) ;
2022-04-20 15:57:17 +02:00
2025-05-31 20:26:47 +02:00
viirs_products . images . push_back ( { 21 , " VIIRS-DNB " , " dnb " , viirs_reader_dnb [ 0 ] . getImage ( ) , 16 , satdump : : ChannelTransform ( ) . init_affine_interpx ( 1 , 2 , 0 , 1 , points_viirs_dnb_ch ) } ) ;
2022-03-15 01:01:03 +01:00
}
if ( viirs_reader_dnb [ 1 ] . segments . size ( ) > 0 )
{
logger - > info ( " DNB MGS... " ) ;
2022-04-20 15:57:17 +02:00
2025-05-31 20:26:47 +02:00
viirs_products . images . push_back (
{ 22 , " VIIRS-DNB-MGS " , " dnbmgs " , viirs_reader_dnb [ 1 ] . getImage ( ) , 16 , satdump : : ChannelTransform ( ) . init_affine_interpx ( 1 , 2 , 0 , 1 , points_viirs_dnb_ch ) } ) ;
2022-03-15 01:01:03 +01:00
}
if ( viirs_reader_dnb [ 2 ] . segments . size ( ) > 0 )
{
logger - > info ( " DNB LGS... " ) ;
2022-04-20 15:57:17 +02:00
2025-05-31 20:26:47 +02:00
viirs_products . images . push_back (
{ 23 , " VIIRS-DNB-LGS " , " dnblgs " , viirs_reader_dnb [ 2 ] . getImage ( ) , 16 , satdump : : ChannelTransform ( ) . init_affine_interpx ( 1 , 2 , 0 , 1 , points_viirs_dnb_ch ) } ) ;
2022-03-15 01:01:03 +01:00
}
viirs_dnb_status = DONE ;
2022-04-20 15:57:17 +02:00
viirs_products . save ( directory ) ;
2022-04-27 23:10:22 +02:00
dataset . products_list . push_back ( " VIIRS " ) ;
2022-03-15 01:01:03 +01:00
}
2022-04-27 23:10:22 +02:00
dataset . save ( d_output_file_hint . substr ( 0 , d_output_file_hint . rfind ( ' / ' ) ) ) ;
2022-03-15 01:01:03 +01:00
}
void JPSSInstrumentsDecoderModule : : drawUI ( bool window )
{
2022-09-02 01:59:13 +02:00
ImGui : : Begin ( " JPSS Instruments Decoder " , NULL , window ? 0 : NOWINDOW_FLAGS ) ;
2022-03-15 01:01:03 +01:00
if ( ImGui : : BeginTable ( " ##jpssinstrumentstable " , 3 , ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg ) )
{
ImGui : : TableNextRow ( ) ;
ImGui : : TableSetColumnIndex ( 0 ) ;
ImGui : : Text ( " Instrument " ) ;
ImGui : : TableSetColumnIndex ( 1 ) ;
ImGui : : Text ( " Lines / Frames " ) ;
ImGui : : TableSetColumnIndex ( 2 ) ;
ImGui : : Text ( " Status " ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableSetColumnIndex ( 0 ) ;
ImGui : : Text ( " ATMS " ) ;
ImGui : : TableSetColumnIndex ( 1 ) ;
2024-01-21 14:57:41 -05:00
ImGui : : TextColored ( style : : theme . green , " %d " , atms_reader . lines ) ;
2022-03-15 01:01:03 +01:00
ImGui : : TableSetColumnIndex ( 2 ) ;
drawStatus ( atms_status ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableSetColumnIndex ( 0 ) ;
ImGui : : Text ( " OMPS Nadir " ) ;
ImGui : : TableSetColumnIndex ( 1 ) ;
2024-01-21 14:57:41 -05:00
ImGui : : TextColored ( style : : theme . green , " %d " , omps_nadir_reader . lines ) ;
2022-03-15 01:01:03 +01:00
ImGui : : TableSetColumnIndex ( 2 ) ;
drawStatus ( omps_nadir_status ) ;
ImGui : : TableNextRow ( ) ;
ImGui : : TableSetColumnIndex ( 0 ) ;
ImGui : : Text ( " OMPS Limb " ) ;
ImGui : : TableSetColumnIndex ( 1 ) ;
2024-01-21 14:57:41 -05:00
ImGui : : TextColored ( style : : theme . green , " %d " , omps_limb_reader . lines ) ;
2022-03-15 01:01:03 +01:00
ImGui : : TableSetColumnIndex ( 2 ) ;
drawStatus ( omps_limb_status ) ;
for ( int i = 0 ; i < 16 ; i + + )
{
ImGui : : TableNextRow ( ) ;
ImGui : : TableSetColumnIndex ( 0 ) ;
ImGui : : Text ( " VIIRS M%d " , i + 1 ) ;
ImGui : : TableSetColumnIndex ( 1 ) ;
2024-01-21 14:57:41 -05:00
ImGui : : TextColored ( style : : theme . green , " %d " , ( int ) viirs_reader_moderate [ i ] . segments . size ( ) ) ;
2022-03-15 01:01:03 +01:00
ImGui : : TableSetColumnIndex ( 2 ) ;
drawStatus ( viirs_moderate_status [ i ] ) ;
}
for ( int i = 0 ; i < 5 ; i + + )
{
ImGui : : TableNextRow ( ) ;
ImGui : : TableSetColumnIndex ( 0 ) ;
ImGui : : Text ( " VIIRS I%d " , i + 1 ) ;
ImGui : : TableSetColumnIndex ( 1 ) ;
2024-01-21 14:57:41 -05:00
ImGui : : TextColored ( style : : theme . green , " %d " , ( int ) viirs_reader_imaging [ i ] . segments . size ( ) ) ;
2022-03-15 01:01:03 +01:00
ImGui : : TableSetColumnIndex ( 2 ) ;
drawStatus ( viirs_imaging_status [ i ] ) ;
}
ImGui : : TableNextRow ( ) ;
ImGui : : TableSetColumnIndex ( 0 ) ;
ImGui : : Text ( " VIIRS DNB " ) ;
ImGui : : TableSetColumnIndex ( 1 ) ;
2024-01-21 14:57:41 -05:00
ImGui : : TextColored ( style : : theme . green , " %d " , ( int ) viirs_reader_dnb [ 0 ] . segments . size ( ) ) ;
2022-03-15 01:01:03 +01:00
ImGui : : TableSetColumnIndex ( 2 ) ;
drawStatus ( viirs_dnb_status ) ;
ImGui : : EndTable ( ) ;
}
2025-05-31 20:26:47 +02:00
drawProgressBar ( ) ;
2022-03-15 01:01:03 +01:00
ImGui : : End ( ) ;
}
2024-12-08 18:54:18 +01:00
inline bool vectorContains ( std : : vector < double > v , double f )
{
for ( auto & c : v )
if ( c = = f )
return true ;
return false ;
}
2022-03-15 01:01:03 +01:00
void JPSSInstrumentsDecoderModule : : process_viirs_channels ( )
{
2024-12-08 18:54:18 +01:00
{
std : : vector < double > timestamps ;
for ( int i = 0 ; i < 5 ; i + + )
for ( auto & seg : viirs_reader_imaging [ i ] . segments )
if ( ! vectorContains ( timestamps , seg . timestamp ) )
timestamps . push_back ( seg . timestamp ) ;
for ( int i = 0 ; i < 16 ; i + + )
for ( auto & seg : viirs_reader_moderate [ i ] . segments )
if ( ! vectorContains ( timestamps , seg . timestamp ) )
timestamps . push_back ( seg . timestamp ) ;
2024-12-11 11:54:04 +01:00
for ( int i = 0 ; i < 3 ; i + + )
for ( auto & seg : viirs_reader_dnb [ i ] . segments )
if ( ! vectorContains ( timestamps , seg . timestamp ) )
timestamps . push_back ( seg . timestamp ) ;
2024-12-08 18:54:18 +01:00
std : : sort ( timestamps . begin ( ) , timestamps . end ( ) ) ;
for ( int i = 0 ; i < 5 ; i + + )
{
auto & r = viirs_reader_imaging [ i ] ;
std : : vector < viirs : : VIIRS_Segment > oldSegments = r . segments ;
r . segments . clear ( ) ;
for ( auto & time : timestamps )
{
bool contains = false ;
for ( auto & seg : oldSegments )
{
if ( seg . timestamp = = time )
{
r . segments . push_back ( seg ) ;
contains = true ;
}
}
if ( ! contains )
r . segments . push_back ( viirs : : VIIRS_Segment ( r . channelSettings ) ) ;
}
2025-01-09 20:34:51 +01:00
r . timestamps = timestamps ;
2024-12-08 18:54:18 +01:00
}
for ( int i = 0 ; i < 16 ; i + + )
{
auto & r = viirs_reader_moderate [ i ] ;
std : : vector < viirs : : VIIRS_Segment > oldSegments = r . segments ;
2024-12-11 11:54:04 +01:00
r . segments . clear ( ) ;
for ( auto & time : timestamps )
{
bool contains = false ;
for ( auto & seg : oldSegments )
{
if ( seg . timestamp = = time )
{
r . segments . push_back ( seg ) ;
contains = true ;
}
}
if ( ! contains )
r . segments . push_back ( viirs : : VIIRS_Segment ( r . channelSettings ) ) ;
}
2025-01-09 20:34:51 +01:00
r . timestamps = timestamps ;
2024-12-11 11:54:04 +01:00
}
for ( int i = 0 ; i < 3 ; i + + )
{
auto & r = viirs_reader_dnb [ i ] ;
std : : vector < viirs : : VIIRS_Segment > oldSegments = r . segments ;
2024-12-08 18:54:18 +01:00
r . segments . clear ( ) ;
for ( auto & time : timestamps )
{
bool contains = false ;
for ( auto & seg : oldSegments )
{
if ( seg . timestamp = = time )
{
r . segments . push_back ( seg ) ;
contains = true ;
}
}
if ( ! contains )
r . segments . push_back ( viirs : : VIIRS_Segment ( r . channelSettings ) ) ;
}
2025-01-09 20:34:51 +01:00
r . timestamps = timestamps ;
2024-12-08 18:54:18 +01:00
}
}
2022-03-15 01:01:03 +01:00
// Differential decoding for M5, M3, M2, M1
logger - > info ( " Diff M5... " ) ;
viirs_reader_moderate [ 5 - 1 ] . differentialDecode ( viirs_reader_moderate [ 4 - 1 ] , 1 ) ;
logger - > info ( " Diff M3... " ) ;
viirs_reader_moderate [ 3 - 1 ] . differentialDecode ( viirs_reader_moderate [ 4 - 1 ] , 1 ) ;
logger - > info ( " Diff M2... " ) ;
viirs_reader_moderate [ 2 - 1 ] . differentialDecode ( viirs_reader_moderate [ 3 - 1 ] , 1 ) ;
logger - > info ( " Diff M1... " ) ;
viirs_reader_moderate [ 1 - 1 ] . differentialDecode ( viirs_reader_moderate [ 2 - 1 ] , 1 ) ;
// Differential decoding for M8, M11
logger - > info ( " Diff M8... " ) ;
viirs_reader_moderate [ 8 - 1 ] . differentialDecode ( viirs_reader_moderate [ 10 - 1 ] , 1 ) ;
logger - > info ( " Diff M11... " ) ;
viirs_reader_moderate [ 11 - 1 ] . differentialDecode ( viirs_reader_moderate [ 10 - 1 ] , 1 ) ;
// Differential decoding for M14
logger - > info ( " Diff M14... " ) ;
viirs_reader_moderate [ 14 - 1 ] . differentialDecode ( viirs_reader_moderate [ 15 - 1 ] , 1 ) ;
// Differential decoding for I2, I3
logger - > info ( " Diff I2... " ) ;
viirs_reader_imaging [ 2 - 1 ] . differentialDecode ( viirs_reader_imaging [ 1 - 1 ] , 1 ) ;
logger - > info ( " Diff I3... " ) ;
viirs_reader_imaging [ 3 - 1 ] . differentialDecode ( viirs_reader_imaging [ 2 - 1 ] , 1 ) ;
// Differential decoding for I4 and I5
logger - > info ( " Diff I4... " ) ;
viirs_reader_imaging [ 4 - 1 ] . differentialDecode ( viirs_reader_moderate [ 12 - 1 ] , 2 ) ;
logger - > info ( " Diff I5... " ) ;
viirs_reader_imaging [ 5 - 1 ] . differentialDecode ( viirs_reader_moderate [ 15 - 1 ] , 2 ) ;
}
2025-05-31 20:26:47 +02:00
std : : string JPSSInstrumentsDecoderModule : : getID ( ) { return " jpss_instruments " ; }
2022-03-15 01:01:03 +01:00
2025-05-31 20:26:47 +02:00
std : : shared_ptr < satdump : : pipeline : : ProcessingModule > JPSSInstrumentsDecoderModule : : getInstance ( std : : string input_file , std : : string output_file_hint , nlohmann : : json parameters )
2022-03-15 01:01:03 +01:00
{
return std : : make_shared < JPSSInstrumentsDecoderModule > ( input_file , output_file_hint , parameters ) ;
}
2025-05-31 20:26:47 +02:00
} // namespace instruments
} // namespace jpss