diff --git a/pipelines/Cloudsat.json b/pipelines/Cloudsat.json new file mode 100644 index 000000000..27411a851 --- /dev/null +++ b/pipelines/Cloudsat.json @@ -0,0 +1,48 @@ +{ + "cloudsat_link": { + "name": "CloudSat S-Band Link", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 2217.5 + ], + "samplerate": 4e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 1000000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.004, + "buffer_size": 8192 + } + }, + "frm": { + "ccsds_simple_psk_decoder": { + "ccsds": false, + "constellation": "bpsk", + "cadu_size": 3216, + "derandomize": false, + "nrzm": true, + "rs_i": 0, + "asm": "0x04b3e375" + } + }, + "products": { + "cloudsat_cpr": {} + } + } + } +} \ No newline at end of file diff --git a/pipelines/Coriolis.json b/pipelines/Coriolis.json new file mode 100644 index 000000000..e2960a4f6 --- /dev/null +++ b/pipelines/Coriolis.json @@ -0,0 +1,49 @@ +{ + "coriolis_db": { + "name": "Coriolis S-Band Tactical DB", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 2221.5 + ], + "samplerate": 4e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 512000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.004, + "buffer_size": 8192 + } + }, + "frm": { + "ccsds_conv_r2_concat_decoder": { + "ccsds": false, + "constellation": "bpsk", + "cadu_size": 8192, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": false, + "rs_i": 0, + "asm": "0x352ef853" + } + }, + "products": { + "coriolis_windsat": {} + } + } + } +} \ No newline at end of file diff --git a/pipelines/Cryosat.json b/pipelines/Cryosat.json new file mode 100644 index 000000000..c8c43addc --- /dev/null +++ b/pipelines/Cryosat.json @@ -0,0 +1,35 @@ +{ + "cryosat_dump": { + "name": "Cryosat X-Band Dump", + "live": false, + "live_cfg": [], + "frequencies": [], + "samplerate": 60e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 50000000, + "agc_rate": 0.00001, + "rrc_alpha": 0.35, + "rrc_taps": 31, + "costas_bw": 0.0189, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_simple_psk_decoder": { + "constellation": "qpsk", + "cadu_size": 10232, + "nrzm": true, + "rs_i": 5, + "rs_type": "rs229" + } + }, + "products": { + "cryosat_siral": {} + } + } + } +} \ No newline at end of file diff --git a/pipelines/EOS.json b/pipelines/EOS.json new file mode 100644 index 000000000..ce5ea430a --- /dev/null +++ b/pipelines/EOS.json @@ -0,0 +1,132 @@ +{ + "aqua_db": { + "name": "Aqua DB", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 8160.0 + ], + "samplerate": 15e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "oqpsk_demod": { + "symbolrate": 7500000, + "agc_rate": 0.1, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.006, + "clock_gain_omega": 0.8, + "clock_mu": 0.9, + "clock_gain_mu": 0.037, + "clock_omega_relative_limit": 0.0001, + "dc_block": true, + "constellation_scale": 100, + "buffer_size": 8192 + } + }, + "cadu": { + "aqua_db_decoder": {} + }, + "products": { + "eos_instruments": { + "satellite": "aqua", + "modis_bowtie": true + } + } + } + }, + "terra_db": { + "name": "Terra DB", + "live": false, + "frequencies": [], + "samplerate": 45e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "terra_db_demod": { + "dc_block": false, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "bpsk_90", + "cadu_size": 8192, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": true, + "derand_after_rs": true, + "derand_start": 10, + "nrzm": true, + "rs_i": 4, + "rs_type": "rs223" + } + }, + "products": { + "eos_instruments": { + "satellite": "terra", + "modis_bowtie": true + } + } + } + }, + "aura_db": { + "name": "Aura DB", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 8160.0 + ], + "samplerate": 15e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "oqpsk_demod": { + "symbolrate": 7500000, + "agc_rate": 0.1, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.006, + "clock_gain_omega": 0.8, + "clock_mu": 0.9, + "clock_gain_mu": 0.037, + "clock_omega_relative_limit": 0.0001, + "dc_block": true, + "constellation_scale": 100, + "buffer_size": 8192 + } + }, + "cadu": { + "aqua_db_decoder": {} + }, + "products": { + "eos_instruments": { + "satellite": "aura", + "modis_bowtie": false + } + } + } + } +} \ No newline at end of file diff --git a/pipelines/Elektro_Arktika.json b/pipelines/Elektro_Arktika.json new file mode 100644 index 000000000..418ef8a02 --- /dev/null +++ b/pipelines/Elektro_Arktika.json @@ -0,0 +1,218 @@ +{ + "elektro_rdas": { + "name": "ELEKTRO-L RDAS", + "live": false, + "frequencies": [], + "samplerate": 45e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 30720000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.03, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_simple_psk_decoder": { + "constellation": "bpsk", + "cadu_size": 8192, + "derandomize": true, + "nrzm": true, + "rs_i": 0 + } + }, + "products": { + "elektro_arktika_msugs": {} + } + } + }, + "arktika_rdas": { + "name": "ARKTIKA-M RDAS", + "live": false, + "frequencies": [], + "samplerate": 45e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 30720000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.03, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_simple_psk_decoder": { + "constellation": "bpsk", + "cadu_size": 8192, + "derandomize": true, + "nrzm": true, + "rs_i": 0 + } + }, + "products": { + "elektro_arktika_msugs": {} + } + } + }, + "elektro_lrit": { + "name": "ELEKTRO-L LRIT", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 3, + 0 + ] + ], + "frequencies": [ + 1691.0 + ], + "samplerate": 1e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 294000, + "agc_rate": 0.0001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.02, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "bpsk", + "cadu_size": 8192, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": true, + "rs_i": 4, + "rs_type": "rs223" + } + }, + "products": { + "elektro_lrit_data_decoder": {} + } + } + }, + "elektro_hrit": { + "name": "ELEKTRO-L HRIT", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 3, + 0 + ] + ], + "frequencies": [ + 1691.0 + ], + "samplerate": 6e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "oqpsk_demod": { + "symbolrate": 1150000, + "agc_rate": 0.00001, + "rrc_alpha": 0.6, + "rrc_taps": 31, + "costas_bw": 0.004, + "clock_gain_omega": 2.5e-7, + "clock_mu": 0.5, + "clock_gain_mu": 0.001, + "clock_omega_relative_limit": 0.005, + "dc_block": false, + "constellation_scale": 100, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "qpsk", + "cadu_size": 8192, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": true, + "rs_i": 4, + "rs_type": "rs223" + } + }, + "products": { + "elektro_lrit_data_decoder": {} + } + } + }, + "elektro_tlm": { + "name": "ELEKTRO-L L-Band TLM", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ] + ], + "frequencies": [ + 1693.0 + ], + "samplerate": 3e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "cadu": { + "elektro_arktika_tlm_demod": { + "buffer_size": 8192 + } + } + } + }, + "arktika_tlm": { + "name": "ARKTIKA-M L-Band TLM", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ] + ], + "frequencies": [ + 1703.0 + ], + "samplerate": 3e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "elektro_arktika_tlm_demod": { + "buffer_size": 8192 + } + } + } + } +} \ No newline at end of file diff --git a/pipelines/FengYun-2.json b/pipelines/FengYun-2.json new file mode 100644 index 000000000..fe5df8bf9 --- /dev/null +++ b/pipelines/FengYun-2.json @@ -0,0 +1,46 @@ +{ + "fengyun_svissr": { + "name": "FengYun-2 S-VISSR", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 3, + 0 + ] + ], + "frequencies": [ + 1687.5 + ], + "samplerate": 6e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 660000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.02, + "buffer_size": 8192 + } + }, + "svissr": { + "fengyun_svissr_decoder": {} + }, + "products": { + "fengyun_svissr_image_decoder": { + "satname": "FY-2x" + } + } + } + } +} \ No newline at end of file diff --git a/pipelines/FengYun-3.json b/pipelines/FengYun-3.json new file mode 100644 index 000000000..bf886ee2b --- /dev/null +++ b/pipelines/FengYun-3.json @@ -0,0 +1,256 @@ +{ + "fengyun3_ab_ahrpt": { + "name": "FengYun-3 A/B AHRPT", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 1704.5 + ], + "samplerate": 6e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 2800000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.003, + "buffer_size": 8192 + } + }, + "cadu": { + "new_fengyun_ahrpt_decoder": { + "viterbi_outsync_after": 5, + "viterbi_ber_thresold": 0.170, + "soft_symbols": true, + "invert_second_viterbi": false + } + }, + "products": { + "fengyun_satid": {}, + "fengyun_virr": { + "composites": "composites/fengyun_virr.json.inc" + }, + "fengyun_erm": {}, + "fengyun_mwhs": {} + } + } + }, + "fengyun3_c_ahrpt": { + "name": "FengYun-3 C AHRPT ", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 1701.4 + ], + "samplerate": 6e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 2600000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.003, + "buffer_size": 8192 + } + }, + "cadu": { + "new_fengyun_ahrpt_decoder": { + "viterbi_outsync_after": 5, + "viterbi_ber_thresold": 0.170, + "soft_symbols": true, + "invert_second_viterbi": false + } + }, + "products": { + "fengyun_satid": { + "scid_hint": 51 + }, + "fengyun_virr": { + "composites": "composites/fengyun_virr.json.inc" + }, + "fengyun_erm": {}, + "fengyun_mwhs2": {} + } + } + }, + "fengyun3_abc_mpt": { + "name": "FengYun-3 A/B/C MPT", + "live": false, + "frequencies": [], + "samplerate": 30e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 18700000, + "agc_rate": 0.00001, + "rrc_alpha": 0.35, + "rrc_taps": 31, + "costas_bw": 0.0063, + "buffer_size": 8192 + } + }, + "cadu": { + "new_fengyun_mpt_decoder": { + "viterbi_outsync_after": 5, + "viterbi_ber_thresold": 0.170, + "soft_symbols": true + } + }, + "products": { + "fengyun_satid": {}, + "fengyun_mersi1": { + "correct_bowtie": true, + "composites": "composites/fengyun_mersi1.json.inc" + } + } + } + }, + "fengyun3_d_ahrpt": { + "name": "FengYun-3 D AHRPT", + "live": false, + "frequencies": [], + "samplerate": 45e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 30000000, + "agc_rate": 0.00001, + "rrc_alpha": 0.35, + "rrc_taps": 31, + "costas_bw": 0.0163, + "buffer_size": 8192 + } + }, + "cadu": { + "new_fengyun_ahrpt_decoder": { + "viterbi_outsync_after": 5, + "viterbi_ber_thresold": 0.310, + "soft_symbols": true, + "invert_second_viterbi": true + } + }, + "products": { + "fengyun_satid": { + "scid_hint": 52 + }, + "fengyun_mersi2": { + "correct_bowtie": true, + "composites": "composites/fengyun_mersi2.json.inc" + }, + "fengyun_mwts2": {}, + "fengyun_waai": {}, + "fengyun_mwri": {}, + "fengyun_mwhs2": {} + } + } + }, + "fengyun3_e_ahrpt": { + "name": "FengYun-3 E AHRPT", + "live": false, + "frequencies": [], + "samplerate": 45e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 38400000, + "agc_rate": 0.00001, + "rrc_alpha": 0.35, + "rrc_taps": 31, + "costas_bw": 0.0189, + "buffer_size": 8192 + } + }, + "cadu": { + "new_fengyun_ahrpt_decoder": { + "viterbi_outsync_after": 5, + "viterbi_ber_thresold": 0.170, + "soft_symbols": true, + "invert_second_viterbi": true + } + }, + "products": { + "fengyun_satid": { + "scid_hint": 56 + }, + "fengyun_mersill": { + "correct_bowtie": true, + "composites": "composites/fengyun_mersill.json.inc" + }, + "fengyun_xeuvi": {}, + "fengyun_windrad": {}, + "fengyun_mwts3": {}, + "fengyun_mwhs2": {} + } + } + }, + "fengyun3_abc_dpt": { + "name": "FengYun-3 A/B/C DPT", + "live": false, + "frequencies": [], + "samplerate": 65e6, + "baseband_type": "i8", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 62000000, + "agc_rate": 0.00001, + "rrc_alpha": 0.35, + "rrc_taps": 31, + "costas_bw": 0.0189, + "buffer_size": 8192 + } + }, + "cadu": { + "new_fengyun_ahrpt_decoder": { + "viterbi_outsync_after": 5, + "viterbi_ber_thresold": 0.170, + "soft_symbols": true, + "invert_second_viterbi": true + } + }, + "products": { + "fengyun_satid": {}, + "fengyun_mersi1": { + "correct_bowtie": true, + "composites": "composites/fengyun_mersi1.json.inc" + }, + "fengyun_virr": { + "composites": "composites/fengyun_virr.json.inc" + }, + "fengyun_erm": {}, + "fengyun_mwhs": {} + } + } + } +} \ No newline at end of file diff --git a/pipelines/GEO.json b/pipelines/GEO.json deleted file mode 100644 index 3830e7bc2..000000000 --- a/pipelines/GEO.json +++ /dev/null @@ -1,519 +0,0 @@ -{ - "goes_gvar": { - "name": "GOES GVAR", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ], - [ - 3, - 0 - ] - ], - "frequencies": [ - 1685.7 - ], - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 2110000, - "agc_rate": 0.00001, - "rrc_alpha": 0.7, - "rrc_taps": 31, - "costas_bw": 0.002, - "clock_omega_relative_limit": 0.001, - "buffer_size": 8192 - } - }, - "gvar": { - "goes_gvar_decoder": {} - }, - "products": { - "goes_gvar_image_decoder": {} - } - } - }, - "fengyun_svissr": { - "name": "FengYun-2 S-VISSR", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ], - [ - 3, - 0 - ] - ], - "frequencies": [ - 1687.5 - ], - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 660000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.02, - "buffer_size": 8192 - } - }, - "svissr": { - "fengyun_svissr_decoder": {} - }, - "products": { - "fengyun_svissr_image_decoder": { - "satname": "FY-2x" - } - } - } - }, - "goes_hrit": { - "name": "GOES-R HRIT", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ], - [ - 3, - 0 - ] - ], - "frequencies": [ - 1694.1 - ], - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 927000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.02, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "bpsk", - "cadu_size": 8192, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": true, - "nrzm": true, - "rs_i": 4, - "rs_type": "rs223" - } - }, - "products": { - "goes_lrit_data_decoder": { - "write_images": true, - "write_emwin": true, - "write_messages": true, - "write_dcs": true, - "write_unknown": false - } - } - } - }, - "goes_hrit_tcp": { - "name": "GOES-R HRIT to goestools", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ], - [ - 3, - 0 - ] - ], - "frequencies": [ - 1694.1 - ], - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 927000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.02, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "bpsk", - "cadu_size": 8192, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": true, - "nrzm": true, - "rs_i": 4, - "rs_type": "rs223" - } - }, - "tcp": { - "xrit_goesrecv_publisher": { - "address": "0.0.0.0", - "port": 5004 - } - } - } - }, - "gk2a_lrit": { - "name": "GK-2A LRIT", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ], - [ - 3, - 0 - ] - ], - "frequencies": [ - 1692.14 - ], - "samplerate": 1e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 128000, - "agc_rate": 0.0001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.02, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "bpsk", - "cadu_size": 8192, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": true, - "rs_i": 4, - "rs_type": "rs223" - } - }, - "products": { - "gk2a_lrit_data_decoder": { - "write_images": true, - "write_additional": true, - "write_unknown": true - } - } - } - }, - "gk2a_lrit_tcp": { - "name": "GK-2A LRIT to xrit-rx", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ], - [ - 3, - 0 - ] - ], - "frequencies": [ - 1692.14 - ], - "samplerate": 1e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 128000, - "agc_rate": 0.0001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.02, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "bpsk", - "cadu_size": 8192, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": true, - "rs_i": 4, - "rs_type": "rs223" - } - }, - "tcp": { - "xrit_goesrecv_publisher": { - "address": "0.0.0.0", - "port": 5004 - } - } - } - }, - "gk2a_hrit": { - "name": "GK-2A HRIT", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 1695.4 - ], - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 3000000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.02, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "qpsk", - "cadu_size": 8192, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": true, - "rs_i": 4, - "rs_type": "rs223" - } - } - } - }, - "elektro_lrit": { - "name": "ELEKTRO-L LRIT", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ], - [ - 3, - 0 - ] - ], - "frequencies": [ - 1691.0 - ], - "samplerate": 1e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 294000, - "agc_rate": 0.0001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.02, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "bpsk", - "cadu_size": 8192, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": true, - "rs_i": 4, - "rs_type": "rs223" - } - }, - "products": { - "elektro_lrit_data_decoder": {} - } - } - }, - "elektro_hrit": { - "name": "ELEKTRO-L HRIT", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ], - [ - 3, - 0 - ] - ], - "frequencies": [ - 1691.0 - ], - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "oqpsk_demod": { - "symbolrate": 1150000, - "agc_rate": 0.00001, - "rrc_alpha": 0.6, - "rrc_taps": 31, - "costas_bw": 0.004, - "clock_gain_omega": 2.5e-7, - "clock_mu": 0.5, - "clock_gain_mu": 0.001, - "clock_omega_relative_limit": 0.005, - "dc_block": false, - "constellation_scale": 100, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "qpsk", - "cadu_size": 8192, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": true, - "rs_i": 4, - "rs_type": "rs223" - } - }, - "products": { - "elektro_lrit_data_decoder": {} - } - } - }, - "elektro_tlm": { - "name": "ELEKTRO-L L-Band TLM", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ] - ], - "frequencies": [ - 1693.0 - ], - "samplerate": 3e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "cadu": { - "elektro_arktika_tlm_demod": { - "buffer_size": 8192 - } - } - } - }, - "arktika_tlm": { - "name": "ARKTIKA-M L-Band TLM", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ] - ], - "frequencies": [ - 1703.0 - ], - "samplerate": 3e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "elektro_arktika_tlm_demod": { - "buffer_size": 8192 - } - } - } - }, - "goes_grb": { - "name": "GOES-R GRB", - "live": false, - "frequencies": [], - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "bbframe": {}, - "cadu": { - "goes_grb_cadu_extractor": {} - }, - "products": { - "goes_grb_data_decoder": {} - } - } - } -} \ No newline at end of file diff --git a/pipelines/GK2A.json b/pipelines/GK2A.json new file mode 100644 index 000000000..568e24c91 --- /dev/null +++ b/pipelines/GK2A.json @@ -0,0 +1,152 @@ +{ + "gk2a_lrit": { + "name": "GK-2A LRIT", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 3, + 0 + ] + ], + "frequencies": [ + 1692.14 + ], + "samplerate": 1e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 128000, + "agc_rate": 0.0001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.02, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "bpsk", + "cadu_size": 8192, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": true, + "rs_i": 4, + "rs_type": "rs223" + } + }, + "products": { + "gk2a_lrit_data_decoder": { + "write_images": true, + "write_additional": true, + "write_unknown": true + } + } + } + }, + "gk2a_lrit_tcp": { + "name": "GK-2A LRIT to xrit-rx", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 3, + 0 + ] + ], + "frequencies": [ + 1692.14 + ], + "samplerate": 1e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 128000, + "agc_rate": 0.0001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.02, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "bpsk", + "cadu_size": 8192, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": true, + "rs_i": 4, + "rs_type": "rs223" + } + }, + "tcp": { + "xrit_goesrecv_publisher": { + "address": "0.0.0.0", + "port": 5004 + } + } + } + }, + "gk2a_hrit": { + "name": "GK-2A HRIT", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 1695.4 + ], + "samplerate": 6e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 3000000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.02, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "qpsk", + "cadu_size": 8192, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": true, + "rs_i": 4, + "rs_type": "rs223" + } + } + } + } +} \ No newline at end of file diff --git a/pipelines/GOES.json b/pipelines/GOES.json new file mode 100644 index 000000000..abdc5d372 --- /dev/null +++ b/pipelines/GOES.json @@ -0,0 +1,173 @@ +{ + "goes_gvar": { + "name": "GOES GVAR", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 3, + 0 + ] + ], + "frequencies": [ + 1685.7 + ], + "samplerate": 6e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 2110000, + "agc_rate": 0.00001, + "rrc_alpha": 0.7, + "rrc_taps": 31, + "costas_bw": 0.002, + "clock_omega_relative_limit": 0.001, + "buffer_size": 8192 + } + }, + "gvar": { + "goes_gvar_decoder": {} + }, + "products": { + "goes_gvar_image_decoder": {} + } + } + }, + "goes_hrit": { + "name": "GOES-R HRIT", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 3, + 0 + ] + ], + "frequencies": [ + 1694.1 + ], + "samplerate": 6e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 927000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.02, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "bpsk", + "cadu_size": 8192, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": true, + "nrzm": true, + "rs_i": 4, + "rs_type": "rs223" + } + }, + "products": { + "goes_lrit_data_decoder": { + "write_images": true, + "write_emwin": true, + "write_messages": true, + "write_dcs": true, + "write_unknown": false + } + } + } + }, + "goes_hrit_tcp": { + "name": "GOES-R HRIT to goestools", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 3, + 0 + ] + ], + "frequencies": [ + 1694.1 + ], + "samplerate": 6e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 927000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.02, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "bpsk", + "cadu_size": 8192, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": true, + "nrzm": true, + "rs_i": 4, + "rs_type": "rs223" + } + }, + "tcp": { + "xrit_goesrecv_publisher": { + "address": "0.0.0.0", + "port": 5004 + } + } + } + }, + "goes_grb": { + "name": "GOES-R GRB", + "live": false, + "frequencies": [], + "samplerate": 6e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "bbframe": {}, + "cadu": { + "goes_grb_cadu_extractor": {} + }, + "products": { + "goes_grb_data_decoder": {} + } + } + } +} \ No newline at end of file diff --git a/pipelines/HRPT.json b/pipelines/HRPT.json deleted file mode 100644 index 89bab49c5..000000000 --- a/pipelines/HRPT.json +++ /dev/null @@ -1,592 +0,0 @@ -{ - "metop_ahrpt": { - "name": "MetOp AHRPT", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 1701.3 - ], - "parameters": { - "samplerate": { - "value": 6e6 - } - }, - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 2333333, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.003, - "buffer_size": 8192 - } - }, - "cadu": { - "metop_ahrpt_decoder": { - "viterbi_outsync_after": 10, - "viterbi_ber_thresold": 0.280 - } - }, - "products": { - "metop_instruments": {} - } - } - }, - "fengyun3_ab_ahrpt": { - "name": "FengYun-3 A/B AHRPT", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 1704.5 - ], - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 2800000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.003, - "buffer_size": 8192 - } - }, - "cadu": { - "new_fengyun_ahrpt_decoder": { - "viterbi_outsync_after": 5, - "viterbi_ber_thresold": 0.170, - "soft_symbols": true, - "invert_second_viterbi": false - } - }, - "products": { - "fengyun_satid": {}, - "fengyun_virr": { - "composites": "composites/fengyun_virr.json.inc" - }, - "fengyun_erm": {}, - "fengyun_mwhs": {} - } - } - }, - "fengyun3_ab_ahrpt_old": { - "name": "FengYun-3 A/B AHRPT, old decoder", - "live": false, - "live_cfg": [ - [ - 1, - 0 - ] - ], - "frequencies": [ - 1704.5 - ], - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 2800000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.003, - "buffer_size": 8192 - } - }, - "cadu": { - "fengyun_ahrpt_decoder": { - "viterbi_outsync_after": 5, - "viterbi_ber_thresold": 0.170, - "soft_symbols": true, - "invert_second_viterbi": false - } - }, - "products": { - "fengyun_satid": {}, - "fengyun_virr": { - "composites": "composites/fengyun_virr.json.inc" - }, - "fengyun_erm": {}, - "fengyun_mwhs": {}, - "fengyun_mwts": {} - } - } - }, - "fengyun3_c_ahrpt": { - "name": "FengYun-3 C AHRPT ", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 1701.4 - ], - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 2600000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.003, - "buffer_size": 8192 - } - }, - "cadu": { - "new_fengyun_ahrpt_decoder": { - "viterbi_outsync_after": 5, - "viterbi_ber_thresold": 0.170, - "soft_symbols": true, - "invert_second_viterbi": false - } - }, - "products": { - "fengyun_satid": { - "scid_hint": 51 - }, - "fengyun_virr": { - "composites": "composites/fengyun_virr.json.inc" - }, - "fengyun_erm": {}, - "fengyun_mwhs2": {} - } - } - }, - "fengyun3_c_ahrpt_old": { - "name": "FengYun-3 C AHRPT, old decoder", - "live": false, - "live_cfg": [ - [ - 1, - 0 - ] - ], - "frequencies": [ - 1701.4 - ], - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 2600000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.003, - "buffer_size": 8192 - } - }, - "cadu": { - "fengyun_ahrpt_decoder": { - "viterbi_outsync_after": 5, - "viterbi_ber_thresold": 0.170, - "soft_symbols": true, - "invert_second_viterbi": false - } - }, - "products": { - "fengyun_satid": { - "scid_hint": 51 - }, - "fengyun_virr": { - "composites": "composites/fengyun_virr.json.inc" - }, - "fengyun_erm": {}, - "fengyun_mwhs2": {} - } - } - }, - "noaa_hrpt": { - "name": "NOAA HRPT", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 1707, - 1698, - 1702.5 - ], - "samplerate": 3e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "pm_demod": { - "symbolrate": 665400, - "agc_rate": 0.002e-3, - "pll_bw": 0.01, - "pll_max_offset": 0.5, - "rrc_alpha": 0.6, - "rrc_taps": 31, - "costas_bw": 0.005, - "clock_omega_relative_limit": 0.005, - "buffer_size": 8192 - } - }, - "frames": { - "noaa_hrpt_decoder": { - "deframer_thresold": 10 - } - }, - "products": { - "noaa_avhrr": { - "composites": "composites/noaa_avhrr.json.inc" - }, - "noaa_extractor": { - "gac_mode": false - }, - "noaa_hirs": { - "input_override": "noaa_hrpt.tip" - }, - "noaa_amsu": { - "input_override": "noaa_hrpt.aip" - }, - "noaa_mhs": { - "input_override": "noaa_hrpt.aip" - } - } - } - }, - "meteor_hrpt": { - "name": "METEOR HRPT", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 1700 - ], - "samplerate": 3e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "pm_demod": { - "symbolrate": 665400, - "agc_rate": 0.002e-3, - "pll_bw": 0.01, - "pll_max_offset": 0.5, - "rrc_alpha": 0.6, - "rrc_taps": 31, - "costas_bw": 0.005, - "clock_omega_relative_limit": 0.005, - "buffer_size": 8192 - } - }, - "cadu": { - "meteor_hrpt_decoder": {} - }, - "products": { - "meteor_msumr": { - "composites": "composites/meteor_msumr.json.inc" - }, - "meteor_mtvza": {} - } - } - }, - "saral_l_band": { - "name": "Saral L-Band", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 1698.4 - ], - "samplerate": 3e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 800000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.004, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "qpsk", - "cadu_size": 8192, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": true, - "nrzm": true, - "rs_i": 4, - "rs_type": "rs223" - } - }, - "products": { - "saral_argos": {} - } - } - }, - "angels_l_band": { - "name": "ANGELS L-Band", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ], - [ - 3, - 0 - ] - ], - "frequencies": [ - 1698.4 - ], - "samplerate": 3e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 400000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.004, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "qpsk", - "cadu_size": 8192, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": true, - "nrzm": true, - "rs_i": 4, - "rs_type": "rs223" - } - }, - "products": { - "angels_argos": {} - } - } - }, - "yunhai_ahrpt": { - "name": "Yunhai AHRPT - Encrypted", - "live": false, - "frequencies": [ - 1704 - ], - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 4000000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.002, - "buffer_size": 8192 - } - }, - "cadu": { - "new_fengyun_ahrpt_decoder": { - "viterbi_outsync_after": 5, - "viterbi_ber_thresold": 0.170, - "soft_symbols": true, - "invert_second_viterbi": false - } - } - } - }, - "noaa_gac": { - "name": "NOAA GAC", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 1702.5, - 1698.0, - 2247.5 - ], - "parameters": { - "backward": { - "type": "bool", - "value": false, - "name": "Backward GAC", - "description": "Over the US, NOAA satellites often transmit\nGAC in reverse order. This mode allows\ndecoding those backward replays properly." - } - }, - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 2.6616e6, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.004, - "buffer_size": 8192, - "post_costas_dc": true - } - }, - "frm": { - "noaa_gac_decoder": { - "backward": false - } - }, - "products": { - "noaa_avhrr": { - "composites": "composites/noaa_avhrr.json.inc", - "gac_mode": true - }, - "noaa_extractor": { - "gac_mode": true - }, - "noaa_hirs": { - "input_override": "noaa_gac.tip" - }, - "noaa_amsu": { - "input_override": "noaa_gac.aip" - }, - "noaa_mhs": { - "input_override": "noaa_gac.aip" - } - } - } - }, - "noaa_gac_backward": { - "name": "NOAA GAC - Backward playback", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 1702.5, - 1698.0, - 2247.5 - ], - "samplerate": 6e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 2.6616e6, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.004, - "buffer_size": 8192, - "post_costas_dc": true - } - }, - "frm": { - "noaa_gac_decoder": { - "backward": true - } - }, - "products": { - "noaa_avhrr": { - "composites": "composites/noaa_avhrr.json.inc", - "gac_mode": true - }, - "noaa_extractor": { - "gac_mode": true - }, - "noaa_hirs": { - "input_override": "noaa_gac_backward.tip" - }, - "noaa_amsu": { - "input_override": "noaa_gac_backward.aip" - }, - "noaa_mhs": { - "input_override": "noaa_gac_backward.aip" - } - } - } - } -} \ No newline at end of file diff --git a/pipelines/JPSS.json b/pipelines/JPSS.json new file mode 100644 index 000000000..2ed797ec6 --- /dev/null +++ b/pipelines/JPSS.json @@ -0,0 +1,91 @@ +{ + "npp_hrd": { + "name": "Suomi NPP / JPSS-1 HRD", + "live": false, + "frequencies": [], + "samplerate": 25e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 15000000, + "agc_rate": 0.0001, + "rrc_alpha": 0.7, + "rrc_taps": 31, + "costas_bw": 0.001, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "qpsk", + "cadu_size": 8192, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": true, + "nrzm": true, + "rs_i": 4, + "rs_type": "rs223" + } + }, + "products": { + "jpss_satid": { + "npp_mode": true + }, + "jpss_viirs": { + "npp_mode": true, + "composites": { + "RGB-I221": { + "channels": [ + 101, + 102 + ], + "expression": "ch102 * 4 - 0.2, ch102 * 4 - 0.2, ch101 * 4.4 - 0.2" + }, + "RGB-I321": { + "channels": [ + 101, + 102, + 103 + ], + "expression": "ch103 * 4 - 0.2, ch102 * 4 - 0.2, ch101 * 4 - 0.2" + }, + "RGB-(23)21": { + "channels": [ + 101, + 102, + 103 + ], + "expression": "(ch103 * 0.4 + ch102 * 0.6) * 4 - 0.2, ch102 * 4 - 0.2, ch101 * 4 - 0.2", + "corrected": true + }, + "RGB-M543": { + "channels": [ + 5, + 4, + 3 + ], + "expression": "ch5, ch4, ch3", + "equalize": true + }, + "I4-EQU": { + "channels": [ + 104 + ], + "expression": "ch104", + "equalize": true, + "normalize": true + } + } + }, + "jpss_atms": { + "npp_mode": true + }, + "jpss_omps": { + "npp_mode": true + } + } + } + } +} \ No newline at end of file diff --git a/pipelines/Jason-3.json b/pipelines/Jason-3.json new file mode 100644 index 000000000..0028cd125 --- /dev/null +++ b/pipelines/Jason-3.json @@ -0,0 +1,49 @@ +{ + "jason3_link": { + "name": "Jason-3 S-Band Link", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [], + "samplerate": 3e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 838000, + "agc_rate": 0.00001, + "rrc_alpha": 0.7, + "rrc_taps": 31, + "costas_bw": 0.005, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "qpsk", + "cadu_size": 10232, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": true, + "nrzm": true, + "rs_i": 5, + "rs_type": "rs239" + } + }, + "products": { + "jason3_poseidon": {}, + "jason3_amr2": {}, + "jason3_lpt": {} + } + } + } +} \ No newline at end of file diff --git a/pipelines/MetOp.json b/pipelines/MetOp.json new file mode 100644 index 000000000..bd95af66f --- /dev/null +++ b/pipelines/MetOp.json @@ -0,0 +1,77 @@ +{ + "metop_ahrpt": { + "name": "MetOp AHRPT", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 1701.3 + ], + "parameters": { + "samplerate": { + "value": 6e6 + } + }, + "samplerate": 6e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 2333333, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.003, + "buffer_size": 8192 + } + }, + "cadu": { + "metop_ahrpt_decoder": { + "viterbi_outsync_after": 10, + "viterbi_ber_thresold": 0.280 + } + }, + "products": { + "metop_instruments": {} + } + } + }, + "metop_dump": { + "name": "MetOp X-Band Dump", + "live": false, + "live_cfg": [], + "frequencies": [ + 7800 + ], + "samplerate": 45e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 35000000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.03, + "buffer_size": 8192 + } + }, + "cadu": { + "metop_dump_decoder": {} + }, + "products": { + "metop_instruments": {} + } + } + } +} \ No newline at end of file diff --git a/pipelines/VHF.json b/pipelines/Meteor-M.json similarity index 82% rename from pipelines/VHF.json rename to pipelines/Meteor-M.json index 7da2ee130..1c2e2c509 100644 --- a/pipelines/VHF.json +++ b/pipelines/Meteor-M.json @@ -1,16 +1,28 @@ { - "noaa_dsb": { - "name": "NOAA DSB", - "live": false, - "frequencies": [], - "samplerate": 0, + "meteor_hrpt": { + "name": "METEOR HRPT", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 1700 + ], + "samplerate": 3e6, "baseband_type": "i16", "work": { "baseband": {}, "soft": { "pm_demod": { - "symbolrate": 8320, - "agc_rate": 0.001, + "symbolrate": 665400, + "agc_rate": 0.002e-3, "pll_bw": 0.01, "pll_max_offset": 0.5, "rrc_alpha": 0.6, @@ -20,11 +32,14 @@ "buffer_size": 8192 } }, - "frames": { - "noaa_dsb_decoder": {} + "cadu": { + "meteor_hrpt_decoder": {} }, "products": { - "noaa_hirs": {} + "meteor_msumr": { + "composites": "composites/meteor_msumr.json.inc" + }, + "meteor_mtvza": {} } } }, diff --git a/pipelines/NOAA.json b/pipelines/NOAA.json new file mode 100644 index 000000000..5b13d67ff --- /dev/null +++ b/pipelines/NOAA.json @@ -0,0 +1,156 @@ +{ + "noaa_dsb": { + "name": "NOAA DSB", + "live": false, + "frequencies": [], + "samplerate": 0, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "pm_demod": { + "symbolrate": 8320, + "agc_rate": 0.001, + "pll_bw": 0.01, + "pll_max_offset": 0.5, + "rrc_alpha": 0.6, + "rrc_taps": 31, + "costas_bw": 0.005, + "clock_omega_relative_limit": 0.005, + "buffer_size": 8192 + } + }, + "frames": { + "noaa_dsb_decoder": {} + }, + "products": { + "noaa_hirs": {} + } + } + }, + "noaa_hrpt": { + "name": "NOAA HRPT", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 1707, + 1698, + 1702.5 + ], + "samplerate": 3e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "pm_demod": { + "symbolrate": 665400, + "agc_rate": 0.002e-3, + "pll_bw": 0.01, + "pll_max_offset": 0.5, + "rrc_alpha": 0.6, + "rrc_taps": 31, + "costas_bw": 0.005, + "clock_omega_relative_limit": 0.005, + "buffer_size": 8192 + } + }, + "frames": { + "noaa_hrpt_decoder": { + "deframer_thresold": 10 + } + }, + "products": { + "noaa_avhrr": { + "composites": "composites/noaa_avhrr.json.inc" + }, + "noaa_extractor": { + "gac_mode": false + }, + "noaa_hirs": { + "input_override": "noaa_hrpt.tip" + }, + "noaa_amsu": { + "input_override": "noaa_hrpt.aip" + }, + "noaa_mhs": { + "input_override": "noaa_hrpt.aip" + } + } + } + }, + "noaa_gac": { + "name": "NOAA GAC", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 1702.5, + 1698.0, + 2247.5 + ], + "parameters": { + "backward": { + "type": "bool", + "value": false, + "name": "Backward GAC", + "description": "Over the US, NOAA satellites often transmit\nGAC in reverse order. This mode allows\ndecoding those backward replays properly." + } + }, + "samplerate": 6e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 2.6616e6, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.004, + "buffer_size": 8192, + "post_costas_dc": true + } + }, + "frm": { + "noaa_gac_decoder": { + "backward": false + } + }, + "products": { + "noaa_avhrr": { + "composites": "composites/noaa_avhrr.json.inc", + "gac_mode": true + }, + "noaa_extractor": { + "gac_mode": true + }, + "noaa_hirs": { + "input_override": "noaa_gac.tip" + }, + "noaa_amsu": { + "input_override": "noaa_gac.aip" + }, + "noaa_mhs": { + "input_override": "noaa_gac.aip" + } + } + } + } +} \ No newline at end of file diff --git a/pipelines/Oceansat.json b/pipelines/Oceansat.json new file mode 100644 index 000000000..23fd60e88 --- /dev/null +++ b/pipelines/Oceansat.json @@ -0,0 +1,28 @@ +{ + "oceansat2_db": { + "name": "OceanSat-2 DB", + "live": false, + "frequencies": [], + "samplerate": 35e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 21226000, + "agc_rate": 0.00001, + "rrc_alpha": 0.8, + "rrc_taps": 31, + "costas_bw": 0.01, + "buffer_size": 8192 + } + }, + "frames": { + "oceansat2_db_decoder": {} + }, + "products": { + "oceansat_ocm": {} + } + } + } +} \ No newline at end of file diff --git a/pipelines/Others.json b/pipelines/Others.json new file mode 100644 index 000000000..089a396bc --- /dev/null +++ b/pipelines/Others.json @@ -0,0 +1,130 @@ +{ + "saral_l_band": { + "name": "Saral L-Band", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 1698.4 + ], + "samplerate": 3e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 800000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.004, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "qpsk", + "cadu_size": 8192, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": true, + "nrzm": true, + "rs_i": 4, + "rs_type": "rs223" + } + }, + "products": { + "saral_argos": {} + } + } + }, + "angels_l_band": { + "name": "ANGELS L-Band", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ], + [ + 3, + 0 + ] + ], + "frequencies": [ + 1698.4 + ], + "samplerate": 3e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 400000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.004, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "qpsk", + "cadu_size": 8192, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": true, + "nrzm": true, + "rs_i": 4, + "rs_type": "rs223" + } + }, + "products": { + "angels_argos": {} + } + } + }, + "yunhai_ahrpt": { + "name": "Yunhai AHRPT - Encrypted", + "live": false, + "frequencies": [ + 1704 + ], + "samplerate": 6e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 4000000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.002, + "buffer_size": 8192 + } + }, + "cadu": { + "new_fengyun_ahrpt_decoder": { + "viterbi_outsync_after": 5, + "viterbi_ber_thresold": 0.170, + "soft_symbols": true, + "invert_second_viterbi": false + } + } + } + } +} \ No newline at end of file diff --git a/pipelines/Proba.json b/pipelines/Proba.json new file mode 100644 index 000000000..5469c82a4 --- /dev/null +++ b/pipelines/Proba.json @@ -0,0 +1,227 @@ +{ + "proba1_dump": { + "name": "Proba-1 Dump", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 2235 + ], + "samplerate": 4e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 2000000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.004, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "bpsk_90", + "cadu_size": 10232, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": false, + "rs_i": 5, + "rs_type": "rs223" + } + }, + "products": { + "proba_chris": { + "composites_low": { + "RGB-080502": { + "channels": [ + 1, + 2 + ], + "expression": "(ch8-0.03)*3, (ch5-0.03)*2.7, (ch2-0.03)*3" + }, + "EVI-(vegetation)": { + "channels": [ + 1, + 2 + ], + "expression": "((ch19-ch8)/(ch19+6*ch8-7.5*ch2+1))*2" + }, + "EVI-141908-(vegetation)": { + "channels": [ + 1, + 2 + ], + "expression": "ch14 * 1.5, (ch19 + (ch19-ch8)*1.5/(ch19+6*ch8-7.5*ch2+1)) * 1.5, ch8* 1.5" + }, + "RGB-191908-(221)": { + "channels": [ + 1, + 2 + ], + "expression": "ch19*2, ch19*2, ch8*2" + }, + "EVI-(vegetation)-[chlorophyll]": { + "channels": [ + 1, + 2 + ], + "expression": "((ch15-ch8)/(ch15+6*ch8-7.5*ch2+1))*1.5" + }, + "EVI-101808-(vegetation)-[chlorophyll]": { + "channels": [ + 1, + 2 + ], + "expression": "ch10 * 1.5, ch18 + (ch15-ch8)/(ch15+6*ch8-7.5*ch2+1) * 1.5, ch8* 1.5" + }, + "RGB-151508-(221)-[chlorophyll]": { + "channels": [ + 1, + 2 + ], + "expression": "ch19*2, ch19*2, ch8*2" + }, + "RGB-120805-[water]": { + "channels": [ + 1, + 2 + ], + "expression": "(ch12-0.1)*4, (ch8-0.1)*4, (ch5-0.1)*4" + } + }, + "composites_all": { + "RGB-251607-(RGB)": { + "channels": [ + 1, + 2 + ], + "expression": "ch25 * 1.65, ch16 * 2.1, ch7 * 2" + }, + "RGB-464625-(221)": { + "channels": [ + 1, + 2 + ], + "expression": "ch46 * 2, ch46 * 2, ch25 * 2" + }, + "EVI-634625-(vegetation)": { + "channels": [ + 1, + 2 + ], + "expression": "ch63, ch46 + ((ch46-ch25)/(ch46+6*ch25-7.5*ch7+1)), ch25" + }, + "EVI-(vegetation)": { + "channels": [ + 1, + 2 + ], + "expression": "((ch46-ch25)/(ch46+6*ch25-7.5*ch7+1))*1.5" + } + } + }, + "proba_hrc": {} + } + } + }, + "proba2_dump": { + "name": "Proba-2 Dump", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 2235 + ], + "samplerate": 4e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 2000000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.004, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "bpsk_90", + "cadu_size": 10232, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": false, + "rs_i": 5, + "rs_type": "rs223" + } + }, + "products": { + "proba_swap": {} + } + } + }, + "probav_s_dump": { + "name": "Proba-V S-Band Dump", + "live": true, + "live_cfg": [ + [ + 1, + 0 + ], + [ + 2, + 0 + ] + ], + "frequencies": [ + 2235 + ], + "samplerate": 4e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 1919000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.004, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_conv_r2_concat_decoder": { + "constellation": "bpsk_90", + "cadu_size": 10232, + "viterbi_ber_thresold": 0.300, + "viterbi_outsync_after": 20, + "derandomize": true, + "rs_i": 5, + "rs_type": "rs223" + } + } + } + } +} \ No newline at end of file diff --git a/pipelines/S-Band.json b/pipelines/S-Band.json deleted file mode 100644 index 0615a430e..000000000 --- a/pipelines/S-Band.json +++ /dev/null @@ -1,495 +0,0 @@ -{ - "proba1_dump": { - "name": "Proba-1 Dump", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 2235 - ], - "samplerate": 4e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 2000000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.004, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "bpsk_90", - "cadu_size": 10232, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": false, - "rs_i": 5, - "rs_type": "rs223" - } - }, - "products": { - "proba_chris": { - "composites_low": { - "RGB-080502": { - "channels": [ - 1, - 2 - ], - "expression": "(ch8-0.03)*3, (ch5-0.03)*2.7, (ch2-0.03)*3" - }, - "EVI-(vegetation)": { - "channels": [ - 1, - 2 - ], - "expression": "((ch19-ch8)/(ch19+6*ch8-7.5*ch2+1))*2" - }, - "EVI-141908-(vegetation)": { - "channels": [ - 1, - 2 - ], - "expression": "ch14 * 1.5, (ch19 + (ch19-ch8)*1.5/(ch19+6*ch8-7.5*ch2+1)) * 1.5, ch8* 1.5" - }, - "RGB-191908-(221)": { - "channels": [ - 1, - 2 - ], - "expression": "ch19*2, ch19*2, ch8*2" - }, - "EVI-(vegetation)-[chlorophyll]": { - "channels": [ - 1, - 2 - ], - "expression": "((ch15-ch8)/(ch15+6*ch8-7.5*ch2+1))*1.5" - }, - "EVI-101808-(vegetation)-[chlorophyll]": { - "channels": [ - 1, - 2 - ], - "expression": "ch10 * 1.5, ch18 + (ch15-ch8)/(ch15+6*ch8-7.5*ch2+1) * 1.5, ch8* 1.5" - }, - "RGB-151508-(221)-[chlorophyll]": { - "channels": [ - 1, - 2 - ], - "expression": "ch19*2, ch19*2, ch8*2" - }, - "RGB-120805-[water]": { - "channels": [ - 1, - 2 - ], - "expression": "(ch12-0.1)*4, (ch8-0.1)*4, (ch5-0.1)*4" - } - }, - "composites_all": { - "RGB-251607-(RGB)": { - "channels": [ - 1, - 2 - ], - "expression": "ch25 * 1.65, ch16 * 2.1, ch7 * 2" - }, - "RGB-464625-(221)": { - "channels": [ - 1, - 2 - ], - "expression": "ch46 * 2, ch46 * 2, ch25 * 2" - }, - "EVI-634625-(vegetation)": { - "channels": [ - 1, - 2 - ], - "expression": "ch63, ch46 + ((ch46-ch25)/(ch46+6*ch25-7.5*ch7+1)), ch25" - }, - "EVI-(vegetation)": { - "channels": [ - 1, - 2 - ], - "expression": "((ch46-ch25)/(ch46+6*ch25-7.5*ch7+1))*1.5" - } - } - }, - "proba_hrc": {} - } - } - }, - "proba2_dump": { - "name": "Proba-2 Dump", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 2235 - ], - "samplerate": 4e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 2000000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.004, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "bpsk_90", - "cadu_size": 10232, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": false, - "rs_i": 5, - "rs_type": "rs223" - } - }, - "products": { - "proba_swap": {} - } - } - }, - "probav_s_dump": { - "name": "Proba-V S-Band Dump", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 2235 - ], - "samplerate": 4e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 1919000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.004, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "bpsk_90", - "cadu_size": 10232, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": true, - "rs_i": 5, - "rs_type": "rs223" - } - } - } - }, - "smap_s_link": { - "name": "SMAP S-Band Link", - "live": false, - "frequencies": [], - "samplerate": 3e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 590000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.04, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_simple_psk_decoder": { - "constellation": "bpsk", - "cadu_size": 10232, - "derandomize": true, - "nrzm": true, - "rs_i": 5, - "rs_type": "rs239" - } - } - } - }, - "jason3_link": { - "name": "Jason-3 S-Band Link", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [], - "samplerate": 3e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 838000, - "agc_rate": 0.00001, - "rrc_alpha": 0.7, - "rrc_taps": 31, - "costas_bw": 0.005, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "qpsk", - "cadu_size": 10232, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": true, - "nrzm": true, - "rs_i": 5, - "rs_type": "rs239" - } - }, - "products": { - "jason3_poseidon": {}, - "jason3_amr2": {}, - "jason3_lpt": {} - } - } - }, - "coriolis_db": { - "name": "Coriolis S-Band Tactical DB", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 2221.5 - ], - "samplerate": 4e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 512000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.004, - "buffer_size": 8192 - } - }, - "frm": { - "ccsds_conv_r2_concat_decoder": { - "ccsds": false, - "constellation": "bpsk", - "cadu_size": 8192, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": false, - "rs_i": 0, - "asm": "0x352ef853" - } - }, - "products": { - "coriolis_windsat": {} - } - } - }, - "cloudsat_link": { - "name": "CloudSat S-Band Link", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 2217.5 - ], - "samplerate": 4e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 1000000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.004, - "buffer_size": 8192 - } - }, - "frm": { - "ccsds_simple_psk_decoder": { - "ccsds": false, - "constellation": "bpsk", - "cadu_size": 3216, - "derandomize": false, - "nrzm": true, - "rs_i": 0, - "asm": "0x04b3e375" - } - }, - "products": { - "cloudsat_cpr": {} - } - } - }, - "grace_fo_link": { - "name": "Grace-FO Dump", - "live": false, - "frequencies": [], - "samplerate": 20e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "oqpsk_demod": { - "symbolrate": 1500000, - "agc_rate": 0.1, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.006, - "clock_gain_omega": 0.8, - "clock_mu": 0.9, - "clock_gain_mu": 0.037, - "clock_omega_relative_limit": 0.001, - "constellation_scale": 100, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_simple_psk_decoder": { - "constellation": "qpsk", - "cadu_size": 10232, - "nrzm": false, - "rs_i": 5, - "rs_type": "rs239" - } - } - } - }, - "cheops_link": { - "name": "CHEOPS S-Band Dump", - "live": false, - "frequencies": [], - "samplerate": 3e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "oqpsk_demod": { - "symbolrate": 1142000, - "agc_rate": 0.1, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.006, - "clock_gain_omega": 0.8, - "clock_mu": 0.9, - "clock_gain_mu": 0.037, - "clock_omega_relative_limit": 0.001, - "constellation_scale": 100, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_simple_psk_decoder": { - "constellation": "qpsk", - "cadu_size": 10232, - "oqpsk_delay": true, - "rs_i": 5, - "rs_type": "rs223" - } - } - } - }, - "timed_dump": { - "name": "TIMED S-Band Dump", - "live": false, - "frequencies": [], - "samplerate": 6e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 2.295e6, - "agc_rate": 0.1, - "rrc_alpha": 0.6, - "rrc_taps": 31, - "costas_bw": 0.006, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_simple_psk_decoder": { - "constellation": "qpsk", - "cadu_size": 9872, - "nrzm": true, - "qpsk_swap_iq": true, - "rs_i": 0, - "rs_type": "rs223" - } - } - } - } -} \ No newline at end of file diff --git a/pipelines/Rockets.json b/pipelines/SpaceX.json similarity index 100% rename from pipelines/Rockets.json rename to pipelines/SpaceX.json diff --git a/pipelines/Work-In-Progress.json b/pipelines/Work-In-Progress.json index 42d9daad3..fc784a980 100644 --- a/pipelines/Work-In-Progress.json +++ b/pipelines/Work-In-Progress.json @@ -260,5 +260,163 @@ "iris_dump_decoder": {} } } + }, + "smap_s_link": { + "name": "SMAP S-Band Link", + "live": false, + "frequencies": [], + "samplerate": 3e6, + "baseband_type": "i16", + "work": { + "baseband": {}, + "soft": { + "bpsk_demod": { + "symbolrate": 590000, + "agc_rate": 0.00001, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.04, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_simple_psk_decoder": { + "constellation": "bpsk", + "cadu_size": 10232, + "derandomize": true, + "nrzm": true, + "rs_i": 5, + "rs_type": "rs239" + } + } + } + }, + "cheops_link": { + "name": "CHEOPS S-Band Dump", + "live": false, + "frequencies": [], + "samplerate": 3e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "oqpsk_demod": { + "symbolrate": 1142000, + "agc_rate": 0.1, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.006, + "clock_gain_omega": 0.8, + "clock_mu": 0.9, + "clock_gain_mu": 0.037, + "clock_omega_relative_limit": 0.001, + "constellation_scale": 100, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_simple_psk_decoder": { + "constellation": "qpsk", + "cadu_size": 10232, + "oqpsk_delay": true, + "rs_i": 5, + "rs_type": "rs223" + } + } + } + }, + "timed_dump": { + "name": "TIMED S-Band Dump", + "live": false, + "frequencies": [], + "samplerate": 6e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 2.295e6, + "agc_rate": 0.1, + "rrc_alpha": 0.6, + "rrc_taps": 31, + "costas_bw": 0.006, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_simple_psk_decoder": { + "constellation": "qpsk", + "cadu_size": 9872, + "nrzm": true, + "qpsk_swap_iq": true, + "rs_i": 0, + "rs_type": "rs223" + } + } + } + }, + "grace_fo_link": { + "name": "Grace-FO Dump", + "live": false, + "frequencies": [], + "samplerate": 20e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "oqpsk_demod": { + "symbolrate": 1500000, + "agc_rate": 0.1, + "rrc_alpha": 0.5, + "rrc_taps": 31, + "costas_bw": 0.006, + "clock_gain_omega": 0.8, + "clock_mu": 0.9, + "clock_gain_mu": 0.037, + "clock_omega_relative_limit": 0.001, + "constellation_scale": 100, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_simple_psk_decoder": { + "constellation": "qpsk", + "cadu_size": 10232, + "nrzm": false, + "rs_i": 5, + "rs_type": "rs239" + } + } + } + }, + "cfosat1_dump": { + "name": "CFOSAT-1 X-Band Dump", + "live": false, + "live_cfg": [], + "frequencies": [], + "samplerate": 40e6, + "baseband_type": "w8", + "work": { + "baseband": {}, + "soft": { + "qpsk_demod": { + "symbolrate": 30000000, + "agc_rate": 0.00001, + "rrc_alpha": 0.35, + "rrc_taps": 31, + "costas_bw": 0.0189, + "buffer_size": 8192 + } + }, + "cadu": { + "ccsds_simple_psk_decoder": { + "constellation": "qpsk", + "cadu_size": 8192, + "nrzm": true, + "rs_i": 4, + "rs_type": "rs223" + } + } + } } } \ No newline at end of file diff --git a/pipelines/X-Band.json b/pipelines/X-Band.json deleted file mode 100644 index ed354fa86..000000000 --- a/pipelines/X-Band.json +++ /dev/null @@ -1,559 +0,0 @@ -{ - "fengyun3_abc_mpt": { - "name": "FengYun-3 A/B/C MPT", - "live": false, - "frequencies": [], - "samplerate": 30e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 18700000, - "agc_rate": 0.00001, - "rrc_alpha": 0.35, - "rrc_taps": 31, - "costas_bw": 0.0063, - "buffer_size": 8192 - } - }, - "cadu": { - "new_fengyun_mpt_decoder": { - "viterbi_outsync_after": 5, - "viterbi_ber_thresold": 0.170, - "soft_symbols": true - } - }, - "products": { - "fengyun_satid": {}, - "fengyun_mersi1": { - "correct_bowtie": true, - "composites": "composites/fengyun_mersi1.json.inc" - } - } - } - }, - "fengyun3_d_ahrpt": { - "name": "FengYun-3 D AHRPT", - "live": false, - "frequencies": [], - "samplerate": 45e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 30000000, - "agc_rate": 0.00001, - "rrc_alpha": 0.35, - "rrc_taps": 31, - "costas_bw": 0.0163, - "buffer_size": 8192 - } - }, - "cadu": { - "new_fengyun_ahrpt_decoder": { - "viterbi_outsync_after": 5, - "viterbi_ber_thresold": 0.310, - "soft_symbols": true, - "invert_second_viterbi": true - } - }, - "products": { - "fengyun_satid": { - "scid_hint": 52 - }, - "fengyun_mersi2": { - "correct_bowtie": true, - "composites": "composites/fengyun_mersi2.json.inc" - }, - "fengyun_mwts2": {}, - "fengyun_waai": {}, - "fengyun_mwri": {}, - "fengyun_mwhs2": {} - } - } - }, - "fengyun3_e_ahrpt": { - "name": "FengYun-3 E AHRPT", - "live": false, - "frequencies": [], - "samplerate": 45e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 38400000, - "agc_rate": 0.00001, - "rrc_alpha": 0.35, - "rrc_taps": 31, - "costas_bw": 0.0189, - "buffer_size": 8192 - } - }, - "cadu": { - "new_fengyun_ahrpt_decoder": { - "viterbi_outsync_after": 5, - "viterbi_ber_thresold": 0.170, - "soft_symbols": true, - "invert_second_viterbi": true - } - }, - "products": { - "fengyun_satid": { - "scid_hint": 56 - }, - "fengyun_mersill": { - "correct_bowtie": true, - "composites": "composites/fengyun_mersill.json.inc" - }, - "fengyun_xeuvi": {}, - "fengyun_windrad": {}, - "fengyun_mwts3": {}, - "fengyun_mwhs2": {} - } - } - }, - "aqua_db": { - "name": "Aqua DB", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 8160.0 - ], - "samplerate": 15e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "oqpsk_demod": { - "symbolrate": 7500000, - "agc_rate": 0.1, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.006, - "clock_gain_omega": 0.8, - "clock_mu": 0.9, - "clock_gain_mu": 0.037, - "clock_omega_relative_limit": 0.0001, - "dc_block": true, - "constellation_scale": 100, - "buffer_size": 8192 - } - }, - "cadu": { - "aqua_db_decoder": {} - }, - "products": { - "eos_instruments": { - "satellite": "aqua", - "modis_bowtie": true - } - } - } - }, - "terra_db": { - "name": "Terra DB", - "live": false, - "frequencies": [], - "samplerate": 45e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "terra_db_demod": { - "dc_block": false, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "bpsk_90", - "cadu_size": 8192, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": true, - "derand_after_rs": true, - "derand_start": 10, - "nrzm": true, - "rs_i": 4, - "rs_type": "rs223" - } - }, - "products": { - "eos_instruments": { - "satellite": "terra", - "modis_bowtie": true - } - } - } - }, - "npp_hrd": { - "name": "Suomi NPP / JPSS-1 HRD", - "live": false, - "frequencies": [], - "samplerate": 25e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 15000000, - "agc_rate": 0.0001, - "rrc_alpha": 0.7, - "rrc_taps": 31, - "costas_bw": 0.001, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_conv_r2_concat_decoder": { - "constellation": "qpsk", - "cadu_size": 8192, - "viterbi_ber_thresold": 0.300, - "viterbi_outsync_after": 20, - "derandomize": true, - "nrzm": true, - "rs_i": 4, - "rs_type": "rs223" - } - }, - "products": { - "jpss_satid": { - "npp_mode": true - }, - "jpss_viirs": { - "npp_mode": true, - "composites": { - "RGB-I221": { - "channels": [ - 101, - 102 - ], - "expression": "ch102 * 4 - 0.2, ch102 * 4 - 0.2, ch101 * 4.4 - 0.2" - }, - "RGB-I321": { - "channels": [ - 101, - 102, - 103 - ], - "expression": "ch103 * 4 - 0.2, ch102 * 4 - 0.2, ch101 * 4 - 0.2" - }, - "RGB-(23)21": { - "channels": [ - 101, - 102, - 103 - ], - "expression": "(ch103 * 0.4 + ch102 * 0.6) * 4 - 0.2, ch102 * 4 - 0.2, ch101 * 4 - 0.2", - "corrected": true - }, - "RGB-M543": { - "channels": [ - 5, - 4, - 3 - ], - "expression": "ch5, ch4, ch3", - "equalize": true - }, - "I4-EQU": { - "channels": [ - 104 - ], - "expression": "ch104", - "equalize": true, - "normalize": true - } - } - }, - "jpss_atms": { - "npp_mode": true - }, - "jpss_omps": { - "npp_mode": true - } - } - } - }, - "elektro_rdas": { - "name": "ELEKTRO-L RDAS", - "live": false, - "frequencies": [], - "samplerate": 45e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 30720000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.03, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_simple_psk_decoder": { - "constellation": "bpsk", - "cadu_size": 8192, - "derandomize": true, - "nrzm": true, - "rs_i": 0 - } - }, - "products": { - "elektro_arktika_msugs": {} - } - } - }, - "arktika_rdas": { - "name": "ARKTIKA-M RDAS", - "live": false, - "frequencies": [], - "samplerate": 45e6, - "baseband_type": "i16", - "work": { - "baseband": {}, - "soft": { - "bpsk_demod": { - "symbolrate": 30720000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.03, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_simple_psk_decoder": { - "constellation": "bpsk", - "cadu_size": 8192, - "derandomize": true, - "nrzm": true, - "rs_i": 0 - } - }, - "products": { - "elektro_arktika_msugs": {} - } - } - }, - "oceansat2_db": { - "name": "OceanSat-2 DB", - "live": false, - "frequencies": [], - "samplerate": 35e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 21226000, - "agc_rate": 0.00001, - "rrc_alpha": 0.8, - "rrc_taps": 31, - "costas_bw": 0.01, - "buffer_size": 8192 - } - }, - "frames": { - "oceansat2_db_decoder": {} - }, - "products": { - "oceansat_ocm": {} - } - } - }, - "fengyun3_abc_dpt": { - "name": "FengYun-3 A/B/C DPT", - "live": false, - "frequencies": [], - "samplerate": 65e6, - "baseband_type": "i8", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 62000000, - "agc_rate": 0.00001, - "rrc_alpha": 0.35, - "rrc_taps": 31, - "costas_bw": 0.0189, - "buffer_size": 8192 - } - }, - "cadu": { - "new_fengyun_ahrpt_decoder": { - "viterbi_outsync_after": 5, - "viterbi_ber_thresold": 0.170, - "soft_symbols": true, - "invert_second_viterbi": true - } - }, - "products": { - "fengyun_satid": {}, - "fengyun_mersi1": { - "correct_bowtie": true, - "composites": "composites/fengyun_mersi1.json.inc" - }, - "fengyun_virr": { - "composites": "composites/fengyun_virr.json.inc" - }, - "fengyun_erm": {}, - "fengyun_mwhs": {} - } - } - }, - "metop_dump": { - "name": "MetOp X-Band Dump", - "live": false, - "live_cfg": [], - "frequencies": [ - 7800 - ], - "samplerate": 45e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 35000000, - "agc_rate": 0.00001, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.03, - "buffer_size": 8192 - } - }, - "cadu": { - "metop_dump_decoder": {} - }, - "products": { - "metop_instruments": {} - } - } - }, - "aura_db": { - "name": "Aura DB", - "live": true, - "live_cfg": [ - [ - 1, - 0 - ], - [ - 2, - 0 - ] - ], - "frequencies": [ - 8160.0 - ], - "samplerate": 15e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "oqpsk_demod": { - "symbolrate": 7500000, - "agc_rate": 0.1, - "rrc_alpha": 0.5, - "rrc_taps": 31, - "costas_bw": 0.006, - "clock_gain_omega": 0.8, - "clock_mu": 0.9, - "clock_gain_mu": 0.037, - "clock_omega_relative_limit": 0.0001, - "dc_block": true, - "constellation_scale": 100, - "buffer_size": 8192 - } - }, - "cadu": { - "aqua_db_decoder": {} - }, - "products": { - "eos_instruments": { - "satellite": "aura", - "modis_bowtie": false - } - } - } - }, - "cfosat1_dump": { - "name": "CFOSAT-1 X-Band Dump", - "live": false, - "live_cfg": [], - "frequencies": [], - "samplerate": 40e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 30000000, - "agc_rate": 0.00001, - "rrc_alpha": 0.35, - "rrc_taps": 31, - "costas_bw": 0.0189, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_simple_psk_decoder": { - "constellation": "qpsk", - "cadu_size": 8192, - "nrzm": true, - "rs_i": 4, - "rs_type": "rs223" - } - } - } - }, - "cryosat_dump": { - "name": "Cryosat X-Band Dump", - "live": false, - "live_cfg": [], - "frequencies": [], - "samplerate": 60e6, - "baseband_type": "w8", - "work": { - "baseband": {}, - "soft": { - "qpsk_demod": { - "symbolrate": 50000000, - "agc_rate": 0.00001, - "rrc_alpha": 0.35, - "rrc_taps": 31, - "costas_bw": 0.0189, - "buffer_size": 8192 - } - }, - "cadu": { - "ccsds_simple_psk_decoder": { - "constellation": "qpsk", - "cadu_size": 10232, - "nrzm": true, - "rs_i": 5, - "rs_type": "rs229" - } - }, - "products": { - "cryosat_siral": {} - } - } - } -} \ No newline at end of file diff --git a/satdump_cfg.json b/satdump_cfg.json index 588760e1e..216dda31c 100644 --- a/satdump_cfg.json +++ b/satdump_cfg.json @@ -1,5 +1,7 @@ { + // Settings for the SatDump UI "user_interface": { + // Parameters shown in the default UI table, for everything "default_offline_parameters": { "baseband_format": { "type": "options", @@ -10,7 +12,8 @@ "u8", "s16", "f32" - ] + ], + "description": "The sample format of the recorded baseband.\nThis depends on the settings of your recording software,\nbut some common formats are s16 (SDR#, etc),\nf32 (GQRX), u8 (HDSDR), etc" }, "samplerate": { "type": "int", diff --git a/src-cli/main.cpp b/src-cli/main.cpp index a8d28bf86..f79d511ba 100644 --- a/src-cli/main.cpp +++ b/src-cli/main.cpp @@ -22,7 +22,7 @@ int main(int argc, char *argv[]) } // Init SatDump - initSatdump(); + satdump::initSatdump(); std::string downlink_pipeline = argv[1]; std::string input_level = argv[2]; @@ -45,7 +45,7 @@ int main(int argc, char *argv[]) std::filesystem::create_directories(output_file); // Get pipeline - std::optional pipeline = getPipelineFromName(downlink_pipeline); + std::optional pipeline = satdump::getPipelineFromName(downlink_pipeline); if (pipeline.has_value()) { diff --git a/src-core/common/utils.cpp b/src-core/common/utils.cpp index b5c3b3946..32ae1720f 100644 --- a/src-core/common/utils.cpp +++ b/src-core/common/utils.cpp @@ -45,4 +45,13 @@ size_t getFilesize(std::string filepath) std::size_t fileSize = file.tellg(); file.close(); return fileSize; +} + +bool isStringPresent(std::string searched, std::string keyword) +{ + std::transform(searched.begin(), searched.end(), searched.begin(), tolower); + std::transform(keyword.begin(), keyword.end(), keyword.begin(), tolower); + + auto found_it = searched.find(keyword, 0); + return found_it != std::string::npos; } \ No newline at end of file diff --git a/src-core/common/utils.h b/src-core/common/utils.h index 40c951fcd..4b6a5634c 100644 --- a/src-core/common/utils.h +++ b/src-core/common/utils.h @@ -87,5 +87,7 @@ inline bool getBit(T &data, int &bit) return (data >> bit) & 1; } +bool isStringPresent(std::string searched, std::string keyword); + // Return filesize size_t getFilesize(std::string filepath); \ No newline at end of file diff --git a/src-core/core/pipeline.cpp b/src-core/core/pipeline.cpp index d195e6b01..8326399c8 100644 --- a/src-core/core/pipeline.cpp +++ b/src-core/core/pipeline.cpp @@ -6,376 +6,362 @@ #include #include -SATDUMP_DLL std::vector pipelines; -SATDUMP_DLL std::vector pipeline_categories; - -void Pipeline::run(std::string input_file, - std::string output_directory, - nlohmann::json parameters, - std::string input_level, - bool ui, - std::shared_ptr>> uiCallList, - std::shared_ptr uiCallListMutex) +namespace satdump { - if (!std::filesystem::exists(input_file)) + SATDUMP_DLL std::vector pipelines; + + void Pipeline::run(std::string input_file, + std::string output_directory, + nlohmann::json parameters, + std::string input_level, + bool ui, + std::shared_ptr>> uiCallList, + std::shared_ptr uiCallListMutex) { - logger->error("Input file " + input_file + " does not exist!"); - return; - } - - logger->debug("Starting " + name); - - std::vector lastFiles; - - int currentStep = 0; - int stepC = 0; - bool foundLevel = false; - - /* - In most cases, all processing pipelines will start from - baseband, demodulate to some intermediate level and then - feed an actual decoder down to frames. - - Hence, in most cases, if the first and second module both - support streaming data from the first to the second, we - can skip this intermediate level and do both in parrallel. - - Here, we first test modules are compatible with this way - of doing things, then unless specifically disabled by the - user, proceed to run both in parralel saving up on processing - time. - */ - if (steps[1].modules.size() == 1 && - steps[2].modules.size() == 1 && - input_level == "baseband" && - parameters.count("disable_multi_modules") == 0) - { - logger->info("Checking the 2 first modules..."); - - PipelineModule module1 = steps[1].modules[0]; - PipelineModule module2 = steps[2].modules[0]; - - if (modules_registry.count(module1.module_name) <= 0 || modules_registry.count(module2.module_name) <= 0) - throw std::runtime_error("Module " + module1.module_name + " or " + module2.module_name + " is not registered. Cancelling pipeline."); - - nlohmann::json params1 = prepareParameters(module1.parameters, parameters); - nlohmann::json params2 = prepareParameters(module2.parameters, parameters); - - std::shared_ptr m1 = modules_registry[module1.module_name](module1.input_override == "" ? input_file : output_directory + "/" + module1.input_override, - output_directory + "/" + name, - params1); - std::shared_ptr m2 = modules_registry[module2.module_name](module2.input_override == "" ? input_file : output_directory + "/" + module2.input_override, - output_directory + "/" + name, - params2); - - std::vector m1_outputs = m1->getOutputTypes(); - std::vector m2_inputs = m2->getInputTypes(); - - bool m1_has_stream = std::find(m1_outputs.begin(), m1_outputs.end(), DATA_STREAM) != m1_outputs.end(); - bool m2_has_stream = std::find(m2_inputs.begin(), m2_inputs.end(), DATA_STREAM) != m2_inputs.end(); - - if (m1_has_stream && m2_has_stream) + if (!std::filesystem::exists(input_file)) { - logger->info("Both 2 first modules can be run at once!"); + logger->error("Input file " + input_file + " does not exist!"); + return; + } - m1->setInputType(DATA_FILE); - m1->setOutputType(DATA_STREAM); - m1->output_fifo = std::make_shared>(1000000); + logger->debug("Starting " + name); - m2->input_fifo = m1->output_fifo; - m2->setInputType(DATA_STREAM); - m2->setOutputType(DATA_FILE); - m2->input_active = true; + std::vector lastFiles; - m1->init(); - m2->init(); + int currentStep = 0; + int stepC = 0; + bool foundLevel = false; - if (ui) + /* + In most cases, all processing pipelines will start from + baseband, demodulate to some intermediate level and then + feed an actual decoder down to frames. + + Hence, in most cases, if the first and second module both + support streaming data from the first to the second, we + can skip this intermediate level and do both in parrallel. + + Here, we first test modules are compatible with this way + of doing things, then unless specifically disabled by the + user, proceed to run both in parralel saving up on processing + time. + */ + if (steps[1].modules.size() == 1 && + steps[2].modules.size() == 1 && + input_level == "baseband" && + parameters.count("disable_multi_modules") == 0) + { + logger->info("Checking the 2 first modules..."); + + PipelineModule module1 = steps[1].modules[0]; + PipelineModule module2 = steps[2].modules[0]; + + if (modules_registry.count(module1.module_name) <= 0 || modules_registry.count(module2.module_name) <= 0) + throw std::runtime_error("Module " + module1.module_name + " or " + module2.module_name + " is not registered. Cancelling pipeline."); + + nlohmann::json params1 = prepareParameters(module1.parameters, parameters); + nlohmann::json params2 = prepareParameters(module2.parameters, parameters); + + std::shared_ptr m1 = modules_registry[module1.module_name](module1.input_override == "" ? input_file : output_directory + "/" + module1.input_override, + output_directory + "/" + name, + params1); + std::shared_ptr m2 = modules_registry[module2.module_name](module2.input_override == "" ? input_file : output_directory + "/" + module2.input_override, + output_directory + "/" + name, + params2); + + std::vector m1_outputs = m1->getOutputTypes(); + std::vector m2_inputs = m2->getInputTypes(); + + bool m1_has_stream = std::find(m1_outputs.begin(), m1_outputs.end(), DATA_STREAM) != m1_outputs.end(); + bool m2_has_stream = std::find(m2_inputs.begin(), m2_inputs.end(), DATA_STREAM) != m2_inputs.end(); + + if (m1_has_stream && m2_has_stream) { - uiCallListMutex->lock(); - uiCallList->push_back(m1); - uiCallList->push_back(m2); - uiCallListMutex->unlock(); - } + logger->info("Both 2 first modules can be run at once!"); - std::thread module1_thread([m1]() - { + m1->setInputType(DATA_FILE); + m1->setOutputType(DATA_STREAM); + m1->output_fifo = std::make_shared>(1000000); + + m2->input_fifo = m1->output_fifo; + m2->setInputType(DATA_STREAM); + m2->setOutputType(DATA_FILE); + m2->input_active = true; + + m1->init(); + m2->init(); + + if (ui) + { + uiCallListMutex->lock(); + uiCallList->push_back(m1); + uiCallList->push_back(m2); + uiCallListMutex->unlock(); + } + + std::thread module1_thread([m1]() + { m1->process(); logger->info("MODULE 1 DONE"); }); - std::thread module2_thread([m2]() - { + std::thread module2_thread([m2]() + { m2->process(); logger->info("MODULE 2 DONE"); }); - if (module1_thread.joinable()) - module1_thread.join(); - m2->input_active = false; - m2->input_fifo->stopReader(); - m2->input_fifo->stopWriter(); - m2->stop(); - if (module2_thread.joinable()) - module2_thread.join(); + if (module1_thread.joinable()) + module1_thread.join(); + m2->input_active = false; + m2->input_fifo->stopReader(); + m2->input_fifo->stopWriter(); + m2->stop(); + if (module2_thread.joinable()) + module2_thread.join(); - if (ui) + if (ui) + { + uiCallListMutex->lock(); + uiCallList->clear(); + uiCallListMutex->unlock(); + } + + lastFiles = m2->getOutputs(); + currentStep += 2; + input_level = steps[2].level_name; + stepC++; + } + } + + for (; currentStep < (int)steps.size(); currentStep++) + { + PipelineStep &step = steps[currentStep]; + + if (!foundLevel) { - uiCallListMutex->lock(); - uiCallList->clear(); - uiCallListMutex->unlock(); + foundLevel = step.level_name == input_level; + logger->warn("Data is already at level " + step.level_name + ", skipping"); + continue; } - lastFiles = m2->getOutputs(); - currentStep += 2; - input_level = steps[2].level_name; + logger->warn("Processing data to level " + step.level_name); + + std::vector files; + + for (PipelineModule modStep : step.modules) + { + // Check module exists! + if (modules_registry.count(modStep.module_name) <= 0) + throw std::runtime_error("Module " + modStep.module_name + " is not registered. Cancelling pipeline."); + + nlohmann::json final_parameters = prepareParameters(modStep.parameters, parameters); + + std::shared_ptr module = modules_registry[modStep.module_name](modStep.input_override == "" ? (stepC == 0 ? input_file : lastFiles[0]) : output_directory + "/" + modStep.input_override, + output_directory + "/" + name, + final_parameters); + + module->setInputType(DATA_FILE); + module->setOutputType(DATA_FILE); + + module->init(); + + if (ui) + { + uiCallListMutex->lock(); + uiCallList->push_back(module); + uiCallListMutex->unlock(); + } + + module->process(); + + if (ui) + { + uiCallListMutex->lock(); + uiCallList->clear(); + uiCallListMutex->unlock(); + } + + std::vector newfiles = module->getOutputs(); + files.insert(files.end(), newfiles.begin(), newfiles.end()); + + module.reset(); + } + + lastFiles = files; stepC++; } } - for (; currentStep < (int)steps.size(); currentStep++) + nlohmann::json Pipeline::prepareParameters(nlohmann::json &module_params, nlohmann::json &pipeline_params) { - PipelineStep &step = steps[currentStep]; + nlohmann::json final_parameters = module_params; + for (const nlohmann::detail::iteration_proxy_value> ¶m : pipeline_params.items()) + if (final_parameters.count(param.key()) > 0) + ; // Do Nothing //final_parameters[param.first] = param.second; + else + final_parameters.emplace(param.key(), param.value()); - if (!foundLevel) - { - foundLevel = step.level_name == input_level; - logger->warn("Data is already at level " + step.level_name + ", skipping"); - continue; - } + logger->debug("Parameters :"); + for (const nlohmann::detail::iteration_proxy_value> ¶m : final_parameters.items()) + logger->debug(" - " + param.key() + " : " + param.value().dump()); - logger->warn("Processing data to level " + step.level_name); - - std::vector files; - - for (PipelineModule modStep : step.modules) - { - // Check module exists! - if (modules_registry.count(modStep.module_name) <= 0) - throw std::runtime_error("Module " + modStep.module_name + " is not registered. Cancelling pipeline."); - - nlohmann::json final_parameters = prepareParameters(modStep.parameters, parameters); - - std::shared_ptr module = modules_registry[modStep.module_name](modStep.input_override == "" ? (stepC == 0 ? input_file : lastFiles[0]) : output_directory + "/" + modStep.input_override, - output_directory + "/" + name, - final_parameters); - - module->setInputType(DATA_FILE); - module->setOutputType(DATA_FILE); - - module->init(); - - if (ui) - { - uiCallListMutex->lock(); - uiCallList->push_back(module); - uiCallListMutex->unlock(); - } - - module->process(); - - if (ui) - { - uiCallListMutex->lock(); - uiCallList->clear(); - uiCallListMutex->unlock(); - } - - std::vector newfiles = module->getOutputs(); - files.insert(files.end(), newfiles.begin(), newfiles.end()); - - module.reset(); - } - - lastFiles = files; - stepC++; + return final_parameters; } -} -nlohmann::json Pipeline::prepareParameters(nlohmann::json &module_params, nlohmann::json &pipeline_params) -{ - nlohmann::json final_parameters = module_params; - for (const nlohmann::detail::iteration_proxy_value> ¶m : pipeline_params.items()) - if (final_parameters.count(param.key()) > 0) - ; // Do Nothing //final_parameters[param.first] = param.second; - else - final_parameters.emplace(param.key(), param.value()); - - logger->debug("Parameters :"); - for (const nlohmann::detail::iteration_proxy_value> ¶m : final_parameters.items()) - logger->debug(" - " + param.key() + " : " + param.value().dump()); - - return final_parameters; -} - -void loadPipeline(std::string filepath, std::string category, std::vector &pipelines, std::map(std::string, std::string, nlohmann::json)>> &modules_registry) -{ - logger->info("Loading pipelines from file " + filepath); - - // Read file into a string - std::ifstream fileStream(filepath); - std::string pipelineString((std::istreambuf_iterator(fileStream)), - (std::istreambuf_iterator())); - fileStream.close(); - - // Replace "includes" + void loadPipeline(std::string filepath, std::string category, std::vector &pipelines, std::map(std::string, std::string, nlohmann::json)>> &modules_registry) { - std::map toReplace; - for (int i = 0; i < int(pipelineString.size() - sizeof(".json.inc")); i++) - { - std::string currentPos = pipelineString.substr(i, 9); + logger->info("Loading pipelines from file " + filepath); - if (currentPos == ".json.inc") + // Read file into a string + std::ifstream fileStream(filepath); + std::string pipelineString((std::istreambuf_iterator(fileStream)), + (std::istreambuf_iterator())); + fileStream.close(); + + // Replace "includes" + { + std::map toReplace; + for (int i = 0; i < int(pipelineString.size() - sizeof(".json.inc")); i++) { - int bracketPos = i; - for (int y = i; y >= 0; y--) + std::string currentPos = pipelineString.substr(i, 9); + + if (currentPos == ".json.inc") { - if (pipelineString[y] == '"') + int bracketPos = i; + for (int y = i; y >= 0; y--) { - bracketPos = y; - break; + if (pipelineString[y] == '"') + { + bracketPos = y; + break; + } + } + + std::string finalStr = pipelineString.substr(bracketPos, (i - bracketPos) + 10); + std::string filenameToLoad = finalStr.substr(1, finalStr.size() - 2); + std::string pathToLoad = std::filesystem::path(filepath).parent_path().string() + "/" + filenameToLoad; + + if (std::filesystem::exists(pathToLoad)) + { + std::ifstream fileStream(pathToLoad); + std::string includeString((std::istreambuf_iterator(fileStream)), + (std::istreambuf_iterator())); + fileStream.close(); + + toReplace.emplace(finalStr, includeString); + } + else + { + logger->error("Could not include " + pathToLoad + "!"); } } - - std::string finalStr = pipelineString.substr(bracketPos, (i - bracketPos) + 10); - std::string filenameToLoad = finalStr.substr(1, finalStr.size() - 2); - std::string pathToLoad = std::filesystem::path(filepath).parent_path().string() + "/" + filenameToLoad; - - if (std::filesystem::exists(pathToLoad)) - { - std::ifstream fileStream(pathToLoad); - std::string includeString((std::istreambuf_iterator(fileStream)), - (std::istreambuf_iterator())); - fileStream.close(); - - toReplace.emplace(finalStr, includeString); - } - else - { - logger->error("Could not include " + pathToLoad + "!"); - } } - } - for (std::pair replace : toReplace) - { - while (pipelineString.find(replace.first) != std::string::npos) - pipelineString.replace(pipelineString.find(replace.first), replace.first.size(), replace.second); - } - - // logger->info(pipelineString); - } - - // Parse it - nlohmann::ordered_json jsonObj = nlohmann::ordered_json::parse(pipelineString); - - for (nlohmann::detail::iteration_proxy_value> pipelineConfig : jsonObj.items()) - { - Pipeline newPipeline; - newPipeline.name = pipelineConfig.key(); - newPipeline.readable_name = pipelineConfig.value()["name"]; - newPipeline.live = pipelineConfig.value()["live"]; - if (newPipeline.live) - newPipeline.live_cfg = pipelineConfig.value()["live_cfg"].get>>(); - newPipeline.frequencies = pipelineConfig.value()["frequencies"].get>(); - newPipeline.default_samplerate = pipelineConfig.value()["samplerate"]; - newPipeline.default_baseband_type = pipelineConfig.value()["baseband_type"]; - newPipeline.category = category; - newPipeline.editable_parameters = pipelineConfig.value()["parameters"]; - // logger->info(newPipeline.name); - - bool hasAllModules = true; - - for (nlohmann::detail::iteration_proxy_value> pipelineStep : pipelineConfig.value()["work"].items()) - { - PipelineStep newStep; - newStep.level_name = pipelineStep.key(); - // logger->warn(newStep.level_name); - - for (nlohmann::detail::iteration_proxy_value> pipelineModule : pipelineStep.value().items()) + for (std::pair replace : toReplace) { - PipelineModule newModule; - newModule.module_name = pipelineModule.key(); - newModule.parameters = pipelineModule.value(); - - if (newModule.parameters.count("input_override") > 0) - newModule.input_override = newModule.parameters["input_override"]; - else - newModule.input_override = ""; - // logger->debug(newModule.module_name); - - if (modules_registry.count(newModule.module_name) <= 0 && hasAllModules) - { - logger->warn("Module " + newModule.module_name + " is not loaded. Skipping pipeline!"); - hasAllModules = false; - } - - newStep.modules.push_back(newModule); + while (pipelineString.find(replace.first) != std::string::npos) + pipelineString.replace(pipelineString.find(replace.first), replace.first.size(), replace.second); } - newPipeline.steps.push_back(newStep); + // logger->info(pipelineString); } - if (hasAllModules) - pipelines.push_back(newPipeline); - } -} + // Parse it + nlohmann::ordered_json jsonObj = nlohmann::ordered_json::parse(pipelineString); -void loadPipelines(std::string filepath, std::vector &pipelines, std::map(std::string, std::string, nlohmann::json)>> &modules_registry) -{ - logger->info("Loading pipelines from " + filepath); - - std::vector> pipelinesToLoad; - - std::filesystem::recursive_directory_iterator pipelinesIterator(filepath); - std::error_code iteratorError; - while (pipelinesIterator != std::filesystem::recursive_directory_iterator()) - { - if (!std::filesystem::is_directory(pipelinesIterator->path())) + for (nlohmann::detail::iteration_proxy_value> pipelineConfig : jsonObj.items()) { - if (pipelinesIterator->path().filename().string().find(".json") != std::string::npos) + Pipeline newPipeline; + newPipeline.name = pipelineConfig.key(); + newPipeline.readable_name = pipelineConfig.value()["name"]; + newPipeline.live = pipelineConfig.value()["live"]; + if (newPipeline.live) + newPipeline.live_cfg = pipelineConfig.value()["live_cfg"].get>>(); + newPipeline.frequencies = pipelineConfig.value()["frequencies"].get>(); + newPipeline.default_samplerate = pipelineConfig.value()["samplerate"]; + newPipeline.default_baseband_type = pipelineConfig.value()["baseband_type"]; + newPipeline.category = category; + newPipeline.editable_parameters = pipelineConfig.value()["parameters"]; + // logger->info(newPipeline.name); + + bool hasAllModules = true; + + for (nlohmann::detail::iteration_proxy_value> pipelineStep : pipelineConfig.value()["work"].items()) { - if (pipelinesIterator->path().string().find(".json.inc") == std::string::npos) + PipelineStep newStep; + newStep.level_name = pipelineStep.key(); + // logger->warn(newStep.level_name); + + for (nlohmann::detail::iteration_proxy_value> pipelineModule : pipelineStep.value().items()) { - logger->trace("Found pipeline file " + pipelinesIterator->path().string()); - pipelinesToLoad.push_back({pipelinesIterator->path().string(), pipelinesIterator->path().stem().string()}); + PipelineModule newModule; + newModule.module_name = pipelineModule.key(); + newModule.parameters = pipelineModule.value(); + + if (newModule.parameters.count("input_override") > 0) + newModule.input_override = newModule.parameters["input_override"]; + else + newModule.input_override = ""; + // logger->debug(newModule.module_name); + + if (modules_registry.count(newModule.module_name) <= 0 && hasAllModules) + { + logger->warn("Module " + newModule.module_name + " is not loaded. Skipping pipeline!"); + hasAllModules = false; + } + + newStep.modules.push_back(newModule); + } + + newPipeline.steps.push_back(newStep); + } + + if (hasAllModules) + pipelines.push_back(newPipeline); + } + } + + void loadPipelines(std::string filepath, std::vector &pipelines, std::map(std::string, std::string, nlohmann::json)>> &modules_registry) + { + logger->info("Loading pipelines from " + filepath); + + std::vector> pipelinesToLoad; + + std::filesystem::recursive_directory_iterator pipelinesIterator(filepath); + std::error_code iteratorError; + while (pipelinesIterator != std::filesystem::recursive_directory_iterator()) + { + if (!std::filesystem::is_directory(pipelinesIterator->path())) + { + if (pipelinesIterator->path().filename().string().find(".json") != std::string::npos) + { + if (pipelinesIterator->path().string().find(".json.inc") == std::string::npos) + { + logger->trace("Found pipeline file " + pipelinesIterator->path().string()); + pipelinesToLoad.push_back({pipelinesIterator->path().string(), pipelinesIterator->path().stem().string()}); + } } } + + pipelinesIterator.increment(iteratorError); + if (iteratorError) + logger->critical(iteratorError.message()); } - pipelinesIterator.increment(iteratorError); - if (iteratorError) - logger->critical(iteratorError.message()); + for (std::pair pipeline : pipelinesToLoad) + loadPipeline(pipeline.first, pipeline.second, pipelines, modules_registry); } - for (std::pair pipeline : pipelinesToLoad) + std::optional getPipelineFromName(std::string downlink_pipeline) { - loadPipeline(pipeline.first, pipeline.second, pipelines, modules_registry); - pipeline_categories.push_back(pipeline.second); + std::vector::iterator it = std::find_if(pipelines.begin(), + pipelines.end(), + [&downlink_pipeline](const Pipeline &e) + { + return e.name == downlink_pipeline; + }); + + if (it != pipelines.end()) + return std::optional(*it); + else + return std::optional(); } -} - -std::vector getPipelinesInCategory(std::string category) -{ - std::vector catPipelines; - std::copy_if(pipelines.begin(), pipelines.end(), std::back_inserter(catPipelines), [=](Pipeline p) - { return p.category == category; }); - return catPipelines; -} - -Pipeline getPipelineInCategoryFromId(std::string category, int id) -{ - return getPipelinesInCategory(category)[id]; -} - -std::optional getPipelineFromName(std::string downlink_pipeline) -{ - std::vector::iterator it = std::find_if(pipelines.begin(), - pipelines.end(), - [&downlink_pipeline](const Pipeline &e) - { - return e.name == downlink_pipeline; - }); - - if (it != pipelines.end()) - return std::optional(*it); - else - return std::optional(); } \ No newline at end of file diff --git a/src-core/core/pipeline.h b/src-core/core/pipeline.h index 691499bce..6c0b10af1 100644 --- a/src-core/core/pipeline.h +++ b/src-core/core/pipeline.h @@ -8,48 +8,48 @@ #include "nlohmann/json.hpp" #include -struct PipelineModule +namespace satdump { - std::string module_name; - nlohmann::json parameters; - std::string input_override; -}; + struct PipelineModule + { + std::string module_name; + nlohmann::json parameters; + std::string input_override; + }; -struct PipelineStep -{ - std::string level_name; - std::vector modules; -}; + struct PipelineStep + { + std::string level_name; + std::vector modules; + }; -struct Pipeline -{ - std::string name; - std::string readable_name; - std::string category; - bool live; - std::vector frequencies; - long default_samplerate; - std::string default_baseband_type; - std::vector> live_cfg; + struct Pipeline + { + std::string name; + std::string readable_name; + std::string category; + bool live; + std::vector frequencies; + long default_samplerate; + std::string default_baseband_type; + std::vector> live_cfg; - nlohmann::json editable_parameters; + nlohmann::json editable_parameters; - std::vector steps; - void run(std::string input_file, - std::string output_directory, - nlohmann::json parameters, - std::string input_level, - bool ui = false, - std::shared_ptr>> uiCallList = nullptr, - std::shared_ptr uiCallListMutex = nullptr); + std::vector steps; + void run(std::string input_file, + std::string output_directory, + nlohmann::json parameters, + std::string input_level, + bool ui = false, + std::shared_ptr>> uiCallList = nullptr, + std::shared_ptr uiCallListMutex = nullptr); - nlohmann::json prepareParameters(nlohmann::json &module_params, nlohmann::json &pipeline_params); -}; + nlohmann::json prepareParameters(nlohmann::json &module_params, nlohmann::json &pipeline_params); + }; -SATDUMP_DLL extern std::vector pipelines; -SATDUMP_DLL extern std::vector pipeline_categories; + SATDUMP_DLL extern std::vector pipelines; -void loadPipelines(std::string filepath, std::vector &pipelines = pipelines, std::map(std::string, std::string, nlohmann::json)>> &modules_registry = modules_registry); -std::vector getPipelinesInCategory(std::string category); -Pipeline getPipelineInCategoryFromId(std::string category, int id); -std::optional getPipelineFromName(std::string downlink_pipeline); \ No newline at end of file + void loadPipelines(std::string filepath, std::vector &pipelines = pipelines, std::map(std::string, std::string, nlohmann::json)>> &modules_registry = modules_registry); + std::optional getPipelineFromName(std::string downlink_pipeline); +} \ No newline at end of file diff --git a/src-core/init.cpp b/src-core/init.cpp index f9d4da66f..ba7825b94 100644 --- a/src-core/init.cpp +++ b/src-core/init.cpp @@ -8,37 +8,40 @@ #include "satdump_vars.h" #include "core/config.h" -void initSatdump() +namespace satdump { - logger->info(" _____ __ ____ "); - logger->info(" / ___/____ _/ /_/ __ \\__ ______ ___ ____ "); - logger->info(" \\__ \\/ __ `/ __/ / / / / / / __ `__ \\/ __ \\"); - logger->info(" ___/ / /_/ / /_/ /_/ / /_/ / / / / / / /_/ /"); - logger->info("/____/\\__,_/\\__/_____/\\__,_/_/ /_/ /_/ .___/ "); - logger->info(" /_/ "); - logger->info("Starting SatDump v" + (std::string)SATDUMP_VERSION); - logger->info(""); + void initSatdump() + { + logger->info(" _____ __ ____ "); + logger->info(" / ___/____ _/ /_/ __ \\__ ______ ___ ____ "); + logger->info(" \\__ \\/ __ `/ __/ / / / / / / __ `__ \\/ __ \\"); + logger->info(" ___/ / /_/ / /_/ /_/ / /_/ / / / / / / /_/ /"); + logger->info("/____/\\__,_/\\__/_____/\\__,_/_/ /_/ /_/ .___/ "); + logger->info(" /_/ "); + logger->info("Starting SatDump v" + (std::string)SATDUMP_VERSION); + logger->info(""); - satdump::config::loadConfig("satdump_cfg.json"); + config::loadConfig("satdump_cfg.json"); - loadPlugins(); + loadPlugins(); - registerModules(); + registerModules(); - // Load pipelines - if (std::filesystem::exists("pipelines") && std::filesystem::is_directory("pipelines")) - loadPipelines("pipelines"); - else - loadPipelines((std::string)RESOURCES_PATH + "pipelines"); + // Load pipelines + if (std::filesystem::exists("pipelines") && std::filesystem::is_directory("pipelines")) + loadPipelines("pipelines"); + else + loadPipelines((std::string)RESOURCES_PATH + "pipelines"); - // List them - logger->debug("Registered pipelines :"); - for (Pipeline &pipeline : pipelines) - logger->debug(" - " + pipeline.name); + // List them + logger->debug("Registered pipelines :"); + for (Pipeline &pipeline : pipelines) + logger->debug(" - " + pipeline.name); - // TLEs - // tle::loadTLEs(); + // TLEs + // tle::loadTLEs(); - // Let plugins know we started - satdump::eventBus->fire_event({}); -} + // Let plugins know we started + eventBus->fire_event({}); + } +} \ No newline at end of file diff --git a/src-core/init.h b/src-core/init.h index 6abed5b2b..0a43e198b 100644 --- a/src-core/init.h +++ b/src-core/init.h @@ -1,3 +1,6 @@ #pragma once -void initSatdump(); \ No newline at end of file +namespace satdump +{ + void initSatdump(); +} \ No newline at end of file diff --git a/src-core/live_pipeline.cpp b/src-core/live_pipeline.cpp index 959d9939f..a16d7698e 100644 --- a/src-core/live_pipeline.cpp +++ b/src-core/live_pipeline.cpp @@ -1,127 +1,127 @@ #include "live_pipeline.h" #include "logger.h" -LivePipeline::LivePipeline(Pipeline pipeline, - nlohmann::json parameters, - std::string output_dir) +namespace satdump { - logger->info("Starting live pipeline " + pipeline.readable_name); - - for (std::pair currentModule : pipeline.live_cfg) + LivePipeline::LivePipeline(Pipeline pipeline, + nlohmann::json parameters, + std::string output_dir) { - nlohmann::json final_parameters = pipeline.steps[currentModule.first].modules[currentModule.second].parameters; - for (const nlohmann::detail::iteration_proxy_value> ¶m : parameters.items()) - if (final_parameters.count(param.key()) > 0) - final_parameters[param.key()] = param.value(); - else - final_parameters.emplace(param.key(), param.value()); + logger->info("Starting live pipeline " + pipeline.readable_name); - logger->info("Module " + pipeline.steps[currentModule.first].modules[currentModule.second].module_name); - logger->debug("Parameters :"); - for (const nlohmann::detail::iteration_proxy_value> ¶m : final_parameters.items()) - logger->debug(" - " + param.key() + " : " + param.value().dump()); + for (std::pair currentModule : pipeline.live_cfg) + { + nlohmann::json final_parameters = pipeline.steps[currentModule.first].modules[currentModule.second].parameters; + for (const nlohmann::detail::iteration_proxy_value> ¶m : parameters.items()) + if (final_parameters.count(param.key()) > 0) + final_parameters[param.key()] = param.value(); + else + final_parameters.emplace(param.key(), param.value()); - modules.push_back(modules_registry[pipeline.steps[currentModule.first] - .modules[currentModule.second] - .module_name]("", output_dir + "/" + pipeline.name, final_parameters)); + logger->info("Module " + pipeline.steps[currentModule.first].modules[currentModule.second].module_name); + logger->debug("Parameters :"); + for (const nlohmann::detail::iteration_proxy_value> ¶m : final_parameters.items()) + logger->debug(" - " + param.key() + " : " + param.value().dump()); + + modules.push_back(modules_registry[pipeline.steps[currentModule.first] + .modules[currentModule.second] + .module_name]("", output_dir + "/" + pipeline.name, final_parameters)); + } } -} -LivePipeline::~LivePipeline() -{ -} - -void LivePipeline::start(std::shared_ptr> stream, ctpl::thread_pool &threadPool) -{ - // Init first module in the chain, always a demod... - modules[0]->input_stream = stream; - modules[0]->setInputType(DATA_DSP_STREAM); - modules[0]->setOutputType(modules.size() > 1 ? DATA_STREAM : DATA_FILE); - modules[0]->output_fifo = std::make_shared>(1000000); - modules[0]->init(); - modules[0]->input_active = true; - moduleFutures.push_back(threadPool.push([=](int) - { - logger->info("Start processing..."); - modules[0]->process(); - })); - - // Init whatever's in the middle - for (int i = 1; i < (int)modules.size() - 1; i++) + LivePipeline::~LivePipeline() { - modules[i]->input_fifo = modules[i - 1]->output_fifo; - modules[i]->output_fifo = std::make_shared>(1000000); - modules[i]->setInputType(DATA_STREAM); - modules[i]->setOutputType(DATA_STREAM); - modules[i]->init(); - modules[i]->input_active = true; + } + + void LivePipeline::start(std::shared_ptr> stream, ctpl::thread_pool &threadPool) + { + // Init first module in the chain, always a demod... + modules[0]->input_stream = stream; + modules[0]->setInputType(DATA_DSP_STREAM); + modules[0]->setOutputType(modules.size() > 1 ? DATA_STREAM : DATA_FILE); + modules[0]->output_fifo = std::make_shared>(1000000); + modules[0]->init(); + modules[0]->input_active = true; moduleFutures.push_back(threadPool.push([=](int) { + logger->info("Start processing..."); + modules[0]->process(); })); + + // Init whatever's in the middle + for (int i = 1; i < (int)modules.size() - 1; i++) + { + modules[i]->input_fifo = modules[i - 1]->output_fifo; + modules[i]->output_fifo = std::make_shared>(1000000); + modules[i]->setInputType(DATA_STREAM); + modules[i]->setOutputType(DATA_STREAM); + modules[i]->init(); + modules[i]->input_active = true; + moduleFutures.push_back(threadPool.push([=](int) + { logger->info("Start processing..."); - modules[i]->process(); - })); + modules[i]->process(); })); + } + + // Init the last module + if (modules.size() > 1) + { + int num = modules.size() - 1; + modules[num]->input_fifo = modules[num - 1]->output_fifo; + modules[num]->setInputType(DATA_STREAM); + modules[num]->setOutputType(DATA_FILE); + modules[num]->init(); + modules[num]->input_active = true; + moduleFutures.push_back(threadPool.push([=](int) + { + logger->info("Start processing..."); + modules[num]->process(); })); + } } - // Init the last module - if (modules.size() > 1) + void LivePipeline::stop() + { + logger->info("Stop processing"); + for (int i = 0; i < (int)modules.size(); i++) + { + std::shared_ptr mod = modules[i]; + + mod->input_active = false; + + if (mod->getInputType() == DATA_DSP_STREAM) + { + mod->input_stream->stopReader(); + mod->input_stream->stopWriter(); + } + else if (mod->getInputType() == DATA_STREAM) + { + mod->input_fifo->stopReader(); + mod->input_fifo->stopWriter(); + } + mod->stop(); + moduleFutures[i].get(); + } + } + + std::vector LivePipeline::getOutputFiles() { int num = modules.size() - 1; - modules[num]->input_fifo = modules[num - 1]->output_fifo; - modules[num]->setInputType(DATA_STREAM); - modules[num]->setOutputType(DATA_FILE); - modules[num]->init(); - modules[num]->input_active = true; - moduleFutures.push_back(threadPool.push([=](int) - { - logger->info("Start processing..."); - modules[num]->process(); - })); + return modules[num]->getOutputs(); } -} -void LivePipeline::stop() -{ - logger->info("Stop processing"); - for (int i = 0; i < (int)modules.size(); i++) + nlohmann::json LivePipeline::getModulesStats() { - std::shared_ptr mod = modules[i]; - - mod->input_active = false; - - if (mod->getInputType() == DATA_DSP_STREAM) + nlohmann::json stats; + for (std::shared_ptr mod : modules) { - mod->input_stream->stopReader(); - mod->input_stream->stopWriter(); + if (mod->module_stats.size() > 0) + stats[mod->getIDM()] = mod->module_stats; } - else if (mod->getInputType() == DATA_STREAM) - { - mod->input_fifo->stopReader(); - mod->input_fifo->stopWriter(); - } - mod->stop(); - moduleFutures[i].get(); + return stats; } -} -std::vector LivePipeline::getOutputFiles() -{ - int num = modules.size() - 1; - return modules[num]->getOutputs(); -} - -nlohmann::json LivePipeline::getModulesStats() -{ - nlohmann::json stats; - for (std::shared_ptr mod : modules) + void LivePipeline::drawUIs() { - if (mod->module_stats.size() > 0) - stats[mod->getIDM()] = mod->module_stats; + for (std::shared_ptr mod : modules) + mod->drawUI(true); } - return stats; -} - -void LivePipeline::drawUIs() -{ - for (std::shared_ptr mod : modules) - mod->drawUI(true); } \ No newline at end of file diff --git a/src-core/live_pipeline.h b/src-core/live_pipeline.h index dada66a6c..d4fcef98a 100644 --- a/src-core/live_pipeline.h +++ b/src-core/live_pipeline.h @@ -3,25 +3,28 @@ #include "core/pipeline.h" #include "libs/ctpl/ctpl_stl.h" -class LivePipeline +namespace satdump { -private: - nlohmann::json d_parameters; - std::vector> modules; - std::vector> moduleFutures; + class LivePipeline + { + private: + nlohmann::json d_parameters; + std::vector> modules; + std::vector> moduleFutures; -public: - LivePipeline(Pipeline pipeline, - nlohmann::json parameters, - std::string output_dir); - ~LivePipeline(); + public: + LivePipeline(Pipeline pipeline, + nlohmann::json parameters, + std::string output_dir); + ~LivePipeline(); - void start(std::shared_ptr> stream, ctpl::thread_pool &threadPool); - void stop(); + void start(std::shared_ptr> stream, ctpl::thread_pool &threadPool); + void stop(); - std::vector getOutputFiles(); + std::vector getOutputFiles(); - nlohmann::json getModulesStats(); + nlohmann::json getModulesStats(); - void drawUIs(); -}; \ No newline at end of file + void drawUIs(); + }; +} \ No newline at end of file diff --git a/src-interface/error.cpp b/src-interface/error.cpp new file mode 100644 index 000000000..1da08ba4a --- /dev/null +++ b/src-interface/error.cpp @@ -0,0 +1,29 @@ +#include "error.h" +#include "imgui/imgui.h" +#include + +namespace satdump +{ + namespace error + { + bool hasError = false; + std::string error_title; + std::string error_message; + + void set_error(std::string title, std::string description) + { + error_title = title; + error_message = description; + hasError = true; + } + + void render() + { + ImGui::Begin(error_title.c_str(), &hasError); + ImGui::TextColored(ImColor(255, 0, 0), "%s", error_message.c_str()); + if (ImGui::Button("Close")) + hasError = false; + ImGui::End(); + } + } +} \ No newline at end of file diff --git a/src-interface/error.h b/src-interface/error.h new file mode 100644 index 000000000..68ea329e9 --- /dev/null +++ b/src-interface/error.h @@ -0,0 +1,13 @@ +#pragma once + +#include + +namespace satdump +{ + namespace error + { + extern bool hasError; + void set_error(std::string title, std::string description); + void render(); + } +} \ No newline at end of file diff --git a/src-interface/global.cpp b/src-interface/global.cpp deleted file mode 100644 index 6fe86de38..000000000 --- a/src-interface/global.cpp +++ /dev/null @@ -1,6 +0,0 @@ -#include "global.h" - -std::shared_ptr>> uiCallList; -std::shared_ptr uiCallListMutex; - -ctpl::thread_pool processThreadPool(8); diff --git a/src-interface/global.h b/src-interface/global.h deleted file mode 100644 index 3288770e1..000000000 --- a/src-interface/global.h +++ /dev/null @@ -1,9 +0,0 @@ -#pragma once - -#include "libs/ctpl/ctpl_stl.h" -#include "core/module.h" - -extern std::shared_ptr>> uiCallList; -extern std::shared_ptr uiCallListMutex; - -extern ctpl::thread_pool processThreadPool; diff --git a/src-interface/main_ui.cpp b/src-interface/main_ui.cpp index 0966f2f7b..3b76dd6a0 100644 --- a/src-interface/main_ui.cpp +++ b/src-interface/main_ui.cpp @@ -1,62 +1,56 @@ #include "main_ui.h" -//#include "settingsui.h" -//#include "recorder/recorder_menu.h" -//#include "recorder/recorder.h" -//#include "credits/credits.h" -#include "global.h" #include "imgui/imgui_flags.h" #include "imgui/imgui.h" -//#include "offline/offline.h" #include "processing.h" -//#include "live/live.h" -//#include "live/live_run.h" -//#include "projection/projection.h" -//#include "projection/projection_menu.h" -//#include "projection/overlay.h" - -// satdump_ui_status satdumpUiStatus = MAIN_MENU; - #include "offline.h" +#include "error.h" -void initMainUI() +namespace satdump { - offline::setup(); -} - -bool isProcessing = false; - -void renderMainUI(int wwidth, int wheight) -{ - if (isProcessing) + void initMainUI() { - uiCallListMutex->lock(); - float winheight = uiCallList->size() > 0 ? wheight / uiCallList->size() : wheight; - float currentPos = 0; - for (std::shared_ptr module : *uiCallList) - { - ImGui::SetNextWindowPos({0, currentPos}); - currentPos += winheight; - ImGui::SetNextWindowSize({(float)wwidth, (float)winheight}); - module->drawUI(false); - } - uiCallListMutex->unlock(); + offline::setup(); } - else - { - ImGui::SetNextWindowPos({0, 0}); - ImGui::SetNextWindowSize({wwidth, wheight}); - ImGui::Begin("Main", __null, NOWINDOW_FLAGS | ImGuiWindowFlags_NoDecoration); - if (ImGui::BeginTabBar("Main TabBar", ImGuiTabBarFlags_None)) + std::string error_message; + bool isError_UI = false; + + void renderMainUI(int wwidth, int wheight) + { + if (processing::is_processing) { - if (ImGui::BeginTabItem("Offline processing")) + processing::ui_call_list_mutex->lock(); + float winheight = processing::ui_call_list->size() > 0 ? wheight / processing::ui_call_list->size() : wheight; + float currentPos = 0; + for (std::shared_ptr module : *processing::ui_call_list) { - offline::render(); - ImGui::EndTabItem(); + ImGui::SetNextWindowPos({0, currentPos}); + currentPos += winheight; + ImGui::SetNextWindowSize({(float)wwidth, (float)winheight}); + module->drawUI(false); } + processing::ui_call_list_mutex->unlock(); } - ImGui::EndTabBar(); + else + { + ImGui::SetNextWindowPos({0, 0}); + ImGui::SetNextWindowSize({wwidth, wheight}); + ImGui::Begin("Main", __null, NOWINDOW_FLAGS | ImGuiWindowFlags_NoDecoration); + if (ImGui::BeginTabBar("Main TabBar", ImGuiTabBarFlags_None)) + { + if (ImGui::BeginTabItem("Offline processing")) + { + offline::render(); + ImGui::EndTabItem(); + } + } + ImGui::EndTabBar(); + ImGui::End(); - ImGui::End(); + if (error::hasError) + error::render(); + } } + + ctpl::thread_pool ui_thread_pool(8); } \ No newline at end of file diff --git a/src-interface/main_ui.h b/src-interface/main_ui.h index 40da47c3a..20b438c0e 100644 --- a/src-interface/main_ui.h +++ b/src-interface/main_ui.h @@ -1,6 +1,15 @@ #pragma once -extern bool isProcessing; +#include +#include "libs/ctpl/ctpl_stl.h" -void initMainUI(); -void renderMainUI(int wwidth, int wheight); \ No newline at end of file +namespace satdump +{ + extern std::string error_message; + extern bool isError_UI; + + extern ctpl::thread_pool ui_thread_pool; + + void initMainUI(); + void renderMainUI(int wwidth, int wheight); +} \ No newline at end of file diff --git a/src-interface/offline.cpp b/src-interface/offline.cpp index 91937b228..82f87fc9c 100644 --- a/src-interface/offline.cpp +++ b/src-interface/offline.cpp @@ -1,45 +1,43 @@ #include "offline.h" #include "imgui/imgui.h" #include -#include #include "core/params.h" -#include "nlohmann/json_utils.h" #include "core/pipeline.h" #include "pfd/widget.h" #include "core/config.h" - #include "processing.h" -#include "global.h" +#include "main_ui.h" +#include "common/utils.h" -namespace offline +namespace satdump { - FileSelectWidget inputfileselect("Input File", "Select Input File"); - FileSelectWidget outputdirselect("Output Directory", "Select Output Directory", true); - - int pipelines_levels_select_id = -1; - std::string pipeline_levels_str; - - std::vector> parameters_ui; - std::vector> parameters_ui_pipeline; - - std::string pipelines_str; - int pipeline_id = 0; - - std::string error_message = ""; - - void setup() + namespace offline { - nlohmann::ordered_json params = satdump::config::cfg["user_interface"]["default_offline_parameters"]; + FileSelectWidget inputfileselect("Input File", "Select Input File"); + FileSelectWidget outputdirselect("Output Directory", "Select Output Directory", true); - for (nlohmann::detail::iteration_proxy_value> cfg : params.items()) - parameters_ui.push_back({cfg.key(), satdump::params::EditableParameter(cfg.value())}); - for (Pipeline pp : pipelines) - pipelines_str += pp.readable_name + '\0'; - } + int pipelines_levels_select_id = -1; + std::string pipeline_levels_str; - void render() - { - if (ImGui::Combo("##pipelineselection", &pipeline_id, pipelines_str.c_str()) || pipelines_levels_select_id == -1) + std::vector> parameters_ui; + std::vector> parameters_ui_pipeline; + + char pipeline_search_in[1000]; + int pipeline_id = 0; + + std::string error_message = ""; + + void setup() + { + nlohmann::ordered_json params = satdump::config::cfg["user_interface"]["default_offline_parameters"]; + + for (nlohmann::detail::iteration_proxy_value> cfg : params.items()) + parameters_ui.push_back({cfg.key(), satdump::params::EditableParameter(cfg.value())}); + + memset(pipeline_search_in, 0, 1000); + } + + void updateSelectedPipeline() { parameters_ui_pipeline.clear(); for (nlohmann::detail::iteration_proxy_value> cfg : pipelines[pipeline_id].editable_parameters.items()) @@ -66,65 +64,100 @@ namespace offline pipelines_levels_select_id = 0; } - ImGui::BeginTable("##pipelinesmainoptions", 2); - ImGui::TableSetupColumn("##pipelinesmaincolumn1", ImGuiTableColumnFlags_WidthFixed, 100); - ImGui::TableSetupColumn("##pipelinesmaincolumn2", ImGuiTableColumnFlags_WidthStretch, 100); - - ImGui::TableNextRow(); - ImGui::TableSetColumnIndex(0); - ImGui::Text("Input File"); - ImGui::TableSetColumnIndex(1); - inputfileselect.draw(); - - ImGui::TableNextRow(); - ImGui::TableSetColumnIndex(0); - ImGui::Text("Output Directory"); - ImGui::TableSetColumnIndex(1); - outputdirselect.draw(); - - ImGui::TableNextRow(); - ImGui::TableSetColumnIndex(0); - ImGui::Text("Input Level"); - ImGui::TableSetColumnIndex(1); - ImGui::Combo("##pipelinelevel", &pipelines_levels_select_id, pipeline_levels_str.c_str()); - ImGui::EndTable(); - - ImGui::Spacing(); - - if (ImGui::BeginTable("##pipelineoptions", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) + void render() { - for (std::pair &p : parameters_ui) - p.second.draw(); - for (std::pair &p : parameters_ui_pipeline) - p.second.draw(); + ImGui::InputTextWithHint("##pipelinesearchbox", "Search pipelines...", pipeline_search_in, 1000); + if (ImGui::BeginListBox("##pipelineslistbox")) + { + for (int n = 0; n < pipelines.size(); n++) + { + bool show = true; + std::string search_query(pipeline_search_in); + if (search_query.size() != 0) + show = isStringPresent(pipelines[n].readable_name, search_query); + + if (show) + { + const bool is_selected = (pipeline_id == n); + if (ImGui::Selectable(pipelines[n].readable_name.c_str(), is_selected)) + { + pipeline_id = n; + updateSelectedPipeline(); + } + + if (is_selected) + ImGui::SetItemDefaultFocus(); + } + } + ImGui::EndListBox(); + } + + ImGui::Spacing(); + ImGui::Separator(); + ImGui::Spacing(); + + ImGui::BeginTable("##pipelinesmainoptions", 2); + ImGui::TableSetupColumn("##pipelinesmaincolumn1", ImGuiTableColumnFlags_WidthFixed, 100); + ImGui::TableSetupColumn("##pipelinesmaincolumn2", ImGuiTableColumnFlags_WidthStretch, 100); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::Text("Input File"); + ImGui::TableSetColumnIndex(1); + inputfileselect.draw(); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::Text("Output Directory"); + ImGui::TableSetColumnIndex(1); + outputdirselect.draw(); + + ImGui::TableNextRow(); + ImGui::TableSetColumnIndex(0); + ImGui::Text("Input Level"); + ImGui::TableSetColumnIndex(1); + ImGui::Combo("##pipelinelevel", &pipelines_levels_select_id, pipeline_levels_str.c_str()); ImGui::EndTable(); - } - if (ImGui::Button("Start")) - { - nlohmann::json params2; - for (std::pair &p : parameters_ui) - params2[p.first] = p.second.getValue(); - for (std::pair &p : parameters_ui_pipeline) - params2[p.first] = p.second.getValue(); + ImGui::Spacing(); + // ImGui::Separator(); + ImGui::Spacing(); - if (!inputfileselect.file_valid) - error_message = "Input file is invalid!"; - else if (!outputdirselect.file_valid) - error_message = "Output folder is invalid!"; - else - processThreadPool.push([&, params2](int) - { processing::process(pipelines[pipeline_id].name, - pipelines[pipeline_id].steps[pipelines_levels_select_id].level_name, - inputfileselect.getPath(), - outputdirselect.getPath(), - params2); }); - } + if (ImGui::BeginTable("##pipelineoptions", 2, ImGuiTableFlags_Borders | ImGuiTableFlags_RowBg)) + { + for (std::pair &p : parameters_ui) + p.second.draw(); + for (std::pair &p : parameters_ui_pipeline) + p.second.draw(); + ImGui::EndTable(); + } - if (error_message.size() > 0) - { - ImGui::SameLine(); - ImGui::TextColored(ImColor(255, 0, 0), "%s", error_message.c_str()); + if (ImGui::Button("Start")) + { + nlohmann::json params2; + for (std::pair &p : parameters_ui) + params2[p.first] = p.second.getValue(); + for (std::pair &p : parameters_ui_pipeline) + params2[p.first] = p.second.getValue(); + + if (!inputfileselect.file_valid) + error_message = "Input file is invalid!"; + else if (!outputdirselect.file_valid) + error_message = "Output folder is invalid!"; + else + ui_thread_pool.push([&, params2](int) + { processing::process(pipelines[pipeline_id].name, + pipelines[pipeline_id].steps[pipelines_levels_select_id].level_name, + inputfileselect.getPath(), + outputdirselect.getPath(), + params2); }); + } + + if (error_message.size() > 0) + { + ImGui::SameLine(); + ImGui::TextColored(ImColor(255, 0, 0), "%s", error_message.c_str()); + } } } -}; \ No newline at end of file +} \ No newline at end of file diff --git a/src-interface/offline.h b/src-interface/offline.h index 7aaf3d878..abf80c8da 100644 --- a/src-interface/offline.h +++ b/src-interface/offline.h @@ -1,7 +1,10 @@ #pragma once -namespace offline +namespace satdump { - void setup(); - void render(); + namespace offline + { + void setup(); + void render(); + } } \ No newline at end of file diff --git a/src-interface/processing.cpp b/src-interface/processing.cpp index 40d14151c..cfad36174 100644 --- a/src-interface/processing.cpp +++ b/src-interface/processing.cpp @@ -1,38 +1,54 @@ -#include "logger.h" -#include "core/module.h" -#include "core/pipeline.h" #include -#include "nlohmann/json.hpp" -#include #include "processing.h" -#include "main_ui.h" +#include "logger.h" +#include "core/pipeline.h" +#include "error.h" -namespace processing +namespace satdump { - void process(std::string downlink_pipeline, - std::string input_level, - std::string input_file, - std::string output_file, - nlohmann::json parameters) + namespace processing { - isProcessing = true; + void process(std::string downlink_pipeline, + std::string input_level, + std::string input_file, + std::string output_file, + nlohmann::json parameters) + { + is_processing = true; - logger->info("Starting processing pipeline " + downlink_pipeline + "..."); - logger->debug("Input file (" + input_level + ") : " + input_file); - logger->debug("Output file : " + output_file); + logger->info("Starting processing pipeline " + downlink_pipeline + "..."); + logger->debug("Input file (" + input_level + ") : " + input_file); + logger->debug("Output file : " + output_file); - if (!std::filesystem::exists(output_file)) - std::filesystem::create_directories(output_file); + if (!std::filesystem::exists(output_file)) + std::filesystem::create_directories(output_file); - // Get pipeline - std::optional pipeline = getPipelineFromName(downlink_pipeline); + // Get pipeline + std::optional pipeline = getPipelineFromName(downlink_pipeline); - if (pipeline.has_value()) - pipeline.value().run(input_file, output_file, parameters, input_level, true, uiCallList, uiCallListMutex); - else - logger->critical("Pipeline " + downlink_pipeline + " does not exist!"); + if (pipeline.has_value()) + { + try + { + pipeline.value().run(input_file, output_file, parameters, input_level); + } + catch (std::exception &e) + { + logger->error("Fatal error running pipeline : " + std::string(e.what())); + error::set_error("Pipeline Error", e.what()); + is_processing = false; + return; + } + } + else + logger->critical("Pipeline " + downlink_pipeline + " does not exist!"); - logger->info("Done! Goodbye"); - isProcessing = false; + logger->info("Done! Goodbye"); + is_processing = false; + } + + std::shared_ptr>> ui_call_list = std::make_shared>>(); + std::shared_ptr ui_call_list_mutex = std::make_shared(); + bool is_processing = false; } } \ No newline at end of file diff --git a/src-interface/processing.h b/src-interface/processing.h index b52b8039f..f95c43eae 100644 --- a/src-interface/processing.h +++ b/src-interface/processing.h @@ -3,16 +3,19 @@ #include #include #include "core/module.h" -#include "pipeline.h" -extern std::shared_ptr>> uiCallList; -extern std::shared_ptr uiCallListMutex; - -namespace processing +namespace satdump { - void process(std::string downlink_pipeline, - std::string input_level, - std::string input_file, - std::string output_file, - nlohmann::json parameters); + namespace processing + { + extern std::shared_ptr>> ui_call_list; + extern std::shared_ptr ui_call_list_mutex; + extern bool is_processing; + + void process(std::string downlink_pipeline, + std::string input_level, + std::string input_file, + std::string output_file, + nlohmann::json parameters); + } } \ No newline at end of file diff --git a/src-ui/main.cpp b/src-ui/main.cpp index 5f4f4d14d..80137f727 100644 --- a/src-ui/main.cpp +++ b/src-ui/main.cpp @@ -5,7 +5,6 @@ #include #include #include "imgui/imgui_flags.h" -#include "global.h" #include "init.h" #include "processing.h" #include @@ -27,10 +26,6 @@ void bindImageTextureFunctions(); int main(int argc, char *argv[]) { bindImageTextureFunctions(); - - uiCallList = std::make_shared>>(); - uiCallListMutex = std::make_shared(); - initLogger(); if (argc < 5) // Check overall command @@ -41,10 +36,10 @@ int main(int argc, char *argv[]) return 1; } else - isProcessing = true; + satdump::processing::is_processing = true; // Init SatDump - initSatdump(); + satdump::initSatdump(); std::string downlink_pipeline = argv[1]; std::string input_level = argv[2]; @@ -58,7 +53,7 @@ int main(int argc, char *argv[]) // exit(0); // Init UI - initMainUI(); + satdump::initMainUI(); // Setup window glfwSetErrorCallback(glfw_error_callback); @@ -122,9 +117,9 @@ int main(int argc, char *argv[]) style::setDarkStyle((std::string)RESOURCES_PATH); } - if (isProcessing) - processThreadPool.push([&](int) - { processing::process(downlink_pipeline, input_level, input_file, output_file, parameters); }); + if (satdump::processing::is_processing) + satdump::ui_thread_pool.push([&](int) + { satdump::processing::process(downlink_pipeline, input_level, input_file, output_file, parameters); }); // Main loop while (!glfwWindowShouldClose(window)) @@ -140,7 +135,7 @@ int main(int argc, char *argv[]) glfwGetWindowSize(window, &wwidth, &wheight); // User rendering - renderMainUI(wwidth, wheight); + satdump::renderMainUI(wwidth, wheight); // Rendering ImGui::Render(); @@ -171,19 +166,19 @@ int main(int argc, char *argv[]) logger->info("UI Exit"); // If we're doing live processing, we want this to kill all threads quickly. Hence don't call destructors - if (isProcessing) + if (satdump::processing::is_processing) #ifdef __APPLE__ exit(0); #else quick_exit(0); #endif - processThreadPool.stop(); + satdump::ui_thread_pool.stop(); - for (int i = 0; i < processThreadPool.size(); i++) + for (int i = 0; i < satdump::ui_thread_pool.size(); i++) { - if (processThreadPool.get_thread(i).joinable()) - processThreadPool.get_thread(i).join(); + if (satdump::ui_thread_pool.get_thread(i).joinable()) + satdump::ui_thread_pool.get_thread(i).join(); } logger->info("Exiting!");