{"id":146956,"name":"goestools","description":"Tools to work with signals and files from GOES satellites.","url":"https://github.com/pietern/goestools","last_synced_at":"2026-04-30T09:00:46.301Z","repository":{"id":37927498,"uuid":"102387147","full_name":"pietern/goestools","owner":"pietern","description":"Tools to work with signals and files from GOES satellites","archived":false,"fork":false,"pushed_at":"2024-09-03T22:15:52.000Z","size":11605,"stargazers_count":418,"open_issues_count":54,"forks_count":95,"subscribers_count":33,"default_branch":"main","last_synced_at":"2026-04-24T06:07:30.198Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"https://pietern.github.io/goestools/","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-2-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pietern.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-09-04T17:45:59.000Z","updated_at":"2026-04-03T13:20:06.000Z","dependencies_parsed_at":"2023-01-21T12:34:04.782Z","dependency_job_id":"1ec9d863-c618-47be-b1d9-f65c841b29cc","html_url":"https://github.com/pietern/goestools","commit_stats":{"total_commits":394,"total_committers":10,"mean_commits":39.4,"dds":"0.048223350253807085","last_synced_commit":"80ece1a7ab8a93fb5dfa50d47387ae7c4a8f2a73"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/pietern/goestools","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pietern%2Fgoestools","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pietern%2Fgoestools/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pietern%2Fgoestools/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pietern%2Fgoestools/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pietern","download_url":"https://codeload.github.com/pietern/goestools/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pietern%2Fgoestools/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32459420,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T22:27:22.272Z","status":"online","status_checked_at":"2026-04-30T02:00:05.929Z","response_time":57,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"owner":{"login":"pietern","name":"Pieter Noordhuis","uuid":"9845","kind":"user","description":"","email":"","website":"http://twitter.com/pnoordhuis","location":null,"twitter":null,"company":null,"icon_url":"https://avatars.githubusercontent.com/u/9845?v=4","repositories_count":49,"last_synced_at":"2023-08-22T05:41:36.919Z","metadata":{"has_sponsors_listing":false},"html_url":"https://github.com/pietern","funding_links":[],"total_stars":null,"followers":null,"following":null,"created_at":"2022-11-07T20:10:20.559Z","updated_at":"2023-08-22T05:41:37.498Z","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pietern","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pietern/repositories"},"packages":[],"commits":{"id":1452593,"full_name":"pietern/goestools","default_branch":"main","total_commits":394,"total_committers":10,"total_bot_commits":0,"total_bot_committers":0,"mean_commits":39.4,"dds":0.048223350253807085,"past_year_total_commits":0,"past_year_total_committers":0,"past_year_total_bot_commits":0,"past_year_total_bot_committers":0,"past_year_mean_commits":0.0,"past_year_dds":0.0,"last_synced_at":"2026-04-28T08:01:14.330Z","last_synced_commit":"80ece1a7ab8a93fb5dfa50d47387ae7c4a8f2a73","created_at":"2023-12-05T11:25:14.001Z","updated_at":"2026-04-28T08:01:05.840Z","committers":[{"name":"Pieter Noordhuis","email":"pcnoordhuis@gmail.com","login":"pietern","count":375},{"name":"Scott K Logan","email":"logans@cottsay.net","login":"cottsay","count":8},{"name":"Andrew Hobgood","email":"33164785+ahobgood","login":"ahobgood","count":3},{"name":"Andrew Chin","email":"achin@eminence32.net","login":"eminence","count":2},{"name":"ghulands","email":"ghulands@me.com","login":"ghulands","count":1},{"name":"Jim Minter","email":"jim-minter","login":"jim-minter","count":1},{"name":"Ed Lafargue","email":"ed@wizkers.io","login":"elafargue","count":1},{"name":"Carl","email":"47005123+creinemann","login":"creinemann","count":1},{"name":"AlCutter","email":"al-github@9600.org","login":"AlCutter","count":1},{"name":"whiten01se","email":"github@laleli.lu","login":null,"count":1}],"past_year_committers":[],"commits_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories/pietern%2Fgoestools/commits","host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-04-30T00:00:07.427Z","repositories_count":6223657,"commits_count":899623383,"contributors_count":34896060,"owners_count":1147661,"icon_url":"https://github.com/github.png","host_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://commits.ecosyste.ms/api/v1/hosts/GitHub/repositories"}},"issues_stats":{"full_name":"pietern/goestools","html_url":"https://github.com/pietern/goestools","last_synced_at":"2026-04-03T05:01:45.249Z","status":null,"issues_count":68,"pull_requests_count":55,"avg_time_to_close_issue":18108113.657894738,"avg_time_to_close_pull_request":22816471.684210528,"issues_closed_count":38,"pull_requests_closed_count":38,"pull_request_authors_count":21,"issue_authors_count":46,"avg_comments_per_issue":3.7205882352941178,"avg_comments_per_pull_request":1.2363636363636363,"merged_pull_requests_count":22,"bot_issues_count":0,"bot_pull_requests_count":2,"past_year_issues_count":2,"past_year_pull_requests_count":7,"past_year_avg_time_to_close_issue":454.0,"past_year_avg_time_to_close_pull_request":648.0,"past_year_issues_closed_count":1,"past_year_pull_requests_closed_count":4,"past_year_pull_request_authors_count":3,"past_year_issue_authors_count":2,"past_year_avg_comments_per_issue":0.5,"past_year_avg_comments_per_pull_request":0.2857142857142857,"past_year_bot_issues_count":0,"past_year_bot_pull_requests_count":0,"past_year_merged_pull_requests_count":0,"created_at":"2023-12-05T11:25:42.524Z","updated_at":"2026-04-03T05:01:45.250Z","repository_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/pietern%2Fgoestools","issues_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories/pietern%2Fgoestools/issues","issue_labels_count":{"enhancement":2},"pull_request_labels_count":{"dependencies":2},"issue_author_associations_count":{"NONE":59,"CONTRIBUTOR":5,"OWNER":4},"pull_request_author_associations_count":{"NONE":24,"OWNER":16,"CONTRIBUTOR":15},"issue_authors":{"Mopar44084":8,"pietern":4,"nmoon88":3,"nigelvh":3,"robman501a":3,"kizmau":2,"Hellmanx":2,"NeutroniumDev":2,"gojimmypi":2,"creinemann":2,"kidshare":2,"Saberhawk09":1,"ghulands":1,"jpitz":1,"jpcopela":1,"wwoofbum":1,"reykowski":1,"hemna":1,"eoco":1,"bab5871":1,"MaxPastushkov":1,"cswanson420":1,"KiwiInNZ":1,"nationsem":1,"btashton":1,"rpdale":1,"loudelatorre":1,"dive76":1,"launchd":1,"jhgrazier":1,"cosmopotamian":1,"Boosted09Foci":1,"MikeNeilson":1,"zeke800":1,"RyokoAsakura":1,"pumatrax":1,"datatechnician63":1,"GreenCobalt":1,"WakeUpWolfgang":1,"Jcwscience":1,"ZL1LAC":1,"Mambo430":1,"funtime1818":1,"christheradioguy":1,"RyLeeRyno":1,"TS440S":1},"pull_request_authors":{"pietern":16,"cottsay":9,"codyswanson4":4,"jim-minter":4,"jonny-zapto":2,"tmbates12":2,"dependabot[bot]":2,"nbkhwjm":2,"parzivail":2,"spinomaly":1,"darshanbaralvw":1,"creinemann":1,"MikeNeilson":1,"jason-costello":1,"JVital2013":1,"nqbit":1,"ZL1LAC":1,"codient":1,"twcutter":1,"paultag":1,"gojimmypi":1},"host":{"name":"GitHub","url":"https://github.com","kind":"github","last_synced_at":"2026-04-03T00:00:08.051Z","repositories_count":14067026,"issues_count":34444339,"pull_requests_count":112534233,"authors_count":11220461,"icon_url":"https://github.com/github.png","host_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/repositories","owners_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/owners","authors_url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors"},"past_year_issue_labels_count":{},"past_year_pull_request_labels_count":{},"past_year_issue_author_associations_count":{"NONE":2},"past_year_pull_request_author_associations_count":{"NONE":7},"past_year_issue_authors":{"jhgrazier":1,"Mambo430":1},"past_year_pull_request_authors":{"codyswanson4":4,"jonny-zapto":2,"paultag":1},"maintainers":[{"login":"pietern","count":20,"url":"https://issues.ecosyste.ms/api/v1/hosts/GitHub/authors/pietern"}],"active_maintainers":[]},"events":{"total":{"PullRequestEvent":6,"ForkEvent":12,"IssuesEvent":4,"WatchEvent":29,"IssueCommentEvent":6},"last_year":{"PullRequestEvent":1,"ForkEvent":2,"IssuesEvent":3,"WatchEvent":13,"IssueCommentEvent":4}},"keywords":[],"dependencies":[{"ecosystem":"pypi","filepath":"docs/requirements.txt","sha":null,"kind":"manifest","created_at":"2022-08-25T21:10:52.545Z","updated_at":"2022-08-25T21:10:52.545Z","repository_link":"https://github.com/pietern/goestools/blob/main/docs/requirements.txt","dependencies":[{"id":2730865652,"package_name":"sphinx","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":2730865653,"package_name":"sphinx-autobuild","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":2730865654,"package_name":"sphinx_rtd_theme","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false},{"id":2730865655,"package_name":"pygments-github-lexers","ecosystem":"pypi","requirements":"*","direct":true,"kind":"runtime","optional":false}]},{"ecosystem":"actions","filepath":".github/workflows/build.yml","sha":null,"kind":"manifest","created_at":"2023-01-21T12:34:04.703Z","updated_at":"2023-01-21T12:34:04.703Z","repository_link":"https://github.com/pietern/goestools/blob/main/.github/workflows/build.yml","dependencies":[{"id":7078430337,"package_name":"actions/checkout","ecosystem":"actions","requirements":"v3","direct":true,"kind":"composite","optional":false}]},{"ecosystem":"actions","filepath":".github/workflows/docs.yml","sha":null,"kind":"manifest","created_at":"2023-01-21T12:34:04.734Z","updated_at":"2023-01-21T12:34:04.734Z","repository_link":"https://github.com/pietern/goestools/blob/main/.github/workflows/docs.yml","dependencies":[{"id":7078430341,"package_name":"actions/checkout","ecosystem":"actions","requirements":"v3","direct":true,"kind":"composite","optional":false},{"id":7078430342,"package_name":"actions/setup-python","ecosystem":"actions","requirements":"v4","direct":true,"kind":"composite","optional":false},{"id":7078430343,"package_name":"actions/upload-artifact","ecosystem":"actions","requirements":"v3","direct":true,"kind":"composite","optional":false},{"id":7078430344,"package_name":"actions/download-artifact","ecosystem":"actions","requirements":"v3","direct":true,"kind":"composite","optional":false}]},{"ecosystem":"docker","filepath":"docker/ubuntu/Dockerfile","sha":null,"kind":"manifest","created_at":"2023-01-21T12:34:04.758Z","updated_at":"2023-01-21T12:34:04.758Z","repository_link":"https://github.com/pietern/goestools/blob/main/docker/ubuntu/Dockerfile","dependencies":[{"id":7078430346,"package_name":"ubuntu","ecosystem":"docker","requirements":"${version}","direct":true,"kind":"build","optional":false}]}],"score":8.4595640785796,"created_at":"2023-12-05T11:25:09.638Z","updated_at":"2026-04-30T09:00:46.310Z","avatar_url":"https://github.com/pietern.png","language":"C++","category":"Sustainable Development","sub_category":"Environmental Satellites","monthly_downloads":0,"total_dependent_repos":0,"total_dependent_packages":0,"readme":"# goestools\n\nTools to work with signals and files from GOES satellites.\n\n* **goesrecv**: Demodulate and decode signal into packet stream.\n* **goeslrit**: Assemble LRIT files from packet stream.\n* **goesproc**: Process LRIT files into plain files and images.\n\nI started writing this to learn about things involved in the GOES\ncommunication pipeline and in the process learn more about space\ncommunication standards. Everything is written in C++ to strike a\nbalance between usability (no need for yet another hash table in C)\nand performance. ~~Eventually it would be nice to run the entire RX\npipeline on a little ARM board.~~ The entire RX pipeline can run on a\nRaspberry Pi 3.\n\n## Requirements\n\nSystem dependencies:\n\n* CMake\n* C++14 compiler\n* OpenCV 2 (for image processing in goesproc)\n* zlib (for EMWIN decompression)\n\nBundled dependencies:\n\n* libcorrect (currently a fork with CMake related fixes)\n* libaec\n\n## Build\n\n``` shell\ngit clone https://github.com/pietern/goestools\ncd goestools\nmkdir -p build\ncd build\ncmake ../ -DCMAKE_INSTALL_PREFIX=/usr/local\nls ./src/goesdec ./src/goesproc\n```\n\n## Usage\n\n### goesrecv\n\nAs of February 2018 goesrecv only runs ARM processors with NEON\nextensions (such as the Raspberry Pi 3). Stay tuned for compilation\ninstructions...\n\n### goeslrit\n\n\u003e If you're interested in post-processed data (images, text files)\n\u003e then you can ignore `goeslrit` and only use `goesproc`.\n\nThis tool can be used to turn a stream of packets into LRIT files.\nLRIT files can then be used by goesproc (or other tools, such as to\ngenerate usable images and text files, or for debugging purposes.\n\nIt can either read packets from files to process recorded data, or\nsubscribe to `goesrecv` process to work with live data.\n\nTo make it write LRIT files to disk, you have to specify the category\nof files you are interested in. Run `goeslrit --help` for a list of\nfiltering options. To make it write **ALL** LRIT files it seems, run\n`goeslrit` with the `--all` option.\n\n#### Reading packets from files\n\nThe files must be specified in chronological order because they are\nread in order. Packets for a single LRIT file can span multiple packet\nfiles, so if they are not specified in chronological order some LRIT\nfiles will be dropped. Specifying a file glob in bash expands to an\nalphabetically sorted list of file names that match the pattern.\n\nExample with files:\n\n``` shell\n$ goeslrit --images /path/to/packets/packets-2018-02-28T*\nReading: /path/to/packets/packets-2018-02-28T00:00:00Z.raw\nWriting: OR_ABI-L2-CMIPM1-M3C02_G16_s20180582358300_e20180582358358_c20180582358429.lrit (4004087 bytes)\nWriting: OR_ABI-L2-CMIPM2-M3C07_G16_s20180590000000_e20180590000071_c20180590000108.lrit (254551 bytes)\n...\n```\n\n#### Reading packets from a publisher\n\nIf `goesrecv` is running somewhere on your network, `goeslrit` can be\nconfigured to subscribe to its packet publisher to process live data.\nThis is done with the `--subscribe` argument and it can take any valid\nnanomsg address. Often this will be a TCP address\n(`tcp://\u003cip\u003e:\u003cport\u003e`, also see [nn_tcp(7)][nn_tcp]), but if you happen\nto run `goesrecv` on the same machine as `goeslrit` you can also use\nthe IPC transport mechanism (`ipc://path/to/socket`, also see\n[nn_ipc(7)][nn_ipc]).\n\n[nn_tcp]: http://nanomsg.org/v1.1.2/nn_tcp.html\n[nn_ipc]: http://nanomsg.org/v1.1.2/nn_ipc.html\n\nExample with publisher:\n\n``` shell\n$ goeslrit --images --subscribe tcp://1.2.3.4:5005\nWriting: OR_ABI-L2-CMIPM1-M3C02_G16_s20180591958303_e20180591958360_c20180591958427.lrit (4004087 bytes)\nWriting: OR_ABI-L2-CMIPM2-M3C07_G16_s20180592000003_e20180592000073_c20180592000110.lrit (254551 bytes)\n...\n```\n\n### goesproc\n\n```\nUsage: goesproc [OPTIONS] [path...]\nProcess stream of packets (VCDUs) or list of LRIT files.\n\nOptions:\n  -c, --config PATH          Path to configuration file\n  -m, --mode [packet|lrit]   Process stream of VCDU packets\n                             or pre-assembled LRIT files\n      --help                 Show this help\n\nIf mode is set to packet, goesproc reads VCDU packets from the\nspecified path(s). To process real time data you can setup a pipe from\nthe decoder into goesproc (e.g. use /dev/stdin as path argument).\nTo process recorded data you can specify a list of files that contain\nVCDU packets in chronological order.\n\nIf mode is set to lrit, goesproc finds all LRIT files in the specified\npaths and processes them sequentially. You can specify a mix of files\nand directories. Directory arguments expand into the files they\ncontain that match the glob '*.lrit*'. The complete list of LRIT files\nis sorted according to their time stamp header prior to processing it.\n```\n\nAn example goesproc configuration file can be found at\n[./etc/goesproc.conf](etc/goesproc.conf).\n\nFor example, with the following configuration file:\n\n``` toml\n[[handler]]\ntype = \"image\"\nproduct = \"goes15\"\nregion = \"fd\"\nchannels = [ \"VS\" ]\ncrop = [ -2373, 2371, -1357, 1347 ]\nfilename = \"GOES15_%r_%c_%t\"\n```\n\nRunning goesproc against a directory with GOES-15 LRIT files:\n\n``` shell\n$ goesproc --config example.conf --mode lrit ./out/images/goes15/fd\nWriting ./GOES15_FD_VS_20170820-210600.png\nWriting ./GOES15_FD_VS_20170821-000600.png\nWriting ./GOES15_FD_VS_20170821-030600.png\nWriting ./GOES15_FD_VS_20170821-060600.png\nWriting ./GOES15_FD_VS_20170821-090600.png\nWriting ./GOES15_FD_VS_20170821-120600.png\nWriting ./GOES15_FD_VS_20170821-150600.png\nWriting ./GOES15_FD_VS_20170821-180600.png\n...\n```\n\nYou can now use these image files however you like. For example, to\nproduce a GIF from 8 consecutive full disk images, you can use the\nfollowing ImageMagick commands:\n\n``` shell\nmogrify -resize '640x480\u003e' *.png\nconvert -loop 0 -delay 50 *.png GOES15_FD_VS_20170821.gif\n```\n\n![GOES15_FD_VS_20170821.gif](./images/GOES15_FD_VS_20170821.gif)\n\n## Resources\n\nBecause HRIT is similar to LRIT at a higher baud rate, documentation for\nLRIT is also relevant for HRIT. The documents below used to be hosted\nby NOAA until ~2020. They're mirrored here for posterity (thanks @gojimmypi;\nsee https://github.com/pietern/goestools/pull/102).\n\n* [LRIT Receiver Specification](./docs/files/3_LRIT_Receiver-specs.pdf)\n* [LRIT Transmitter Specification](./docs/files/4_LRIT_Transmitter-specs.pdf)\n* [LRIT Mission Specific Data](./docs/files/5_LRIT_Mission-data.pdf)\n\nAlso, these blog series:\n\n* https://web.archive.org/web/20150426214432/http://www.acasper.org/2011/10/24/goes-satellite-decoding/\n* http://www.teske.net.br/lucas/2016/10/goes-satellite-hunt-part-1-antenna-system/\n\n### Reed-Solomon\n\nFrom the LRIT receiver specs:\n\n\u003e The LRIT dissemination service is a Grade-2 service; therefore, the\n\u003e transmission of user data will be error controlled using\n\u003e Reed-Solomon coding as an outer code. The used Reed-Solomon code is\n\u003e (255,223) with an interleaving of I = 4.\n\nData must be transformed from Berlekamp's dual basis representation to\nconventional representation before we can run the Reed-Solomon\nalgorithm provided by libcorrect.\n\nPlease refer to [CCSDS 101.0-B-6][CCSDS101.0-B-6] (Recommendation For\nSpace Data System Standards: Telemetry Channel Coding) to read more\nabout the Reed-Solomon specifics for this application, the dual basis\nrepresentation, and how to transform data between conventional\nrepresentation and dual basis representation.\n\n[CCSDS101.0-B-6]: https://public.ccsds.org/Pubs/101x0b6s.pdf\n\n## Acknowledgments\n\nThanks to [@lukasteske](https://twitter.com/lucasteske) for building\nan open source demodulator and decoder (see [Open Satellite\nProject][OSP]). I used his code to verify my antenna system and as\nreference to cross check between the LRIT spec and his implementation.\n\n[OSP]: https://github.com/opensatelliteproject\n","funding_links":[],"readme_doi_urls":[],"works":{},"citation_counts":{},"total_citations":0,"keywords_from_contributors":[],"project_url":"https://ost.ecosyste.ms/api/v1/projects/146956","html_url":"https://ost.ecosyste.ms/projects/146956"}