{"id":2353,"date":"2021-08-22T06:34:51","date_gmt":"2021-08-22T04:34:51","guid":{"rendered":"https:\/\/aerospaceresearch.net\/?p=2353"},"modified":"2021-08-22T06:46:47","modified_gmt":"2021-08-22T04:46:47","slug":"gsoc2021-findsatbyrf-center-of-satellite-signal-in-the-frequency-domain","status":"publish","type":"post","link":"https:\/\/aerospaceresearch.net\/?p=2353","title":{"rendered":"[GSoC2021: findsatbyrf] Center of satellite signal in the frequency domain"},"content":{"rendered":"\n<h1 class=\"wp-block-heading\"><strong>Overview:<\/strong><\/h1>\n\n\n\n<p>This program finds the center in the frequency domain of a signal by time.<\/p>\n\n\n\n<p>This is the link to its <a rel=\"noreferrer noopener\" href=\"https:\/\/github.com\/aerospaceresearch\/findsatbyrf\" target=\"_blank\">Github repository<\/a>. There, you can also see the markdown (.md) file that contains the same content as this blog.<\/p>\n\n\n\n<p>Every major work on this repository is done by <a href=\"https:\/\/www.linkedin.com\/in\/tranhuubinhminh\/\" target=\"_blank\" rel=\"noreferrer noopener\">Binh-Minh Tran-Huu<\/a> under instructions and monitor from mentor <a href=\"https:\/\/www.linkedin.com\/in\/andreas-hornig-253b2818\/\" target=\"_blank\" rel=\"noreferrer noopener\">Andreas Hornig<\/a> of <a href=\"https:\/\/aerospaceresearch.net\/\" target=\"_blank\" rel=\"noreferrer noopener\">Aerospaceresearch.net<\/a> as <a href=\"https:\/\/summerofcode.withgoogle.com\/projects\/#5393798554714112\" target=\"_blank\" rel=\"noreferrer noopener\">a project participated in Google Summer of Code 2021<\/a>.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>Usage:<\/strong><\/h1>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 1: Prepare your wave file (.wav\/.dat) and a json file containing the information about your signal<\/strong><\/h2>\n\n\n\n<p>Example of the json file:<\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow\">\n<pre class=\"wp-block-code\"><code>{\n    \"signal\": {\n        \"name\": \"NOAA-18\",\n        \"type\": \"NOAA\",\n        \"center_frequency\": 137.5e6,\n        \"time_of_record\": \"2021-06-04T20:17:05.00Z\"\n    },\n    \"tle\": {\n        \"line_1\": \"1 28654U 05018A   21156.90071532  .00000084  00000-0  69961-4 0  9998\",\n        \"line_2\": \"2 28654  98.9942 221.7189 0013368 317.9158  42.0985 14.12611611826810\"\n    },\n    \"station\": {\n        \"name\": \"Stuttgart\",\n        \"longitude\": 9.2356,\n        \"latitude\": 48.777,\n        \"altitude\": 200.0\n    },\n    \"default_channel\": &#91;\n        {\n            \"frequency\": 137912968,\n            \"bandwidth\": 60e3\n        }\n    ]   \n}<\/code><\/pre>\n\n\n\n<p><\/p>\n<\/div><\/div>\n\n\n\n<p>Where:<\/p>\n\n\n\n<ul><li>&#8222;signal&#8220; object contains information about the signal file, such as name, center frequency and time of record. For now, there is only &#8222;type&#8220;: &#8222;NOAA&#8220; is supported, if the signal is not NOAA then you should put &#8222;type&#8220;: null or simply remove that key.<\/li><li>&#8222;tle&#8220; object contains the two lines of the &#8222;two-line element&#8220; file of the satellite that the signal comes from.<\/li><li>&#8222;station&#8220; object contains the information of the station, such as name, longitude (degree), latitude (degree) and altitude (meter).<\/li><li>&#8222;default_channel&#8220; object contains a <em>list<\/em> of channels that will be analyzed in case there is no channel input from the command line. <em>It could handle more than one channel, you can always add more channels into that list<\/em>, for example:<\/li><\/ul>\n\n\n\n<pre class=\"wp-block-code\"><code>\"default_channel\": &#91;\n        {\n            \"frequency\": 400574.350e3,\n            \"bandwidth\": 20e3\n        },\n        {\n            \"frequency\": 400575.0e3,\n            \"bandwidth\": 20e3\n        }\n    ]<\/code><\/pre>\n\n\n\n<p><em><strong>NOTE:<\/strong><\/em> &#8222;tle&#8220; and &#8222;station&#8220; objects are only needed if you intend to use signal center frequency prediction based on TLE, &#8222;default_channel&#8220; object is only needed if you want to not put channel information into the command line, otherwise you can remove them.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Step 2: Run the program from the Command-Line Interface (CLI)<\/strong><\/h2>\n\n\n\n<p>Simply use Python to run the file main.py with the following arguments:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>&#91;-h] \n-f wav\/dat_file \n-i json_file \n&#91;-o name_of_output_file] \n&#91;-ch1 frequency_in_Hz] &#91;-bw1 frequency_in_Hz]\n&#91;-ch2 frequency_in_Hz] &#91;-bw2 frequency_in_Hz]\n&#91;-bw3 frequency_in_Hz] &#91;-ch3 frequency_in_Hz]\n&#91;-ch4 frequency_in_Hz] &#91;-bw4 frequency_in_Hz] \n&#91;-step time_in_second]\n&#91;-sen frequency_in_Hz] \n&#91;-filter float]\n&#91;-tle] \n&#91;-begin time_in_second]\n&#91;-end time_in_second]\n<\/code><\/pre>\n\n\n\n<p>With:<\/p>\n\n\n\n<ul><li>-h: to show help.<\/li><li>-f (required): to input the directory of the wave file.<\/li><li>-i (required): to input the json signal information file.<\/li><li>-o: directory and name without extension of the wanted output file, defaults to &#8222;.\/output&#8220;.<\/li><li>-ch0, -ch1, -ch2, -ch3: to input the frequencies (in Hz) of up to 4 channels to be analyzed. Will overwrite the &#8222;default_channel&#8220; provided by the json file.<\/li><li>-bw0, -bw1, -bw2, -bw3: to input the bandwidth (in Hz) of up to 4 channels to be analyzed. Will overwrite the &#8222;default_channel&#8220; provided by the json file.<\/li><li>-step: to input the length in time (in second) of each time interval, defaults to 1.<\/li><li>-sen: to input the sensitivity, which is the width of each bin in the frequency kernel (in Hz) after FFT, defaults to 1.<\/li><li>-filter: to input the strength of the noise filter as ratio to 1. For example, filter of 1.1 means the noise filter is 1.1 times as strong, or 10% stronger than the default filter, defaults to 1.<\/li><li>-begin: to input the time of begin of the segment to be analyzed, defaults to 1.<\/li><li>-end: to input the time of end of the segment to be analyzed, defaults to the end of the file.<\/li><li>-tle: used to turn on prediction based on Two-line elements (TLE) file, otherwise this function is off.<\/li><\/ul>\n\n\n\n<p>EXAMPLES:\\<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>python3 .\\main.py -i .\\MySignal.json -f .\\MySatellite\\MySignal.wav -ch0 400.575e6 -bw0 20e3 -o D:\\\\CubeSat -begin 10. -end 60. -tle\n\npython3 .\/main.py -i \/home\/MyUser\/MySignal.json -f .\/MySatellite\/MySignal.wav -ch0 400.575e6 -bw0 20e3 -o .\/CubeSat\n\npython3 .\/main.py -i \/home\/MyUser\/MySignal.json -f .\/MySatellite\/MySignal.wav -filter 1.25\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Output:<\/strong><\/h2>\n\n\n\n<ol><li>A time vs. frequency graph, showing the center of the signal in the frequency domain by time, for example: <img decoding=\"async\" loading=\"lazy\" alt=\"APT_NOAA example\" src=\"https:\/\/lh6.googleusercontent.com\/sJebehb3NxocPBe-lNWH9bQrJ-zfrpugXcg1ql6ROPbwpGJcOhJujShHWwKwwihxqKexRp7Mr8TGD9Q2zi-Fm1XkoIt57bYzfNArQ_pvXm5aCilApFS1otSphsC4mUbDmc3cbFXN\" width=\"624\" height=\"237\"><\/li><li>A .csv file storing the center position in the frequency domain by time.<\/li><li>A .json file with a &#8222;header&#8220; object containing metadata of the signal and &#8222;signal_center&#8220; object containing centers of the signal for each channel by time.<\/li><li>On the command-line interface, if -tle is enabled, there will be information about the offset between the calculated frequencies from the wave file and from the tle file as well as the standard error of the signal compared to prediction.<\/li><\/ol>\n\n\n\n<p>All files are exported with name and directory as selected with the [-o] argument.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">Test files:<\/h2>\n\n\n\n<p>You can use the files\u00a0<a href=\"https:\/\/drive.google.com\/drive\/folders\/1xJYhjG-9HT8RZG5PgqbY8jZbCk6mBn_r?usp=sharing\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>\u00a0to test the code.<\/p>\n\n\n\n<h1 class=\"wp-block-heading\"><strong>Description:<\/strong><\/h1>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>1. Introduction:<\/strong><\/h2>\n\n\n\n<p>Because of the recent sharp growth of the satellite industry, it is necessary to have free, accessible, open-source software to analyze satellite signals and track them. In order to achieve that, as one of the most essential steps, those applications must calculate the exact centers of the input satellite signals in the frequency domain. My project is initiated to accommodate this requirement. It aims to provide a program that can reliably detect satellite signals and find their exact frequency centers with high precision, thus providing important statistics for signal analyzing and satellite tracking.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>2. Overview<\/strong><\/h2>\n\n\n\n<p>The project aims to locate the exact centers of given satellite signals with the desired accuracy of 1kHz, based on several different methods of finding the center. At first, the center-of-mass approach will be used to determine the rough location of the center. From that location, more algorithms will be applied depending on the type of the signal to find the signal center with higher accuracy. Currently, for many APT\/NOAA signals, with the center-of-mass and \u201csignal peak finding\u201d approach (that will be shown below), we can get results with standard errors less than 1 kHz. For example, with the example signal above, the standard error is 0.026 kHz.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>3. Theoretical basis<\/strong><\/h2>\n\n\n\n<p>The overall flowchart: <img decoding=\"async\" loading=\"lazy\" alt=\"Flowchart\" src=\"https:\/\/lh4.googleusercontent.com\/yp0HgcV4tyLPItq4rBydpjkkEkwsVxAkIJ-_enVrWFrulCbwRD8HTT9H_KzRfmaaQebvbN5AubJ2u4YLiHpZIPFs8mzx0y9mOfTsmcIQXyuGCv886IY3p39KNUucwLICGTWTwRY8\" width=\"624\" height=\"520\"><\/p>\n\n\n\n<ul><li>Fast-Fourier Transform (FFT)<\/li><\/ul>\n\n\n\n<p>Fourier Transform is a well-known algorithm to transform a signal from the time domain into the frequency domain. It extracts all the frequencies and their contributions to the total actual signal. More information could be found at <a href=\"https:\/\/en.wikipedia.org\/wiki\/Fourier_transform\" target=\"_blank\" rel=\"noreferrer noopener\">Wikipedia: Discrete Fourier transform<\/a>.<\/p>\n\n\n\n<p>Fast-Fourier Transform is Fourier Transform but uses intelligent ways to reduce the time complexity, thus reducing the time it takes to transform the signal.<\/p>\n\n\n\n<ul><li>Noise reduction and background signal reset:<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/1VvAUuq_dFqLOaZ-5YmMNM_XzE4CfbghQq6OKDSV3Cv_F-Qlpk2wfQHz58Tgxxv6BdK2uKrmBNFs4wHPv5HJf374gI4-R8DZvg6ZpaNyfeQ-Kh2RQlJ_IcNU_OD7nx37zWMgzhNs\" alt=\"Noise in actual signal\"\/><\/figure>\n\n\n\n<p>In actual signals, there is always noise, but generally noise has two important characteristics, which is normally distributed and its amplitude does not change much by frequency. You can see the signal noise in the following figure:<\/p>\n\n\n\n<p>If we can divide the signal in the frequency domain into many parts such that we are sure that at least one of them contains only noise, we can use that part to determine the strength of noise.<\/p>\n\n\n\n<p>For example, consider only this signal segment:<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh5.googleusercontent.com\/8S3IuBfl1KJZiHLO8xkILzg0vVHNoN2VV0hAPQd52abMYSuMX6V2CHseRHoW65BS5QJtBzfQOcP352kNXV3KFnPRUGe8dpNeh2he43cDKcgsIaAJN7T4otZo5mDsVN6ak6zRAAFw\" alt=\"One segment with noise\"\/><\/figure>\n\n\n\n<p>By taking its average, we can find where the noise is located relative to the amplitude 0. By subtracting the whole signal to this average, we can ensure the noise all lies around the zero amplitude.<\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/Rz8QQNGOwK6QLNyefd26xacg3NCHpZnmOpKFyuPZDAlpUcVvORJFWCeT8-pToFYkRbYREEd-RH408hWoRQos02-M11i_FLc0ZqNaNLpCq0S7PJyaX1NlInbWoMQpdPNpWoHXvLtd\" alt=\"One segment with noise\"\/><\/figure>\n\n\n\n<p>Next, we want to reduce all the noise to zero. To do that, we consider the distribution of noise, which is a normal distribution.<\/p>\n\n\n\n<p><img decoding=\"async\" loading=\"lazy\" alt=\"Normal distribution\" src=\"https:\/\/lh6.googleusercontent.com\/J4wMN9qgpzrAUzHmb9DSEP_Omu8lBF166AR2aN_xSWbuDL0SHh7lt_ml5og6SVOeJ-xBVlPjNb7OOm2yqpyYb4zkCuRx0I2BXvZNGQ4iPLJqMYdLyjDE_Vj_qmfToqGauK8nh25U\" width=\"624\" height=\"464\"> Photo from <a href=\"https:\/\/sphweb.bumc.bu.edu\/otlt\/MPH-Modules\/PH717-QuantCore\/PH717-Module6-RandomError\/PH717-Module6-RandomError5.html\">Characteristics of a Normal Distribution<\/a>.<\/p>\n\n\n\n<p>From this distribution, we are sure that 99.9% of noise has amplitude less than three times of the standard deviation of noise. If we shift the whole signal down by 3 times this standard deviation, 99.9% of the noise will have amplitude less than 0. From there, we can just remove every part of the signal with an amplitude less than zero. Then we will be able to get a signal without noise with the background having been reset to 0.<\/p>\n\n\n\n<p>You can clearly see the effect of this algorithm by looking at the signal of PIXL1 satellite above, where all the noise has been shifted to below 0.<\/p>\n\n\n\n<ul><li>Center-of-mass centering<\/li><\/ul>\n\n\n\n<p>This algorithm is simple, the centroid position is calculated as: (sum of (amplitude x position)) \/ (sum of amplitude), similar to how we calculate the center of mass in physics. The result of this algorithm is called the spectral centroid, more information could be found at <a href=\"https:\/\/en.wikipedia.org\/wiki\/Spectral_centroid\" target=\"_blank\" rel=\"noreferrer noopener\">Wikipedia: Spectral centroid<\/a>.<\/p>\n\n\n\n<ul><li>Peak finding.<\/li><\/ul>\n\n\n\n<p>For signals with clear peaks such as APT(NOAA), finding the exact central peak points of the signal would give us good results. From the rough location of the center by Center-of-mass method, we can scan for its neighbor to find the maximum peak. This peak will be the center of the signal that we want to find. For APT signals, this peak is very narrow, therefore this method is able to give us very high precision.<\/p>\n\n\n\n<ul><li>Predicted signal centers from TLE<\/li><\/ul>\n\n\n\n<p>TLE (Two-line element set) information of a satellite can be used to determine the position and velocity of that satellite on the orbit. By using this data of position and velocity, we can calculate the relativistic Doppler effect caused by the location and movement of the satellite to calculate the signal frequency that we expect to receive on the ground. For more information, visit <a href=\"https:\/\/en.wikipedia.org\/wiki\/Relativistic_Doppler_effect#Motion_in_an_arbitrary_direction\" target=\"_blank\" rel=\"noreferrer noopener\">Wikipedia: Relativistic Doppler effect<\/a>.<\/p>\n\n\n\n<ul><li>Error calculation. Assume TLE gives us the correct result of signal center, we can calculate the standard error of the result by calculating the standard deviation:<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/lh4.googleusercontent.com\/7uN4YlxjI7yebyx_eMdrVVr5qGzeslp7tOmphl_q3gb7uKXfaRvGKxc3WWtogeEYZVBtHuV6tVybLhqM9v2PU5NV9s9ZSJKvCLq4IDplMpeH9K7nFGaL19BaY8jZZVYwi1moGnrt\" alt=\"Standard deviation\"\/><\/figure>\n\n\n\n<p>Where n is the number of samples, x_i is the difference between our calculated center frequency from .wav and the frequency we get from TLE.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">4. <strong>Implementation in actual code:<\/strong><\/h2>\n\n\n\n<ul><li><a href=\"https:\/\/github.com\/aerospaceresearch\/findsatbyrf\/blob\/bm_dev\/findsat\/main.py\" target=\"_blank\" rel=\"noreferrer noopener\">main.py<\/a> is where initial parameters are stored. The program is executed when this file is run.<\/li><li><a href=\"https:\/\/github.com\/aerospaceresearch\/findsatbyrf\/blob\/bm_dev\/findsat\/tracker.py\" target=\"_blank\" rel=\"noreferrer noopener\">tracker.py<\/a> stores the Signal object, which is the python object that stores every information about a signal and the functions to find its center.<\/li><li><a href=\"https:\/\/github.com\/aerospaceresearch\/findsatbyrf\/blob\/bm_dev\/findsat\/tools.py\" target=\"_blank\" rel=\"noreferrer noopener\">tools.py<\/a> contains the functions necessary for our calculation, as well as the TLE object used for center prediction.<\/li><li><a href=\"https:\/\/github.com\/aerospaceresearch\/findsatbyrf\/blob\/bm_dev\/findsat\/signal_io.py\" target=\"_blank\" rel=\"noreferrer noopener\">signal_io.py<\/a> stores functions and objects related to the input and output of our signals and instructions.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\">5. <strong>Current results:<\/strong><\/h2>\n\n\n\n<ol><li>For APT(NOAA): Standard error = 0.004 kHz <img decoding=\"async\" loading=\"lazy\" alt=\"APT_NOAA example\" src=\"https:\/\/lh3.googleusercontent.com\/OACViwl9WObDF6bCXVXSKv1LLWRonCJ7-kePH8HENf2ydQwrx8dXQwUTlIJDAauahvD3lFSDpCLG8jGx8nKszNUAaj4bPro3Lc6bqLni4ruVc8xZnlfjUaNzm9cOmJTiMpYEgUBy\" width=\"624\" height=\"237\"><\/li><li>For PIXL1(CUBESAT): Standard error = 0.029 kHz <img decoding=\"async\" loading=\"lazy\" alt=\"PIXL example\" src=\"https:\/\/lh4.googleusercontent.com\/ycAs6dQ-MR4dvY-_ykaEZ3zCoXUxUvEZXxlcs8ssker44b3Rb7bU3TzEUG2GWqdonxquArtnBHPijThkMU1c1BDlJcqtbsWwvOwIVXJv4GHuMLsR9PwdiqgKRcgpsCm1PNtew0t-\" width=\"624\" height=\"237\"><\/li><\/ol>\n\n\n\n<h2 class=\"wp-block-heading\">6. <strong>Potential further improvements:<\/strong><\/h2>\n\n\n\n<ul><li>Expand the program to work better with more types of signals.<\/li><li>Make video-output function works with reasonable computing resources.<br>Currently, with my private version of the code, I am able to make videos such as <a rel=\"noreferrer noopener\" href=\"https:\/\/youtu.be\/GA907aWhWGA\" target=\"_blank\">this one<\/a>, but it took too much time and memory to actually make one, therefore I did not put it into the official code.<\/li><\/ul>\n\n\n\n<figure class=\"wp-block-embed-youtube wp-block-embed is-type-video is-provider-youtube wp-embed-aspect-4-3 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"APT signal from findsatbyrf\" width=\"840\" height=\"630\" src=\"https:\/\/www.youtube.com\/embed\/GA907aWhWGA?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n","protected":false},"excerpt":{"rendered":"<p>Overview: This program finds the center in the frequency domain of a signal by time. This is the link to its Github repository. There, you can also see the markdown (.md) file that contains the same content as this blog. Every major work on this repository is done by Binh-Minh Tran-Huu under instructions and monitor &hellip; <a href=\"https:\/\/aerospaceresearch.net\/?p=2353\" class=\"more-link\"><span class=\"screen-reader-text\">\u201e[GSoC2021: findsatbyrf] Center of satellite signal in the frequency domain\u201c<\/span> weiterlesen<\/a><\/p>\n","protected":false},"author":31,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[32,31,30],"_links":{"self":[{"href":"https:\/\/aerospaceresearch.net\/index.php?rest_route=\/wp\/v2\/posts\/2353"}],"collection":[{"href":"https:\/\/aerospaceresearch.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/aerospaceresearch.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/aerospaceresearch.net\/index.php?rest_route=\/wp\/v2\/users\/31"}],"replies":[{"embeddable":true,"href":"https:\/\/aerospaceresearch.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2353"}],"version-history":[{"count":10,"href":"https:\/\/aerospaceresearch.net\/index.php?rest_route=\/wp\/v2\/posts\/2353\/revisions"}],"predecessor-version":[{"id":2363,"href":"https:\/\/aerospaceresearch.net\/index.php?rest_route=\/wp\/v2\/posts\/2353\/revisions\/2363"}],"wp:attachment":[{"href":"https:\/\/aerospaceresearch.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2353"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/aerospaceresearch.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2353"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/aerospaceresearch.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2353"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}