@@ -0,0 +1,75 | |||||
|
1 | cmake_minimum_required(VERSION 3.6) | |||
|
2 | project(LFR-BasicParameters CXX C) | |||
|
3 | ||||
|
4 | include(GNUInstallDirs) | |||
|
5 | ||||
|
6 | OPTION (CPPCHECK "Analyzes the source code with cppcheck" OFF) | |||
|
7 | OPTION (CLANG_TIDY "Analyzes the source code with Clang Tidy" OFF) | |||
|
8 | OPTION (IWYU "Analyzes the source code with Include What You Use" OFF) | |||
|
9 | OPTION (Coverage "Enables code coverage" OFF) | |||
|
10 | ||||
|
11 | ||||
|
12 | OPTION (Debug_tch "" OFF) | |||
|
13 | OPTION (LSB_FIRST_TCH "" ON) | |||
|
14 | ||||
|
15 | if(Debug_tch) | |||
|
16 | add_definitions(-DDEBUG_TCH) | |||
|
17 | endif() | |||
|
18 | if(LSB_FIRST_TCH) | |||
|
19 | add_definitions(-DLSB_FIRST_TCH) | |||
|
20 | else() | |||
|
21 | add_definitions(-DMSB_FIRST_TCH) | |||
|
22 | endif() | |||
|
23 | ||||
|
24 | set(CMAKE_CXX_STANDARD 17) | |||
|
25 | ||||
|
26 | set(CMAKE_INCLUDE_CURRENT_DIR ON) | |||
|
27 | ||||
|
28 | if(NOT CMAKE_BUILD_TYPE) | |||
|
29 | set(CMAKE_BUILD_TYPE "Release" CACHE STRING "" FORCE) | |||
|
30 | endif() | |||
|
31 | ||||
|
32 | ||||
|
33 | IF(CPPCHECK) | |||
|
34 | set(CMAKE_CXX_CPPCHECK "cppcheck;--enable=warning,style") | |||
|
35 | ENDIF(CPPCHECK) | |||
|
36 | ||||
|
37 | IF(CLANG_TIDY) | |||
|
38 | set(CMAKE_CXX_CLANG_TIDY "clang-tidy;-style=file;-checks=*") | |||
|
39 | ENDIF(CLANG_TIDY) | |||
|
40 | ||||
|
41 | IF(IWYU) | |||
|
42 | set(CMAKE_CXX_INCLUDE_WHAT_YOU_USE "include-what-you-use") | |||
|
43 | ENDIF(IWYU) | |||
|
44 | ||||
|
45 | file(GLOB sources src/*.c) | |||
|
46 | add_library(lfr_basic_params SHARED ${sources}) | |||
|
47 | ||||
|
48 | target_include_directories(lfr_basic_params | |||
|
49 | PUBLIC | |||
|
50 | $<BUILD_INTERFACE:${CMAKE_CURRENT_LIST_DIR}/src> | |||
|
51 | ) | |||
|
52 | ||||
|
53 | IF(Coverage) | |||
|
54 | set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_C_FLAGS_RELEASE} -g -O0 -Wall -W -Wshadow -Wunused-variable -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers -Wno-deprecated -Woverloaded-virtual -Wwrite-strings -fprofile-arcs -ftest-coverage") | |||
|
55 | set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g -O0 -Wall -W -Wshadow -Wunused-variable \ | |||
|
56 | -Wunused-parameter -Wunused-function -Wunused -Wno-system-headers \ | |||
|
57 | -Wno-deprecated -Woverloaded-virtual -Wwrite-strings -fprofile-arcs -ftest-coverage") | |||
|
58 | set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -fprofile-arcs -ftest-coverage") | |||
|
59 | ||||
|
60 | add_custom_command(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/gcov.html | |||
|
61 | COMMAND gcovr --exclude='.*Test.*' --exclude='.*external.*' --object-directory ${CMAKE_BINARY_DIR} -r ${CMAKE_SOURCE_DIR} --html --html-details -o ${CMAKE_CURRENT_BINARY_DIR}/gcov.html | |||
|
62 | ) | |||
|
63 | add_custom_target(gcovr | |||
|
64 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/gcov.html gcovr | |||
|
65 | ) | |||
|
66 | add_custom_target(show_coverage | |||
|
67 | COMMAND xdg-open ${CMAKE_CURRENT_BINARY_DIR}/gcov.html | |||
|
68 | DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/gcov.html gcovr | |||
|
69 | ) | |||
|
70 | ENDIF(Coverage) | |||
|
71 | ||||
|
72 | enable_testing() | |||
|
73 | find_package (Python3 COMPONENTS Interpreter Development) | |||
|
74 | add_test(NAME init_k_coefficients COMMAND ${Python3_EXECUTABLE} ${CMAKE_CURRENT_SOURCE_DIR}/tests/init_k_coefficients.py WORKING_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}) | |||
|
75 |
@@ -0,0 +1,195 | |||||
|
1 | { | |||
|
2 | "cells": [ | |||
|
3 | { | |||
|
4 | "cell_type": "code", | |||
|
5 | "execution_count": 1, | |||
|
6 | "metadata": { | |||
|
7 | "ExecuteTime": { | |||
|
8 | "end_time": "2019-11-08T17:24:20.336383Z", | |||
|
9 | "start_time": "2019-11-08T17:24:20.048293Z" | |||
|
10 | } | |||
|
11 | }, | |||
|
12 | "outputs": [], | |||
|
13 | "source": [ | |||
|
14 | "from ctypes import * \n", | |||
|
15 | "import matplotlib.pyplot as plt\n", | |||
|
16 | "import numpy as np\n", | |||
|
17 | "import os\n", | |||
|
18 | "import sys\n", | |||
|
19 | "\n", | |||
|
20 | "%matplotlib notebook" | |||
|
21 | ] | |||
|
22 | }, | |||
|
23 | { | |||
|
24 | "cell_type": "code", | |||
|
25 | "execution_count": 2, | |||
|
26 | "metadata": { | |||
|
27 | "ExecuteTime": { | |||
|
28 | "end_time": "2019-11-08T17:24:20.382711Z", | |||
|
29 | "start_time": "2019-11-08T17:24:20.378601Z" | |||
|
30 | } | |||
|
31 | }, | |||
|
32 | "outputs": [], | |||
|
33 | "source": [ | |||
|
34 | "lib_basic_params = cdll.LoadLibrary('../build-LFR_basic-parameters-Desktop-Default/liblfr_basic_params.so')" | |||
|
35 | ] | |||
|
36 | }, | |||
|
37 | { | |||
|
38 | "cell_type": "code", | |||
|
39 | "execution_count": null, | |||
|
40 | "metadata": {}, | |||
|
41 | "outputs": [], | |||
|
42 | "source": [] | |||
|
43 | }, | |||
|
44 | { | |||
|
45 | "cell_type": "markdown", | |||
|
46 | "metadata": {}, | |||
|
47 | "source": [ | |||
|
48 | "Code C:\n", | |||
|
49 | "\n", | |||
|
50 | "```c\n", | |||
|
51 | "void init_k_coefficients_f0(float *k_coefficients, unsigned char nb_binscompressed_matrix )\n", | |||
|
52 | "```" | |||
|
53 | ] | |||
|
54 | }, | |||
|
55 | { | |||
|
56 | "cell_type": "code", | |||
|
57 | "execution_count": 3, | |||
|
58 | "metadata": { | |||
|
59 | "ExecuteTime": { | |||
|
60 | "end_time": "2019-11-08T17:24:21.853368Z", | |||
|
61 | "start_time": "2019-11-08T17:24:21.554426Z" | |||
|
62 | } | |||
|
63 | }, | |||
|
64 | "outputs": [ | |||
|
65 | { | |||
|
66 | "data": { | |||
|
67 | "text/plain": [ | |||
|
68 | "[<matplotlib.lines.Line2D at 0x7f466118c050>]" | |||
|
69 | ] | |||
|
70 | }, | |||
|
71 | "execution_count": 3, | |||
|
72 | "metadata": {}, | |||
|
73 | "output_type": "execute_result" | |||
|
74 | }, | |||
|
75 | { | |||
|
76 | "data": { | |||
|
77 | "image/png": "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\n", | |||
|
78 | "text/plain": [ | |||
|
79 | "<Figure size 432x288 with 1 Axes>" | |||
|
80 | ] | |||
|
81 | }, | |||
|
82 | "metadata": { | |||
|
83 | "needs_background": "light" | |||
|
84 | }, | |||
|
85 | "output_type": "display_data" | |||
|
86 | } | |||
|
87 | ], | |||
|
88 | "source": [ | |||
|
89 | "nb_bins = 11\n", | |||
|
90 | "nb_binscompressed_matrix = c_char(nb_bins)\n", | |||
|
91 | "k_coefficients = (c_float * (32 * nb_bins))() \n", | |||
|
92 | "\n", | |||
|
93 | "for i in range(len(k_coefficients)):\n", | |||
|
94 | " k_coefficients[i] = 100.*np.random.random()\n", | |||
|
95 | " \n", | |||
|
96 | "plt.plot(k_coefficients)" | |||
|
97 | ] | |||
|
98 | }, | |||
|
99 | { | |||
|
100 | "cell_type": "code", | |||
|
101 | "execution_count": 4, | |||
|
102 | "metadata": { | |||
|
103 | "ExecuteTime": { | |||
|
104 | "end_time": "2019-11-08T17:24:22.653016Z", | |||
|
105 | "start_time": "2019-11-08T17:24:22.406334Z" | |||
|
106 | } | |||
|
107 | }, | |||
|
108 | "outputs": [ | |||
|
109 | { | |||
|
110 | "data": { | |||
|
111 | "text/plain": [ | |||
|
112 | "[<matplotlib.lines.Line2D at 0x7f4661137a90>]" | |||
|
113 | ] | |||
|
114 | }, | |||
|
115 | "execution_count": 4, | |||
|
116 | "metadata": {}, | |||
|
117 | "output_type": "execute_result" | |||
|
118 | }, | |||
|
119 | { | |||
|
120 | "data": { | |||
|
121 | "image/png": "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\n", | |||
|
122 | "text/plain": [ | |||
|
123 | "<Figure size 432x288 with 1 Axes>" | |||
|
124 | ] | |||
|
125 | }, | |||
|
126 | "metadata": { | |||
|
127 | "needs_background": "light" | |||
|
128 | }, | |||
|
129 | "output_type": "display_data" | |||
|
130 | } | |||
|
131 | ], | |||
|
132 | "source": [ | |||
|
133 | "plt.figure()\n", | |||
|
134 | "lib_basic_params.init_k_coefficients(k_coefficients, nb_binscompressed_matrix)\n", | |||
|
135 | "plt.plot(k_coefficients)" | |||
|
136 | ] | |||
|
137 | }, | |||
|
138 | { | |||
|
139 | "cell_type": "code", | |||
|
140 | "execution_count": 9, | |||
|
141 | "metadata": { | |||
|
142 | "ExecuteTime": { | |||
|
143 | "end_time": "2019-11-08T17:28:05.727737Z", | |||
|
144 | "start_time": "2019-11-08T17:28:05.720427Z" | |||
|
145 | } | |||
|
146 | }, | |||
|
147 | "outputs": [ | |||
|
148 | { | |||
|
149 | "data": { | |||
|
150 | "text/plain": [ | |||
|
151 | "(array([ 2, 3, 34, 35, 66, 67, 98, 99, 130, 131, 162, 163, 194,\n", | |||
|
152 | " 195, 226, 227, 258, 259, 290, 291, 322, 323]),)" | |||
|
153 | ] | |||
|
154 | }, | |||
|
155 | "execution_count": 9, | |||
|
156 | "metadata": {}, | |||
|
157 | "output_type": "execute_result" | |||
|
158 | } | |||
|
159 | ], | |||
|
160 | "source": [ | |||
|
161 | "\n", | |||
|
162 | "arr = np.array(k_coefficients)\n", | |||
|
163 | "np.where(arr == 0.)" | |||
|
164 | ] | |||
|
165 | }, | |||
|
166 | { | |||
|
167 | "cell_type": "code", | |||
|
168 | "execution_count": null, | |||
|
169 | "metadata": {}, | |||
|
170 | "outputs": [], | |||
|
171 | "source": [] | |||
|
172 | } | |||
|
173 | ], | |||
|
174 | "metadata": { | |||
|
175 | "kernelspec": { | |||
|
176 | "display_name": "Python 3", | |||
|
177 | "language": "python", | |||
|
178 | "name": "python3" | |||
|
179 | }, | |||
|
180 | "language_info": { | |||
|
181 | "codemirror_mode": { | |||
|
182 | "name": "ipython", | |||
|
183 | "version": 3 | |||
|
184 | }, | |||
|
185 | "file_extension": ".py", | |||
|
186 | "mimetype": "text/x-python", | |||
|
187 | "name": "python", | |||
|
188 | "nbconvert_exporter": "python", | |||
|
189 | "pygments_lexer": "ipython3", | |||
|
190 | "version": "3.7.4" | |||
|
191 | } | |||
|
192 | }, | |||
|
193 | "nbformat": 4, | |||
|
194 | "nbformat_minor": 2 | |||
|
195 | } |
This diff has been collapsed as it changes many lines, (1002 lines changed) Show them Hide them | |||||
@@ -0,0 +1,1002 | |||||
|
1 | // In the frame of RPW LFR Sofware ICD Issue1 Rev8 (05/07/2013) => R2 FSW | |||
|
2 | // version 1.0: 31/07/2013 | |||
|
3 | // version 1.1: 02/04/2014 | |||
|
4 | // version 1.2: 30/04/2014 | |||
|
5 | // version 1.3: 02/05/2014 | |||
|
6 | // version 1.4: 16/05/2014 | |||
|
7 | // version 1.5: 20/05/2014 | |||
|
8 | // version 1.6: 19/12/2014 | |||
|
9 | // version 1.7: 15/01/2015 (modifs de Paul + correction erreurs qui se compensaient (LSB <=> MSB + indices [0,2] <=> [1,3]) | |||
|
10 | // version 1.8: 02/02/2015 (gestion des divisions par zéro) | |||
|
11 | // In the frame of RPW LFR Sofware ICD Issue3 Rev6 (27/01/2015) => R3 FSW | |||
|
12 | // version 2.0: 19/06/2015 | |||
|
13 | // version 2.1: 22/06/2015 (modifs de Paul) | |||
|
14 | // version 2.2: 23/06/2015 (modifs de l'ordre de déclaration/définition de init_k_coefficients dans basic_parameters.c ... + maintien des declarations dans le .h) | |||
|
15 | // version 2.3: 01/07/2015 (affectation initiale des octets 7 et 9 dans les BP1 corrigée ...) | |||
|
16 | // version 2.4: 05/10/2018 (added GPL headers) | |||
|
17 | // version 2.5: 09/10/2018 (dans main.c #include "basic_parameters_utilities.h" est changé par les déclarations extern correspondantes ...! | |||
|
18 | // + delta mise en conformité LOGISCOPE) | |||
|
19 | ||||
|
20 | /*------------------------------------------------------------------------------ | |||
|
21 | -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW), | |||
|
22 | -- This file is a part of the LFR FSW | |||
|
23 | -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS | |||
|
24 | -- | |||
|
25 | -- This program is free software; you can redistribute it and/or modify | |||
|
26 | -- it under the terms of the GNU General Public License as published by | |||
|
27 | -- the Free Software Foundation; either version 2 of the License, or | |||
|
28 | -- (at your option) any later version. | |||
|
29 | -- | |||
|
30 | -- This program is distributed in the hope that it will be useful, | |||
|
31 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
32 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
33 | -- GNU General Public License for more details. | |||
|
34 | -- | |||
|
35 | -- You should have received a copy of the GNU General Public License | |||
|
36 | -- along with this program; if not, write to the Free Software | |||
|
37 | -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
|
38 | -------------------------------------------------------------------------------*/ | |||
|
39 | /*-- Author : Thomas Chust | |||
|
40 | -- Contact : Thomas Chust | |||
|
41 | -- Mail : thomas.chust@lpp.polytechnique.fr | |||
|
42 | ----------------------------------------------------------------------------*/ | |||
|
43 | ||||
|
44 | #include <stdio.h> | |||
|
45 | #include <math.h> | |||
|
46 | #include <stdint.h> | |||
|
47 | ||||
|
48 | #include "basic_parameters_params.h" | |||
|
49 | ||||
|
50 | void init_k_coefficients(float *k_coefficients, | |||
|
51 | unsigned char nb_binscompressed_matrix ) | |||
|
52 | { | |||
|
53 | uint8_t i; // 8 bits unsigned | |||
|
54 | uint8_t j; | |||
|
55 | for(i=0; i<nb_binscompressed_matrix; i++) | |||
|
56 | { | |||
|
57 | for (j=0;j<NB_K_COEFF_PER_BIN;j++) { | |||
|
58 | k_coefficients[i*NB_K_COEFF_PER_BIN+j] = 1.f; | |||
|
59 | } | |||
|
60 | k_coefficients[i*NB_K_COEFF_PER_BIN+K45_PE_RE] = 0.; | |||
|
61 | k_coefficients[i*NB_K_COEFF_PER_BIN+K45_PE_IM] = 0.; | |||
|
62 | } | |||
|
63 | } | |||
|
64 | ||||
|
65 | ||||
|
66 | void BP1_set(float *compressed_spec_mat, float *k_coeff_intercalib, uint8_t nb_bins_compressed_spec_mat, uint8_t *lfr_bp1){ | |||
|
67 | float PSDB; // 32-bit floating point | |||
|
68 | float PSDE; | |||
|
69 | float tmp; | |||
|
70 | float NVEC_V0; | |||
|
71 | float NVEC_V1; | |||
|
72 | float NVEC_V2; | |||
|
73 | float aux; | |||
|
74 | float tr_SB_SB; | |||
|
75 | float e_cross_b_re; | |||
|
76 | float e_cross_b_im; | |||
|
77 | float n_cross_e_scal_b_re; | |||
|
78 | float n_cross_e_scal_b_im; | |||
|
79 | float ny; | |||
|
80 | float nz; | |||
|
81 | float bx_bx_star; | |||
|
82 | float vphi; | |||
|
83 | float significand; | |||
|
84 | int exponent; // 32-bit signed integer | |||
|
85 | float alpha_M; | |||
|
86 | ||||
|
87 | uint8_t nbitexp; // 8-bit unsigned integer | |||
|
88 | uint8_t nbitsig; | |||
|
89 | uint8_t tmp_uint8; | |||
|
90 | uint8_t *pt_uint8; // pointer on unsigned 8-bit integer | |||
|
91 | int8_t expmin; // 8-bit signed integer | |||
|
92 | int8_t expmax; | |||
|
93 | uint16_t rangesig; // 16-bit unsigned integer | |||
|
94 | uint16_t psd; | |||
|
95 | uint16_t exp; | |||
|
96 | uint16_t tmp_uint16; | |||
|
97 | uint16_t i; | |||
|
98 | ||||
|
99 | alpha_M = 45 * (3.1415927f/180); | |||
|
100 | ||||
|
101 | #ifdef DEBUG_TCH | |||
|
102 | printf("BP1 : \n"); | |||
|
103 | printf("Number of bins: %d\n", nb_bins_compressed_spec_mat); | |||
|
104 | #endif | |||
|
105 | ||||
|
106 | // initialization for managing the exponents of the floating point data: | |||
|
107 | nbitexp = 6; // number of bits for the exponent | |||
|
108 | expmax = 32+5; // maximum value of the exponent | |||
|
109 | expmin = (expmax - (1 << nbitexp)) + 1; // accordingly the minimum exponent value | |||
|
110 | // for floating point data to be recorded on 16-bit words: | |||
|
111 | nbitsig = 16 - nbitexp; // number of bits for the significand | |||
|
112 | rangesig = (1 << nbitsig)-1; // == 2^nbitsig - 1 | |||
|
113 | ||||
|
114 | #ifdef DEBUG_TCH | |||
|
115 | printf("nbitexp : %d, expmax : %d, expmin : %d\n", nbitexp, expmax, expmin); | |||
|
116 | printf("nbitsig : %d, rangesig : %d\n", nbitsig, rangesig); | |||
|
117 | #endif | |||
|
118 | ||||
|
119 | for(i=0; i<nb_bins_compressed_spec_mat; i++){ | |||
|
120 | //============================================== | |||
|
121 | // BP1 PSDB == PA_LFR_SC_BP1_PB_F0 == 16 bits = 6 bits (exponent) + 10 bits (significand) | |||
|
122 | PSDB = compressed_spec_mat[i*NB_VALUES_PER_SPECTRAL_MATRIX] // S11 | |||
|
123 | + compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 9] // S22 | |||
|
124 | + compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 16]; // S33 | |||
|
125 | ||||
|
126 | significand = frexpf(PSDB, &exponent); // 0.5 <= significand < 1 | |||
|
127 | // PSDB = significand * 2^exponent | |||
|
128 | ||||
|
129 | if (exponent < expmin) { // value should be >= 0.5 * 2^expmin | |||
|
130 | exponent = expmin; | |||
|
131 | significand = 0.5; // min value that can be recorded | |||
|
132 | } | |||
|
133 | if (exponent > expmax) { // value should be < 0.5 * 2^(expmax+1) | |||
|
134 | exponent = expmax; | |||
|
135 | significand = 1.0; // max value that can be recorded | |||
|
136 | } | |||
|
137 | if (significand == 0) { // in that case exponent == 0 too | |||
|
138 | exponent = expmin; | |||
|
139 | significand = 0.5; // min value that can be recorded | |||
|
140 | } | |||
|
141 | ||||
|
142 | psd = (uint16_t) ((((significand*2) - 1)*rangesig) + 0.5); // Shift and cast into a 16-bit unsigned int with rounding | |||
|
143 | // where just the first nbitsig bits are used (0, ..., 2^nbitsig-1) | |||
|
144 | exp = (uint16_t) (exponent-expmin); // Shift and cast into a 16-bit unsigned int where just | |||
|
145 | // the first nbitexp bits are used (0, ..., 2^nbitexp-1) | |||
|
146 | tmp_uint16 = psd | (exp << nbitsig); // Put the exponent bits (nbitexp) next to the | |||
|
147 | // left place of the significand bits (nbitsig), | |||
|
148 | // making the 16-bit word to be recorded | |||
|
149 | pt_uint8 = (uint8_t*) &tmp_uint16; // Affect an uint8_t pointer with the adress of tmp_uint16 | |||
|
150 | #ifdef MSB_FIRST_TCH | |||
|
151 | lfr_bp1[(i*NB_BYTES_BP1)+2] = pt_uint8[0]; // Record MSB of tmp_uint16 | |||
|
152 | lfr_bp1[(i*NB_BYTES_BP1)+3] = pt_uint8[1]; // Record LSB of tmp_uint16 | |||
|
153 | #endif | |||
|
154 | #ifdef LSB_FIRST_TCH | |||
|
155 | lfr_bp1[(i*NB_BYTES_BP1)+2] = pt_uint8[1]; // Record MSB of tmp_uint16 | |||
|
156 | lfr_bp1[(i*NB_BYTES_BP1)+3] = pt_uint8[0]; // Record LSB of tmp_uint16 | |||
|
157 | #endif | |||
|
158 | #ifdef DEBUG_TCH | |||
|
159 | printf("\nBin number: %d\n", i); | |||
|
160 | printf("PSDB : %16.8e\n",PSDB); | |||
|
161 | printf("significand : %16.8e\n",significand); | |||
|
162 | printf("exponent : %d\n" ,exponent); | |||
|
163 | printf("psd for PSDB significand : %d\n",psd); | |||
|
164 | printf("exp for PSDB exponent : %d\n",exp); | |||
|
165 | printf("pt_uint8[1] for PSDB exponent + significand: %.3d or %.2x\n",pt_uint8[1], pt_uint8[1]); | |||
|
166 | printf("pt_uint8[0] for PSDB significand: %.3d or %.2x\n",pt_uint8[0], pt_uint8[0]); | |||
|
167 | printf("lfr_bp1[i*NB_BYTES_BP1+2] : %.3d or %.2x\n",lfr_bp1[i*NB_BYTES_BP1+2], lfr_bp1[i*NB_BYTES_BP1+2]); | |||
|
168 | printf("lfr_bp1[i*NB_BYTES_BP1+3] : %.3d or %.2x\n",lfr_bp1[i*NB_BYTES_BP1+3], lfr_bp1[i*NB_BYTES_BP1+3]); | |||
|
169 | #endif | |||
|
170 | //============================================== | |||
|
171 | // BP1 PSDE == PA_LFR_SC_BP1_PE_F0 == 16 bits = 6 bits (exponent) + 10 bits (significand) | |||
|
172 | PSDE = (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 21] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K44_PE]) // S44 | |||
|
173 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 24] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K55_PE]) // S55 | |||
|
174 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 22] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K45_PE_RE]) // S45 Re | |||
|
175 | - (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 23] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K45_PE_IM]); // S45 Im | |||
|
176 | ||||
|
177 | significand = frexpf(PSDE, &exponent); // 0.5 <= significand < 1 | |||
|
178 | // PSDE = significand * 2^exponent | |||
|
179 | ||||
|
180 | if (exponent < expmin) { // value should be >= 0.5 * 2^expmin | |||
|
181 | exponent = expmin; | |||
|
182 | significand = 0.5; // min value that can be recorded | |||
|
183 | } | |||
|
184 | if (exponent > expmax) { // value should be < 0.5 * 2^(expmax+1) | |||
|
185 | exponent = expmax; | |||
|
186 | significand = 1.0; // max value that can be recorded | |||
|
187 | } | |||
|
188 | if (significand == 0) {// in that case exponent == 0 too | |||
|
189 | exponent = expmin; | |||
|
190 | significand = 0.5; // min value that can be recorded | |||
|
191 | } | |||
|
192 | ||||
|
193 | psd = (uint16_t) ((((significand*2)-1)*rangesig) + 0.5); // Shift and cast into a 16-bit unsigned int with rounding | |||
|
194 | // where just the first nbitsig bits are used (0, ..., 2^nbitsig-1) | |||
|
195 | exp = (uint16_t) (exponent-expmin); // Shift and cast into a 16-bit unsigned int where just | |||
|
196 | // the first nbitexp bits are used (0, ..., 2^nbitexp-1) | |||
|
197 | tmp_uint16 = psd | (exp << nbitsig); // Put the exponent bits (nbitexp) next to the | |||
|
198 | // left place of the significand bits (nbitsig), | |||
|
199 | // making the 16-bit word to be recorded | |||
|
200 | pt_uint8 = (uint8_t*) &tmp_uint16; // Affect an uint8_t pointer with the adress of tmp_uint16 | |||
|
201 | #ifdef MSB_FIRST_TCH | |||
|
202 | lfr_bp1[(i*NB_BYTES_BP1) + 0] = pt_uint8[0]; // Record MSB of tmp_uint16 | |||
|
203 | lfr_bp1[(i*NB_BYTES_BP1) + 1] = pt_uint8[1]; // Record LSB of tmp_uint16 | |||
|
204 | #endif | |||
|
205 | #ifdef LSB_FIRST_TCH | |||
|
206 | lfr_bp1[(i*NB_BYTES_BP1) + 0] = pt_uint8[1]; // Record MSB of tmp_uint16 | |||
|
207 | lfr_bp1[(i*NB_BYTES_BP1) + 1] = pt_uint8[0]; // Record LSB of tmp_uint16 | |||
|
208 | #endif | |||
|
209 | #ifdef DEBUG_TCH | |||
|
210 | printf("PSDE : %16.8e\n",PSDE); | |||
|
211 | printf("significand : %16.8e\n",significand); | |||
|
212 | printf("exponent : %d\n" ,exponent); | |||
|
213 | printf("psd for PSDE significand : %d\n",psd); | |||
|
214 | printf("exp for PSDE exponent : %d\n",exp); | |||
|
215 | printf("pt_uint8[1] for PSDE exponent + significand: %.3d or %.2x\n",pt_uint8[1], pt_uint8[1]); | |||
|
216 | printf("pt_uint8[0] for PSDE significand: %.3d or %.2x\n",pt_uint8[0], pt_uint8[0]); | |||
|
217 | printf("lfr_bp1[i*NB_BYTES_BP1+0] : %.3d or %.2x\n",lfr_bp1[i*NB_BYTES_BP1+0], lfr_bp1[i*NB_BYTES_BP1+0]); | |||
|
218 | printf("lfr_bp1[i*NB_BYTES_BP1+1] : %.3d or %.2x\n",lfr_bp1[i*NB_BYTES_BP1+1], lfr_bp1[i*NB_BYTES_BP1+1]); | |||
|
219 | #endif | |||
|
220 | //============================================================================== | |||
|
221 | // BP1 normal wave vector == PA_LFR_SC_BP1_NVEC_V0_F0 == 8 bits | |||
|
222 | // == PA_LFR_SC_BP1_NVEC_V1_F0 == 8 bits | |||
|
223 | // == PA_LFR_SC_BP1_NVEC_V2_F0 == 1 sign bit | |||
|
224 | tmp = sqrt( (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 2] *compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 2]) //Im S12 | |||
|
225 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 4] *compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 4]) //Im S13 | |||
|
226 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 11]*compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 11]) //Im S23 | |||
|
227 | ); | |||
|
228 | if (tmp != 0.) { // no division by 0. | |||
|
229 | NVEC_V0 = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 11] / tmp; // S23 Im => n1 | |||
|
230 | NVEC_V1 = (-compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 4]) / tmp; // S13 Im => n2 | |||
|
231 | NVEC_V2 = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 2] / tmp; // S12 Im => n3 | |||
|
232 | } | |||
|
233 | else | |||
|
234 | { | |||
|
235 | NVEC_V0 = 0.; | |||
|
236 | NVEC_V1 = 0.; | |||
|
237 | NVEC_V2 = 0.; | |||
|
238 | } | |||
|
239 | lfr_bp1[(i*NB_BYTES_BP1) + 4] = (uint8_t) ((NVEC_V0*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
240 | lfr_bp1[(i*NB_BYTES_BP1) + 5] = (uint8_t) ((NVEC_V1*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
241 | pt_uint8 = (uint8_t*) &NVEC_V2; // Affect an uint8_t pointer with the adress of NVEC_V2 | |||
|
242 | #ifdef LSB_FIRST_TCH | |||
|
243 | lfr_bp1[(i*NB_BYTES_BP1) + 6] = pt_uint8[3] & 0x80; // Extract the sign bit of NVEC_V2 (32-bit float, sign bit in the 4th octet:PC convention) | |||
|
244 | // Record it at the 8th bit position (from the right to the left) of lfr_bp1[i*NB_BYTES_BP1+6] | |||
|
245 | #endif | |||
|
246 | #ifdef MSB_FIRST_TCH | |||
|
247 | lfr_bp1[(i*NB_BYTES_BP1) + 6] = pt_uint8[0] & 0x80; // Extract the sign bit of NVEC_V2 (32-bit float, sign bit in the 1th octet:SPARC convention) | |||
|
248 | // Record it at the 8th bit position (from the right to the left) of lfr_bp1[i*NB_BYTES_BP1+6] | |||
|
249 | #endif | |||
|
250 | #ifdef DEBUG_TCH | |||
|
251 | printf("NVEC_V0 : %16.8e\n",NVEC_V0); | |||
|
252 | printf("NVEC_V1 : %16.8e\n",NVEC_V1); | |||
|
253 | printf("NVEC_V2 : %16.8e\n",NVEC_V2); | |||
|
254 | printf("lfr_bp1[i*NB_BYTES_BP1+4] for NVEC_V0 : %u\n",lfr_bp1[i*NB_BYTES_BP1+4]); | |||
|
255 | printf("lfr_bp1[i*NB_BYTES_BP1+5] for NVEC_V1 : %u\n",lfr_bp1[i*NB_BYTES_BP1+5]); | |||
|
256 | printf("lfr_bp1[i*NB_BYTES_BP1+6] for NVEC_V2 : %u\n",lfr_bp1[i*NB_BYTES_BP1+6]); | |||
|
257 | #endif | |||
|
258 | //======================================================= | |||
|
259 | // BP1 ellipticity == PA_LFR_SC_BP1_ELLIP_F0 == 4 bits | |||
|
260 | if (PSDB != 0.) { // no division by 0. | |||
|
261 | aux = 2*tmp / PSDB; // Compute the ellipticity | |||
|
262 | } | |||
|
263 | else | |||
|
264 | { | |||
|
265 | aux = 0.; | |||
|
266 | } | |||
|
267 | tmp_uint8 = (uint8_t) ((aux*15) + 0.5); // Shift and cast into a 8-bit uint8_t with rounding | |||
|
268 | // where just the first 4 bits are used (0, ..., 15) | |||
|
269 | lfr_bp1[(i*NB_BYTES_BP1) + 6] = lfr_bp1[(i*NB_BYTES_BP1) + 6] | (tmp_uint8 << 3); // Put these 4 bits next to the right place | |||
|
270 | // of the sign bit of NVEC_V2 (recorded | |||
|
271 | // previously in lfr_bp1[i*NB_BYTES_BP1+6]) | |||
|
272 | #ifdef DEBUG_TCH | |||
|
273 | printf("ellipticity : %16.8e\n",aux); | |||
|
274 | printf("tmp_uint8 for ellipticity : %u\n",tmp_uint8); | |||
|
275 | printf("lfr_bp1[i*NB_BYTES_BP1+6] for NVEC_V2 + ellipticity : %u\n",lfr_bp1[i*NB_BYTES_BP1+6]); | |||
|
276 | #endif | |||
|
277 | //============================================================== | |||
|
278 | // BP1 degree of polarization == PA_LFR_SC_BP1_DOP_F0 == 3 bits | |||
|
279 | tr_SB_SB = (compressed_spec_mat[i*NB_VALUES_PER_SPECTRAL_MATRIX] * compressed_spec_mat[i*NB_VALUES_PER_SPECTRAL_MATRIX]) | |||
|
280 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 9] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 9]) | |||
|
281 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 16] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 16]) | |||
|
282 | + (2 * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 1] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 1]) | |||
|
283 | + (2 * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 2] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 2]) | |||
|
284 | + (2 * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 3] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 3]) | |||
|
285 | + (2 * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 4] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 4]) | |||
|
286 | + (2 * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 10]* compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 10]) | |||
|
287 | + (2 * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 11]* compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 11]); | |||
|
288 | aux = PSDB*PSDB; | |||
|
289 | if (aux != 0.) { // no division by 0. | |||
|
290 | tmp = ( 3*tr_SB_SB - aux ) / ( 2 * aux ); // Compute the degree of polarisation | |||
|
291 | } | |||
|
292 | else | |||
|
293 | { | |||
|
294 | tmp = 0.; | |||
|
295 | } | |||
|
296 | tmp_uint8 = (uint8_t) ((tmp*7) + 0.5); // Shift and cast into a 8-bit uint8_t with rounding | |||
|
297 | // where just the first 3 bits are used (0, ..., 7) | |||
|
298 | lfr_bp1[(i*NB_BYTES_BP1) + 6] = lfr_bp1[(i*NB_BYTES_BP1) + 6] | tmp_uint8; // Record these 3 bits at the 3 first bit positions | |||
|
299 | // (from the right to the left) of lfr_bp1[i*NB_BYTES_BP1+6] | |||
|
300 | #ifdef DEBUG_TCH | |||
|
301 | printf("DOP : %16.8e\n",tmp); | |||
|
302 | printf("tmp_uint8 for DOP : %u\n",tmp_uint8); | |||
|
303 | printf("lfr_bp1[i*NB_BYTES_BP1+6] for NVEC_V2 + ellipticity + DOP : %u\n",lfr_bp1[i*NB_BYTES_BP1+6]); | |||
|
304 | #endif | |||
|
305 | //======================================================================================= | |||
|
306 | // BP1 X_SO-component of the Poynting flux == PA_LFR_SC_BP1_SX_F0 == 16 bits | |||
|
307 | // = 1 sign bit + 1 argument bit (two sectors) | |||
|
308 | // + 6 bits (exponent) + 8 bits (significand) | |||
|
309 | e_cross_b_re = (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 17] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K34_SX_RE]) //S34 Re | |||
|
310 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 19] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K35_SX_RE]) //S35 Re | |||
|
311 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 5] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K14_SX_RE]) //S14 Re | |||
|
312 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 7] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K15_SX_RE]) //S15 Re | |||
|
313 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 12] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K24_SX_RE]) //S24 Re | |||
|
314 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 14] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K25_SX_RE]) //S25 Re | |||
|
315 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 18] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K34_SX_IM]) //S34 Im | |||
|
316 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 20] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K35_SX_IM]) //S35 Im | |||
|
317 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 6] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K14_SX_IM]) //S14 Im | |||
|
318 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 8] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K15_SX_IM]) //S15 Im | |||
|
319 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 13] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K24_SX_IM]) //S24 Im | |||
|
320 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 15] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K25_SX_IM]); //S25 Im | |||
|
321 | // Im(S_ji) = -Im(S_ij) | |||
|
322 | // k_ji = k_ij | |||
|
323 | e_cross_b_im = (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 17]*k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K34_SX_IM]) //S34 Re | |||
|
324 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 19]*k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K35_SX_IM]) //S35 Re | |||
|
325 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 5] *k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K14_SX_IM]) //S14 Re | |||
|
326 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 7] *k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K15_SX_IM]) //S15 Re | |||
|
327 | + (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 12]*k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K24_SX_IM]) //S24 Re | |||
|
328 | + ((compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 14]*k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K25_SX_IM]) //S25 Re | |||
|
329 | - (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 18]*k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K34_SX_RE]) //S34 Im | |||
|
330 | - (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 20]*k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K35_SX_RE]) //S35 Im | |||
|
331 | - (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 6] *k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K14_SX_RE]) //S14 Im | |||
|
332 | - (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 8] *k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K15_SX_RE]) //S15 Im | |||
|
333 | - (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 13]*k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K24_SX_RE]) //S24 Im | |||
|
334 | - (compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 15]*k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K25_SX_RE])); //S25 Im | |||
|
335 | #ifdef DEBUG_TCH | |||
|
336 | printf("ReaSX : %16.8e\n",e_cross_b_re); | |||
|
337 | #endif | |||
|
338 | pt_uint8 = (uint8_t*) &e_cross_b_re; // Affect an uint8_t pointer with the adress of e_cross_b_re | |||
|
339 | #ifdef LSB_FIRST_TCH | |||
|
340 | ||||
|
341 | lfr_bp1[(i*NB_BYTES_BP1) + 7] = (uint8_t) (pt_uint8[3] & 0x80); // Extract its sign bit (32-bit float, sign bit in the 4th octet:PC convention) | |||
|
342 | // Record it at the 8th bit position (from the right to the left) | |||
|
343 | // of lfr_bp1[i*NB_BYTES_BP1+7] | |||
|
344 | pt_uint8[3] = (pt_uint8[3] & 0x7f); // Make e_cross_b_re be positive in any case: |ReaSX| | |||
|
345 | #endif | |||
|
346 | #ifdef MSB_FIRST_TCH | |||
|
347 | lfr_bp1[(i*NB_BYTES_BP1) + 7] = (uint8_t) (pt_uint8[0] & 0x80); // Extract its sign bit (32-bit float, sign bit in the 1th octet:SPARC convention) | |||
|
348 | // Record it at the 8th bit position (from the right to the left) | |||
|
349 | // of lfr_bp1[i*NB_BYTES_BP1+7] | |||
|
350 | pt_uint8[0] = (pt_uint8[0] & 0x7f); // Make e_cross_b_re be positive in any case: |ReaSX| | |||
|
351 | #endif | |||
|
352 | significand = frexpf(e_cross_b_re, &exponent); // 0.5 <= significand < 1 | |||
|
353 | // ReaSX = significand * 2^exponent | |||
|
354 | if (exponent < expmin) { // value should be >= 0.5 * 2^expmin | |||
|
355 | exponent = expmin; | |||
|
356 | significand = 0.5; // min value that can be recorded | |||
|
357 | } | |||
|
358 | if (exponent > expmax) { // value should be < 0.5 * 2^(expmax+1) | |||
|
359 | exponent = expmax; | |||
|
360 | significand = 1.0; // max value that can be recorded | |||
|
361 | } | |||
|
362 | if (significand == 0) { // in that case exponent == 0 too | |||
|
363 | exponent = expmin; | |||
|
364 | significand = 0.5; // min value that can be recorded | |||
|
365 | } | |||
|
366 | ||||
|
367 | lfr_bp1[(i*NB_BYTES_BP1) + 8] = (uint8_t) ((((significand*2)-1)*255) + 0.5); // Shift and cast into a 8-bit uint8_t with rounding | |||
|
368 | // where all bits are used (0, ..., 255) | |||
|
369 | tmp_uint8 = (uint8_t) (exponent-expmin); // Shift and cast into a 8-bit uint8_t where | |||
|
370 | // just the first nbitexp bits are used (0, ..., 2^nbitexp-1) | |||
|
371 | #ifdef DEBUG_TCH | |||
|
372 | printf("|ReaSX| : %16.8e\n",e_cross_b_re); | |||
|
373 | printf("significand : %16.8e\n",significand); | |||
|
374 | printf("exponent : %d\n" ,exponent); | |||
|
375 | printf("tmp_uint8 for ReaSX exponent : %d\n",tmp_uint8); | |||
|
376 | #endif | |||
|
377 | lfr_bp1[(i*NB_BYTES_BP1) + 7] = lfr_bp1[(i*NB_BYTES_BP1) + 7] | tmp_uint8; // Record these nbitexp bits in the nbitexp first bits | |||
|
378 | // (from the right to the left) of lfr_bp1[i*NB_BYTES_BP1+7] | |||
|
379 | #ifdef DEBUG_TCH | |||
|
380 | printf("lfr_bp1[i*NB_BYTES_BP1+7] for ReaSX sign + RealSX exponent : %u\n",lfr_bp1[i*NB_BYTES_BP1+7]); | |||
|
381 | printf("lfr_bp1[i*NB_BYTES_BP1+8] for ReaSX significand : %u\n",lfr_bp1[i*NB_BYTES_BP1+8]); | |||
|
382 | printf("ImaSX : %16.8e\n",e_cross_b_im); | |||
|
383 | #endif | |||
|
384 | pt_uint8 = (uint8_t*) &e_cross_b_im; // Affect an uint8_t pointer with the adress of e_cross_b_im | |||
|
385 | #ifdef LSB_FIRST_TCH | |||
|
386 | pt_uint8[3] = pt_uint8[3] & 0x7f; // Make e_cross_b_im be positive in any case: |ImaSX| (32-bit float, sign bit in the 4th octet:PC convention) | |||
|
387 | #endif | |||
|
388 | #ifdef MSB_FIRST_TCH | |||
|
389 | pt_uint8[0] = pt_uint8[0] & 0x7f; // Make e_cross_b_im be positive in any case: |ImaSX| (32-bit float, sign bit in the 1th octet:SPARC convention) | |||
|
390 | #endif | |||
|
391 | // Determine the sector argument of SX. If |Im| > |Re| affect | |||
|
392 | // an unsigned 8-bit char with 01000000; otherwise with null. | |||
|
393 | if (e_cross_b_im > e_cross_b_re) { | |||
|
394 | tmp_uint8 = 0x40; | |||
|
395 | } | |||
|
396 | else { | |||
|
397 | tmp_uint8 = 0x00; | |||
|
398 | } | |||
|
399 | ||||
|
400 | lfr_bp1[(i*NB_BYTES_BP1) + 7] = lfr_bp1[(i*NB_BYTES_BP1) + 7] | tmp_uint8; // Record it as a sign bit at the 7th bit position (from the right | |||
|
401 | // to the left) of lfr_bp1[i*NB_BYTES_BP1+7], by simple logical addition. | |||
|
402 | #ifdef DEBUG_TCH | |||
|
403 | printf("|ImaSX| : %16.8e\n",e_cross_b_im); | |||
|
404 | printf("ArgSX sign : %u\n",tmp_uint8); | |||
|
405 | printf("lfr_bp1[i*NB_BYTES_BP1+7] for ReaSX & ArgSX signs + ReaSX exponent : %u\n",lfr_bp1[i*NB_BYTES_BP1+7]); | |||
|
406 | #endif | |||
|
407 | //====================================================================== | |||
|
408 | // BP1 phase velocity estimator == PA_LFR_SC_BP1_VPHI_F0 == 16 bits | |||
|
409 | // = 1 sign bit + 1 argument bit (two sectors) | |||
|
410 | // + 6 bits (exponent) + 8 bits (significand) | |||
|
411 | ny = (sin(alpha_M)*NVEC_V1) + (cos(alpha_M)*NVEC_V2); | |||
|
412 | nz = NVEC_V0; | |||
|
413 | bx_bx_star = (cos(alpha_M)*cos(alpha_M)*compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 9]) // S22 Re | |||
|
414 | + ((sin(alpha_M)*sin(alpha_M)*compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 16]) // S33 Re | |||
|
415 | - (2*sin(alpha_M)*cos(alpha_M)*compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 10])); // S23 Re | |||
|
416 | ||||
|
417 | n_cross_e_scal_b_re = (ny * ((compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 12] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K24_NY_RE]) //S24 Re | |||
|
418 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 14] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K25_NY_RE]) //S25 Re | |||
|
419 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 17] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K34_NY_RE]) //S34 Re | |||
|
420 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 19] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K35_NY_RE]) //S35 Re | |||
|
421 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 13] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K24_NY_IM]) //S24 Im | |||
|
422 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 15] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K25_NY_IM]) //S25 Im | |||
|
423 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 18] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K34_NY_IM]) //S34 Im | |||
|
424 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 20] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K35_NY_IM]))) //S35 Im | |||
|
425 | + (nz * ((compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 12] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K24_NZ_RE]) //S24 Re | |||
|
426 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 14] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K25_NZ_RE]) //S25 Re | |||
|
427 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 17] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K34_NZ_RE]) //S34 Re | |||
|
428 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 19] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K35_NZ_RE]) //S35 Re | |||
|
429 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 13] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K24_NZ_IM]) //S24 Im | |||
|
430 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 15] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K25_NZ_IM]) //S25 Im | |||
|
431 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 18] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K34_NZ_IM]) //S34 Im | |||
|
432 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 20] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K35_NZ_IM])));//S35 Im | |||
|
433 | // Im(S_ji) = -Im(S_ij) | |||
|
434 | // k_ji = k_ij | |||
|
435 | n_cross_e_scal_b_im = (ny * ((compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 12] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K24_NY_IM]) //S24 Re | |||
|
436 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 14] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K25_NY_IM]) //S25 Re | |||
|
437 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 17] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K34_NY_IM]) //S34 Re | |||
|
438 | +((compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 19] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K35_NY_IM]) //S35 Re | |||
|
439 | -(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 13] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K24_NY_RE]) //S24 Im | |||
|
440 | -(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 15] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K25_NY_RE]) //S25 Im | |||
|
441 | -(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 18] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K34_NY_RE]) //S34 Im | |||
|
442 | -(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 20] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K35_NY_RE])))) //S35 Im | |||
|
443 | + (nz * ((compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 12] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K24_NZ_IM]) //S24 Re | |||
|
444 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 14] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K25_NZ_IM]) //S25 Re | |||
|
445 | +(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 17] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K34_NZ_IM] ) //S34 Re | |||
|
446 | +((compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 19] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K35_NZ_IM]) //S35 Re | |||
|
447 | -(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 13] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K24_NZ_RE]) //S24 Im | |||
|
448 | -(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 15] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K25_NZ_RE]) //S25 Im | |||
|
449 | -(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 18] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K34_NZ_RE]) //S34 Im | |||
|
450 | -(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 20] * k_coeff_intercalib[(i*NB_K_COEFF_PER_BIN) + K35_NZ_RE]))));//S35 Im | |||
|
451 | #ifdef DEBUG_TCH | |||
|
452 | printf("n_cross_e_scal_b_re : %16.8e\n",n_cross_e_scal_b_re); | |||
|
453 | printf("n_cross_e_scal_b_im : %16.8e\n",n_cross_e_scal_b_im); | |||
|
454 | #endif | |||
|
455 | // vphi = n_cross_e_scal_b_re / bx_bx_star => sign(VPHI) = sign(n_cross_e_scal_b_re) | |||
|
456 | pt_uint8 = (uint8_t*) &n_cross_e_scal_b_re; // Affect an uint8_t pointer with the adress of n_cross_e_scal_b_re | |||
|
457 | #ifdef LSB_FIRST_TCH | |||
|
458 | lfr_bp1[(i*NB_BYTES_BP1) + 9] = (uint8_t) (pt_uint8[3] & 0x80); // Extract its sign bit (32-bit float, sign bit in the 4th octet:PC convention) | |||
|
459 | // Record it at the 8th bit position (from the right to the left) | |||
|
460 | // of lfr_bp1[i*NB_BYTES_BP1+9] | |||
|
461 | pt_uint8[3] = (pt_uint8[3] & 0x7f); // Make n_cross_e_scal_b_re be positive in any case: |n_cross_e_scal_b_re| | |||
|
462 | #endif | |||
|
463 | #ifdef MSB_FIRST_TCH | |||
|
464 | lfr_bp1[(i*NB_BYTES_BP1) + 9] = (uint8_t) (pt_uint8[0] & 0x80); // Extract its sign bit (32-bit float, sign bit in the 1th octet:SPARC convention) | |||
|
465 | // Record it at the 8th bit position (from the right to the left) | |||
|
466 | // of lfr_bp1[i*NB_BYTES_BP1+9] | |||
|
467 | pt_uint8[0] = (pt_uint8[0] & 0x7f); // Make n_cross_e_scal_b_re be positive in any case: |n_cross_e_scal_b_re| | |||
|
468 | #endif | |||
|
469 | if (bx_bx_star != 0.) { // no division by 0. | |||
|
470 | vphi = n_cross_e_scal_b_re / bx_bx_star; // Compute |VPHI| | |||
|
471 | } | |||
|
472 | else | |||
|
473 | { | |||
|
474 | vphi = 1.e+20; // Put a huge value | |||
|
475 | } | |||
|
476 | significand = frexpf(vphi, &exponent); // 0.5 <= significand < 1 | |||
|
477 | // vphi = significand * 2^exponent | |||
|
478 | if (exponent < expmin) { // value should be >= 0.5 * 2^expmin | |||
|
479 | exponent = expmin; | |||
|
480 | significand = 0.5; // min value that can be recorded | |||
|
481 | } | |||
|
482 | if (exponent > expmax) { // value should be < 0.5 * 2^(expmax+1) | |||
|
483 | exponent = expmax; | |||
|
484 | significand = 1.0; // max value that can be recorded | |||
|
485 | } | |||
|
486 | if (significand == 0) {// in that case exponent == 0 too | |||
|
487 | exponent = expmin; | |||
|
488 | significand = 0.5; // min value that can be recorded | |||
|
489 | } | |||
|
490 | ||||
|
491 | lfr_bp1[(i*NB_BYTES_BP1) + 10] = (uint8_t) ((((significand*2)-1)*255) + 0.5); // Shift and cast into a 8-bit uint8_t with rounding | |||
|
492 | // where all the bits are used (0, ..., 255) | |||
|
493 | tmp_uint8 = (uint8_t) (exponent-expmin); // Shift and cast into a 8-bit uint8_t where | |||
|
494 | // just the first nbitexp bits are used (0, ..., 2^nbitexp-1) | |||
|
495 | #ifdef DEBUG_TCH | |||
|
496 | printf("|VPHI| : %16.8e\n",vphi); | |||
|
497 | printf("significand : %16.8e\n",significand); | |||
|
498 | printf("exponent : %d\n" ,exponent); | |||
|
499 | printf("tmp_uint8 for VPHI exponent : %d\n",tmp_uint8); | |||
|
500 | #endif | |||
|
501 | lfr_bp1[(i*NB_BYTES_BP1) + 9] = lfr_bp1[(i*NB_BYTES_BP1) + 9] | tmp_uint8; // Record these nbitexp bits in the nbitexp first bits | |||
|
502 | // (from the right to the left) of lfr_bp1[i*NB_BYTES_BP1+9] | |||
|
503 | #ifdef DEBUG_TCH | |||
|
504 | printf("lfr_bp1[i*NB_BYTES_BP1+9] for VPHI sign + VPHI exponent : %u\n",lfr_bp1[i*NB_BYTES_BP1+9]); | |||
|
505 | printf("lfr_bp1[i*NB_BYTES_BP1+10] for VPHI significand : %u\n",lfr_bp1[i*NB_BYTES_BP1+10]); | |||
|
506 | #endif | |||
|
507 | pt_uint8 = (uint8_t*) &n_cross_e_scal_b_im; // Affect an uint8_t pointer with the adress of n_cross_e_scal_b_im | |||
|
508 | #ifdef LSB_FIRST_TCH | |||
|
509 | pt_uint8[3] = pt_uint8[3] & 0x7f; // Make n_cross_e_scal_b_im be positive in any case: |ImaNEBX| (32-bit float, sign bit in the 4th octet:PC convention) | |||
|
510 | #endif | |||
|
511 | #ifdef MSB_FIRST_TCH | |||
|
512 | pt_uint8[0] = pt_uint8[0] & 0x7f; // Make n_cross_e_scal_b_im be positive in any case: |ImaNEBX| (32-bit float, sign bit in the 1th octet:SPARC convention) | |||
|
513 | #endif | |||
|
514 | ||||
|
515 | // Determine the sector argument of NEBX. If |Im| > |Re| affect | |||
|
516 | // an unsigned 8-bit char with 01000000; otherwise with null. | |||
|
517 | if (n_cross_e_scal_b_im > n_cross_e_scal_b_re) { | |||
|
518 | tmp_uint8 = 0x40; | |||
|
519 | } | |||
|
520 | else { | |||
|
521 | tmp_uint8 = 0x00; | |||
|
522 | } | |||
|
523 | ||||
|
524 | lfr_bp1[(i*NB_BYTES_BP1) + 9] = lfr_bp1[(i*NB_BYTES_BP1) + 9] | tmp_uint8; // Record it as a sign bit at the 7th bit position (from the right | |||
|
525 | // to the left) of lfr_bp1[i*NB_BYTES_BP1+9], by simple logical addition. | |||
|
526 | #ifdef DEBUG_TCH | |||
|
527 | printf("|n_cross_e_scal_b_im| : %16.8e\n",n_cross_e_scal_b_im); | |||
|
528 | printf("|n_cross_e_scal_b_im|/bx_bx_star : %16.8e\n",n_cross_e_scal_b_im/bx_bx_star); | |||
|
529 | printf("ArgNEBX sign : %u\n",tmp_uint8); | |||
|
530 | printf("lfr_bp1[i*NB_BYTES_BP1+9] for VPHI & ArgNEBX signs + VPHI exponent : %u\n",lfr_bp1[i*NB_BYTES_BP1+9]); | |||
|
531 | #endif | |||
|
532 | } | |||
|
533 | } | |||
|
534 | ||||
|
535 | void BP2_set(float *compressed_spec_mat, uint8_t nb_bins_compressed_spec_mat, uint8_t *lfr_bp2) | |||
|
536 | { | |||
|
537 | float cross_re; // 32-bit floating point | |||
|
538 | float cross_im; | |||
|
539 | float aux; | |||
|
540 | float significand; | |||
|
541 | int exponent; // 32-bit signed integer | |||
|
542 | uint8_t nbitexp; // 8-bit unsigned integer | |||
|
543 | uint8_t nbitsig; | |||
|
544 | uint8_t *pt_uint8; // pointer on unsigned 8-bit integer | |||
|
545 | int8_t expmin; // 8-bit signed integer | |||
|
546 | int8_t expmax; | |||
|
547 | uint16_t rangesig; // 16-bit unsigned integer | |||
|
548 | uint16_t autocor; | |||
|
549 | uint16_t exp; | |||
|
550 | uint16_t tmp_uint16; | |||
|
551 | uint16_t i; | |||
|
552 | ||||
|
553 | #ifdef DEBUG_TCH | |||
|
554 | printf("BP2 : \n"); | |||
|
555 | printf("Number of bins: %d\n", nb_bins_compressed_spec_mat); | |||
|
556 | #endif | |||
|
557 | ||||
|
558 | // For floating point data to be recorded on 16-bit words : | |||
|
559 | nbitexp = 6; // number of bits for the exponent | |||
|
560 | nbitsig = 16 - nbitexp; // number of bits for the significand | |||
|
561 | rangesig = (1 << nbitsig)-1; // == 2^nbitsig - 1 | |||
|
562 | expmax = 32 + 5; | |||
|
563 | expmin = (expmax - (1 << nbitexp)) + 1; | |||
|
564 | ||||
|
565 | #ifdef DEBUG_TCH | |||
|
566 | ||||
|
567 | printf("nbitexp : %d, expmax : %d, expmin : %d\n", nbitexp, expmax, expmin); | |||
|
568 | printf("nbitsig : %d, rangesig : %d\n", nbitsig, rangesig); | |||
|
569 | #endif | |||
|
570 | ||||
|
571 | for(i = 0; i<nb_bins_compressed_spec_mat; i++){ | |||
|
572 | //============================================== | |||
|
573 | // BP2 normalized cross correlations == PA_LFR_SC_BP2_CROSS_F0 == 10 * (8+8) bits | |||
|
574 | // == PA_LFR_SC_BP2_CROSS_RE_0_F0 == 8 bits | |||
|
575 | // == PA_LFR_SC_BP2_CROSS_IM_0_F0 == 8 bits | |||
|
576 | // == PA_LFR_SC_BP2_CROSS_RE_1_F0 == 8 bits | |||
|
577 | // == PA_LFR_SC_BP2_CROSS_IM_1_F0 == 8 bits | |||
|
578 | // == PA_LFR_SC_BP2_CROSS_RE_2_F0 == 8 bits | |||
|
579 | // == PA_LFR_SC_BP2_CROSS_IM_2_F0 == 8 bits | |||
|
580 | // == PA_LFR_SC_BP2_CROSS_RE_3_F0 == 8 bits | |||
|
581 | // == PA_LFR_SC_BP2_CROSS_IM_3_F0 == 8 bits | |||
|
582 | // == PA_LFR_SC_BP2_CROSS_RE_4_F0 == 8 bits | |||
|
583 | // == PA_LFR_SC_BP2_CROSS_IM_4_F0 == 8 bits | |||
|
584 | // == PA_LFR_SC_BP2_CROSS_RE_5_F0 == 8 bits | |||
|
585 | // == PA_LFR_SC_BP2_CROSS_IM_5_F0 == 8 bits | |||
|
586 | // == PA_LFR_SC_BP2_CROSS_RE_6_F0 == 8 bits | |||
|
587 | // == PA_LFR_SC_BP2_CROSS_IM_6_F0 == 8 bits | |||
|
588 | // == PA_LFR_SC_BP2_CROSS_RE_7_F0 == 8 bits | |||
|
589 | // == PA_LFR_SC_BP2_CROSS_IM_7_F0 == 8 bits | |||
|
590 | // == PA_LFR_SC_BP2_CROSS_RE_8_F0 == 8 bits | |||
|
591 | // == PA_LFR_SC_BP2_CROSS_IM_8_F0 == 8 bits | |||
|
592 | // == PA_LFR_SC_BP2_CROSS_RE_9_F0 == 8 bits | |||
|
593 | // == PA_LFR_SC_BP2_CROSS_IM_9_F0 == 8 bits | |||
|
594 | // S12 | |||
|
595 | aux = sqrt(compressed_spec_mat[i*NB_VALUES_PER_SPECTRAL_MATRIX] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 9]); | |||
|
596 | if (aux != 0.) { // no division by 0. | |||
|
597 | cross_re = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 1] / aux; | |||
|
598 | cross_im = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 2] / aux; | |||
|
599 | } | |||
|
600 | else | |||
|
601 | { | |||
|
602 | cross_re = 0.; | |||
|
603 | cross_im = 0.; | |||
|
604 | } | |||
|
605 | lfr_bp2[(i*NB_BYTES_BP2) + 10] = (uint8_t) ((cross_re*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
606 | lfr_bp2[(i*NB_BYTES_BP2) + 20] = (uint8_t) ((cross_im*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
607 | #ifdef DEBUG_TCH | |||
|
608 | printf("\nBin number: %d\n", i); | |||
|
609 | printf("lfr_bp2[i*NB_BYTES_BP2+10] for cross12_re (%16.8e) : %.3u\n",cross_re, lfr_bp2[i*NB_BYTES_BP2+10]); | |||
|
610 | printf("lfr_bp2[i*NB_BYTES_BP2+20] for cross12_im (%16.8e) : %.3u\n",cross_im, lfr_bp2[i*NB_BYTES_BP2+20]); | |||
|
611 | #endif | |||
|
612 | // S13 | |||
|
613 | aux = sqrt(compressed_spec_mat[i*NB_VALUES_PER_SPECTRAL_MATRIX] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 16]); | |||
|
614 | if (aux != 0.) { // no division by 0. | |||
|
615 | cross_re = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 3] / aux; | |||
|
616 | cross_im = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 4] / aux; | |||
|
617 | } | |||
|
618 | else | |||
|
619 | { | |||
|
620 | cross_re = 0.; | |||
|
621 | cross_im = 0.; | |||
|
622 | } | |||
|
623 | lfr_bp2[(i*NB_BYTES_BP2) + 11] = (uint8_t) ((cross_re*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
624 | lfr_bp2[(i*NB_BYTES_BP2) + 21] = (uint8_t) ((cross_im*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
625 | #ifdef DEBUG_TCH | |||
|
626 | printf("lfr_bp2[i*NB_BYTES_BP2+11] for cross13_re (%16.8e) : %.3u\n",cross_re, lfr_bp2[i*NB_BYTES_BP2+11]); | |||
|
627 | printf("lfr_bp2[i*NB_BYTES_BP2+21] for cross13_im (%16.8e) : %.3u\n",cross_im, lfr_bp2[i*NB_BYTES_BP2+21]); | |||
|
628 | #endif | |||
|
629 | // S14 | |||
|
630 | aux = sqrt(compressed_spec_mat[i*NB_VALUES_PER_SPECTRAL_MATRIX] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 21]); | |||
|
631 | if (aux != 0.) { // no division by 0. | |||
|
632 | cross_re = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 5] / aux; | |||
|
633 | cross_im = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 6] / aux; | |||
|
634 | } | |||
|
635 | else | |||
|
636 | { | |||
|
637 | cross_re = 0.; | |||
|
638 | cross_im = 0.; | |||
|
639 | } | |||
|
640 | lfr_bp2[(i*NB_BYTES_BP2) + 12] = (uint8_t) ((cross_re*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
641 | lfr_bp2[(i*NB_BYTES_BP2) + 22] = (uint8_t) ((cross_im*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
642 | #ifdef DEBUG_TCH | |||
|
643 | printf("lfr_bp2[i*NB_BYTES_BP2+12] for cross14_re (%16.8e) : %.3u\n",cross_re, lfr_bp2[i*NB_BYTES_BP2+12]); | |||
|
644 | printf("lfr_bp2[i*NB_BYTES_BP2+22] for cross14_im (%16.8e) : %.3u\n",cross_im, lfr_bp2[i*NB_BYTES_BP2+22]); | |||
|
645 | #endif | |||
|
646 | // S15 | |||
|
647 | aux = sqrt(compressed_spec_mat[i*NB_VALUES_PER_SPECTRAL_MATRIX] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 24]); | |||
|
648 | if (aux != 0.) { // no division by 0. | |||
|
649 | cross_re = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 7] / aux; | |||
|
650 | cross_im = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 8] / aux; | |||
|
651 | } | |||
|
652 | else | |||
|
653 | { | |||
|
654 | cross_re = 0.; | |||
|
655 | cross_im = 0.; | |||
|
656 | } | |||
|
657 | lfr_bp2[(i*NB_BYTES_BP2) + 13] = (uint8_t) ((cross_re*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
658 | lfr_bp2[(i*NB_BYTES_BP2) + 23] = (uint8_t) ((cross_im*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
659 | #ifdef DEBUG_TCH | |||
|
660 | printf("lfr_bp2[i*NB_BYTES_BP2+13] for cross15_re (%16.8e) : %.3u\n",cross_re, lfr_bp2[i*NB_BYTES_BP2+13]); | |||
|
661 | printf("lfr_bp2[i*NB_BYTES_BP2+23] for cross15_im (%16.8e) : %.3u\n",cross_im, lfr_bp2[i*NB_BYTES_BP2+23]); | |||
|
662 | #endif | |||
|
663 | // S23 | |||
|
664 | aux = sqrt(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 9] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 16]); | |||
|
665 | if (aux != 0.) { // no division by 0. | |||
|
666 | cross_re = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 10] / aux; | |||
|
667 | cross_im = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 11] / aux; | |||
|
668 | } | |||
|
669 | else | |||
|
670 | { | |||
|
671 | cross_re = 0.; | |||
|
672 | cross_im = 0.; | |||
|
673 | } | |||
|
674 | lfr_bp2[(i*NB_BYTES_BP2) + 14] = (uint8_t) ((cross_re*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
675 | lfr_bp2[(i*NB_BYTES_BP2) + 24] = (uint8_t) ((cross_im*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
676 | #ifdef DEBUG_TCH | |||
|
677 | printf("lfr_bp2[i*NB_BYTES_BP2+14] for cross23_re (%16.8e) : %.3u\n",cross_re, lfr_bp2[i*NB_BYTES_BP2+14]); | |||
|
678 | printf("lfr_bp2[i*NB_BYTES_BP2+24] for cross23_im (%16.8e) : %.3u\n",cross_im, lfr_bp2[i*NB_BYTES_BP2+24]); | |||
|
679 | #endif | |||
|
680 | // S24 | |||
|
681 | aux = sqrt(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 9] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 21]); | |||
|
682 | if (aux != 0.) { // no division by 0. | |||
|
683 | cross_re = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 12] / aux; | |||
|
684 | cross_im = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 13] / aux; | |||
|
685 | } | |||
|
686 | else | |||
|
687 | { | |||
|
688 | cross_re = 0.; | |||
|
689 | cross_im = 0.; | |||
|
690 | } | |||
|
691 | lfr_bp2[(i*NB_BYTES_BP2) + 15] = (uint8_t) ((cross_re*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
692 | lfr_bp2[(i*NB_BYTES_BP2) + 25] = (uint8_t) ((cross_im*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
693 | #ifdef DEBUG_TCH | |||
|
694 | printf("lfr_bp2[i*NB_BYTES_BP2+15] for cross24_re (%16.8e) : %.3u\n",cross_re, lfr_bp2[i*NB_BYTES_BP2+15]); | |||
|
695 | printf("lfr_bp2[i*NB_BYTES_BP2+25] for cross24_im (%16.8e) : %.3u\n",cross_im, lfr_bp2[i*NB_BYTES_BP2+25]); | |||
|
696 | #endif | |||
|
697 | // S25 | |||
|
698 | aux = sqrt(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 9] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 24]); | |||
|
699 | if (aux != 0.) { // no division by 0. | |||
|
700 | cross_re = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 14] / aux; | |||
|
701 | cross_im = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 15] / aux; | |||
|
702 | } | |||
|
703 | else | |||
|
704 | { | |||
|
705 | cross_re = 0.; | |||
|
706 | cross_im = 0.; | |||
|
707 | } | |||
|
708 | lfr_bp2[(i*NB_BYTES_BP2) + 16] = (uint8_t) ((cross_re*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
709 | lfr_bp2[(i*NB_BYTES_BP2) + 26] = (uint8_t) ((cross_im*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
710 | #ifdef DEBUG_TCH | |||
|
711 | printf("lfr_bp2[i*NB_BYTES_BP2+16] for cross25_re (%16.8e) : %.3u\n",cross_re, lfr_bp2[i*NB_BYTES_BP2+16]); | |||
|
712 | printf("lfr_bp2[i*NB_BYTES_BP2+26] for cross25_im (%16.8e) : %.3u\n",cross_im, lfr_bp2[i*NB_BYTES_BP2+26]); | |||
|
713 | #endif | |||
|
714 | // S34 | |||
|
715 | aux = sqrt(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 16] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 21]); | |||
|
716 | if (aux != 0.) { // no division by 0. | |||
|
717 | cross_re = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 17] / aux; | |||
|
718 | cross_im = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 18] / aux; | |||
|
719 | } | |||
|
720 | else | |||
|
721 | { | |||
|
722 | cross_re = 0.; | |||
|
723 | cross_im = 0.; | |||
|
724 | } | |||
|
725 | lfr_bp2[(i*NB_BYTES_BP2) + 17] = (uint8_t) ((cross_re*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
726 | lfr_bp2[(i*NB_BYTES_BP2) + 27] = (uint8_t) ((cross_im*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
727 | #ifdef DEBUG_TCH | |||
|
728 | printf("lfr_bp2[i*NB_BYTES_BP2+17] for cross34_re (%16.8e) : %.3u\n",cross_re, lfr_bp2[i*NB_BYTES_BP2+17]); | |||
|
729 | printf("lfr_bp2[i*NB_BYTES_BP2+27] for cross34_im (%16.8e) : %.3u\n",cross_im, lfr_bp2[i*NB_BYTES_BP2+27]); | |||
|
730 | #endif | |||
|
731 | // S35 | |||
|
732 | aux = sqrt(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 16] * compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 24]); | |||
|
733 | if (aux != 0.) { // no division by 0. | |||
|
734 | cross_re = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 19] / aux; | |||
|
735 | cross_im = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 20] / aux; | |||
|
736 | } | |||
|
737 | else | |||
|
738 | { | |||
|
739 | cross_re = 0.; | |||
|
740 | cross_im = 0.; | |||
|
741 | } | |||
|
742 | lfr_bp2[(i*NB_BYTES_BP2) + 18] = (uint8_t) ((cross_re*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
743 | lfr_bp2[(i*NB_BYTES_BP2) + 28] = (uint8_t) ((cross_im*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
744 | #ifdef DEBUG_TCH | |||
|
745 | printf("lfr_bp2[i*NB_BYTES_BP2+18] for cross35_re (%16.8e) : %.3u\n",cross_re, lfr_bp2[i*NB_BYTES_BP2+18]); | |||
|
746 | printf("lfr_bp2[i*NB_BYTES_BP2+28] for cross35_im (%16.8e) : %.3u\n",cross_im, lfr_bp2[i*NB_BYTES_BP2+28]); | |||
|
747 | #endif | |||
|
748 | // S45 | |||
|
749 | aux = sqrt(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 21]*compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 24]); | |||
|
750 | if (aux != 0.) { // no division by 0. | |||
|
751 | cross_re = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 22] / aux; | |||
|
752 | cross_im = compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 23] / aux; | |||
|
753 | } | |||
|
754 | else | |||
|
755 | { | |||
|
756 | cross_re = 0.; | |||
|
757 | cross_im = 0.; | |||
|
758 | } | |||
|
759 | lfr_bp2[(i*NB_BYTES_BP2) + 19] = (uint8_t) ((cross_re*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
760 | lfr_bp2[(i*NB_BYTES_BP2) + 29] = (uint8_t) ((cross_im*127.5) + 128); // Shift and cast into a 8-bit uint8_t (0, ..., 255) with rounding | |||
|
761 | #ifdef DEBUG_TCH | |||
|
762 | printf("lfr_bp2[i*NB_BYTES_BP2+19] for cross45_re (%16.8e) : %.3u\n",cross_re, lfr_bp2[i*NB_BYTES_BP2+19]); | |||
|
763 | printf("lfr_bp2[i*NB_BYTES_BP2+29] for cross45_im (%16.8e) : %.3u\n",cross_im, lfr_bp2[i*NB_BYTES_BP2+29]); | |||
|
764 | #endif | |||
|
765 | //============================================== | |||
|
766 | // BP2 auto correlations == PA_LFR_SC_BP2_AUTO_F0 == 5*16 bits = 5*[6 bits (exponent) + 10 bits (significand)] | |||
|
767 | // == PA_LFR_SC_BP2_AUTO_A0_F0 == 16 bits | |||
|
768 | // == PA_LFR_SC_BP2_AUTO_A1_F0 == 16 bits | |||
|
769 | // == PA_LFR_SC_BP2_AUTO_A2_F0 == 16 bits | |||
|
770 | // == PA_LFR_SC_BP2_AUTO_A3_F0 == 16 bits | |||
|
771 | // == PA_LFR_SC_BP2_AUTO_A4_F0 == 16 bits | |||
|
772 | // S11 | |||
|
773 | significand = frexpf(compressed_spec_mat[i*NB_VALUES_PER_SPECTRAL_MATRIX], &exponent); // 0.5 <= significand < 1 | |||
|
774 | // S11 = significand * 2^exponent | |||
|
775 | #ifdef DEBUG_TCH | |||
|
776 | printf("S11 : %16.8e\n",compressed_spec_mat[i*NB_VALUES_PER_SPECTRAL_MATRIX]); | |||
|
777 | printf("significand : %16.8e\n",significand); | |||
|
778 | printf("exponent : %d\n" ,exponent); | |||
|
779 | #endif | |||
|
780 | if (exponent < expmin) { // value should be >= 0.5 * 2^expmin | |||
|
781 | exponent = expmin; | |||
|
782 | significand = 0.5; // min value that can be recorded | |||
|
783 | } | |||
|
784 | if (exponent > expmax) { // value should be < 0.5 * 2^(expmax+1) | |||
|
785 | exponent = expmax; | |||
|
786 | significand = 1.0; // max value that can be recorded | |||
|
787 | } | |||
|
788 | if (significand == 0) { // in that case exponent == 0 too | |||
|
789 | exponent = expmin; | |||
|
790 | significand = 0.5; // min value that can be recorded | |||
|
791 | } | |||
|
792 | ||||
|
793 | autocor = (uint16_t) ((((significand*2)-1)*rangesig) + 0.5); // Shift and cast into a 16-bit unsigned int with rounding | |||
|
794 | // where just the first nbitsig bits are used (0, ..., 2^nbitsig-1) | |||
|
795 | exp = (uint16_t) (exponent-expmin); // Shift and cast into a 16-bit unsigned int where just | |||
|
796 | // the first nbitexp bits are used (0, ..., 2^nbitexp-1) | |||
|
797 | tmp_uint16 = autocor | (exp << nbitsig); // Put the exponent bits (nbitexp) next to the | |||
|
798 | // left place of the significand bits (nbitsig), | |||
|
799 | // making the 16-bit word to be recorded | |||
|
800 | pt_uint8 = (uint8_t*) &tmp_uint16; // Affect an uint8_t pointer with the adress of tmp_uint16 | |||
|
801 | #ifdef MSB_FIRST_TCH | |||
|
802 | lfr_bp2[(i*NB_BYTES_BP2) + 0] = pt_uint8[0]; // Record MSB of tmp_uint16 | |||
|
803 | lfr_bp2[(i*NB_BYTES_BP2) + 1] = pt_uint8[1]; // Record LSB of tmp_uint16 | |||
|
804 | #endif | |||
|
805 | #ifdef LSB_FIRST_TCH | |||
|
806 | lfr_bp2[(i*NB_BYTES_BP2) + 0] = pt_uint8[1]; // Record MSB of tmp_uint16 | |||
|
807 | lfr_bp2[(i*NB_BYTES_BP2) + 1] = pt_uint8[0]; // Record LSB of tmp_uint16 | |||
|
808 | #endif | |||
|
809 | #ifdef DEBUG_TCH | |||
|
810 | printf("autocor for S11 significand : %u\n",autocor); | |||
|
811 | printf("exp for S11 exponent : %u\n",exp); | |||
|
812 | printf("pt_uint8[1] for S11 exponent + significand : %.3d or %2x\n",pt_uint8[1], pt_uint8[1]); | |||
|
813 | printf("pt_uint8[0] for S11 significand : %.3d or %2x\n",pt_uint8[0], pt_uint8[0]); | |||
|
814 | printf("lfr_bp2[i*NB_BYTES_BP2+0] : %3u or %2x\n",lfr_bp2[i*NB_BYTES_BP2+0], lfr_bp2[i*NB_BYTES_BP2+0]); | |||
|
815 | printf("lfr_bp2[i*NB_BYTES_BP2+1] : %3u or %2x\n",lfr_bp2[i*NB_BYTES_BP2+1], lfr_bp2[i*NB_BYTES_BP2+1]); | |||
|
816 | #endif | |||
|
817 | // S22 | |||
|
818 | significand = frexpf(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 9], &exponent); // 0.5 <= significand < 1 | |||
|
819 | // S22 = significand * 2^exponent | |||
|
820 | #ifdef DEBUG_TCH | |||
|
821 | printf("S22 : %16.8e\n",compressed_spec_mat[i*NB_VALUES_PER_SPECTRAL_MATRIX+9]); | |||
|
822 | printf("significand : %16.8e\n",significand); | |||
|
823 | printf("exponent : %d\n" ,exponent); | |||
|
824 | #endif | |||
|
825 | if (exponent < expmin) { // value should be >= 0.5 * 2^expmin | |||
|
826 | exponent = expmin; | |||
|
827 | significand = 0.5; // min value that can be recorded | |||
|
828 | } | |||
|
829 | if (exponent > expmax) { // value should be < 0.5 * 2^(expmax+1) | |||
|
830 | exponent = expmax; | |||
|
831 | significand = 1.0; // max value that can be recorded | |||
|
832 | } | |||
|
833 | if (significand == 0) { // in that case exponent == 0 too | |||
|
834 | exponent = expmin; | |||
|
835 | significand = 0.5; // min value that can be recorded | |||
|
836 | } | |||
|
837 | ||||
|
838 | autocor = (uint16_t) ((((significand*2)-1)*rangesig) + 0.5); // Shift and cast into a 16-bit unsigned int with rounding | |||
|
839 | // where just the first nbitsig bits are used (0, ..., 2^nbitsig-1) | |||
|
840 | exp = (uint16_t) (exponent-expmin); // Shift and cast into a 16-bit unsigned int where just | |||
|
841 | // the first nbitexp bits are used (0, ..., 2^nbitexp-1) | |||
|
842 | tmp_uint16 = autocor | (exp << nbitsig); // Put the exponent bits (nbitexp) next to the | |||
|
843 | // left place of the significand bits (nbitsig), | |||
|
844 | // making the 16-bit word to be recorded | |||
|
845 | pt_uint8 = (uint8_t*) &tmp_uint16; // Affect an uint8_t pointer with the adress of tmp_uint16 | |||
|
846 | #ifdef MSB_FIRST_TCH | |||
|
847 | lfr_bp2[(i*NB_BYTES_BP2) + 2] = pt_uint8[0]; // Record MSB of tmp_uint16 | |||
|
848 | lfr_bp2[(i*NB_BYTES_BP2) + 3] = pt_uint8[1]; // Record LSB of tmp_uint16 | |||
|
849 | #endif | |||
|
850 | #ifdef LSB_FIRST_TCH | |||
|
851 | lfr_bp2[(i*NB_BYTES_BP2) + 2] = pt_uint8[1]; // Record MSB of tmp_uint16 | |||
|
852 | lfr_bp2[(i*NB_BYTES_BP2) + 3] = pt_uint8[0]; // Record LSB of tmp_uint16 | |||
|
853 | #endif | |||
|
854 | #ifdef DEBUG_TCH | |||
|
855 | printf("autocor for S22 significand : %u\n",autocor); | |||
|
856 | printf("exp for S11 exponent : %u\n",exp); | |||
|
857 | printf("pt_uint8[1] for S22 exponent + significand : %.3d or %2x\n",pt_uint8[1], pt_uint8[1]); | |||
|
858 | printf("pt_uint8[0] for S22 significand : %.3d or %2x\n",pt_uint8[0], pt_uint8[0]); | |||
|
859 | printf("lfr_bp2[i*NB_BYTES_BP2+2] : %3u or %2x\n",lfr_bp2[i*NB_BYTES_BP2+2], lfr_bp2[i*NB_BYTES_BP2+2]); | |||
|
860 | printf("lfr_bp2[i*NB_BYTES_BP2+3] : %3u or %2x\n",lfr_bp2[i*NB_BYTES_BP2+3], lfr_bp2[i*NB_BYTES_BP2+3]); | |||
|
861 | #endif | |||
|
862 | // S33 | |||
|
863 | significand = frexpf(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 16], &exponent); // 0.5 <= significand < 1 | |||
|
864 | // S33 = significand * 2^exponent | |||
|
865 | #ifdef DEBUG_TCH | |||
|
866 | printf("S33 : %16.8e\n",compressed_spec_mat[i*NB_VALUES_PER_SPECTRAL_MATRIX+16]); | |||
|
867 | printf("significand : %16.8e\n",significand); | |||
|
868 | printf("exponent : %d\n" ,exponent); | |||
|
869 | #endif | |||
|
870 | if (exponent < expmin) { // value should be >= 0.5 * 2^expmin | |||
|
871 | exponent = expmin; | |||
|
872 | significand = 0.5; // min value that can be recorded | |||
|
873 | } | |||
|
874 | if (exponent > expmax) { // value should be < 0.5 * 2^(expmax+1) | |||
|
875 | exponent = expmax; | |||
|
876 | significand = 1.0; // max value that can be recorded | |||
|
877 | } | |||
|
878 | if (significand == 0) { // in that case exponent == 0 too | |||
|
879 | exponent = expmin; | |||
|
880 | significand = 0.5; // min value that can be recorded | |||
|
881 | } | |||
|
882 | ||||
|
883 | autocor = (uint16_t) ((((significand*2)-1)*rangesig) + 0.5); // Shift and cast into a 16-bit unsigned int with rounding | |||
|
884 | // where just the first nbitsig bits are used (0, ..., 2^nbitsig-1) | |||
|
885 | exp = (uint16_t) (exponent-expmin); // Shift and cast into a 16-bit unsigned int where just | |||
|
886 | // the first nbitexp bits are used (0, ..., 2^nbitexp-1) | |||
|
887 | tmp_uint16 = autocor | (exp << nbitsig); // Put the exponent bits (nbitexp) next to the | |||
|
888 | // left place of the significand bits (nbitsig), | |||
|
889 | // making the 16-bit word to be recorded | |||
|
890 | pt_uint8 = (uint8_t*) &tmp_uint16; // Affect an uint8_t pointer with the adress of tmp_uint16 | |||
|
891 | #ifdef MSB_FIRST_TCH | |||
|
892 | lfr_bp2[(i*NB_BYTES_BP2) + 4] = pt_uint8[0]; // Record MSB of tmp_uint16 | |||
|
893 | lfr_bp2[(i*NB_BYTES_BP2) + 5] = pt_uint8[1]; // Record LSB of tmp_uint16 | |||
|
894 | #endif | |||
|
895 | #ifdef LSB_FIRST_TCH | |||
|
896 | lfr_bp2[(i*NB_BYTES_BP2) + 4] = pt_uint8[1]; // Record MSB of tmp_uint16 | |||
|
897 | lfr_bp2[(i*NB_BYTES_BP2) + 5] = pt_uint8[0]; // Record LSB of tmp_uint16 | |||
|
898 | #endif | |||
|
899 | #ifdef DEBUG_TCH | |||
|
900 | printf("autocor for S33 significand : %u\n",autocor); | |||
|
901 | printf("exp for S33 exponent : %u\n",exp); | |||
|
902 | printf("pt_uint8[1] for S33 exponent + significand : %.3d or %2x\n",pt_uint8[1], pt_uint8[1]); | |||
|
903 | printf("pt_uint8[0] for S33 significand : %.3d or %2x\n",pt_uint8[0], pt_uint8[0]); | |||
|
904 | printf("lfr_bp2[i*NB_BYTES_BP2+4] : %3u or %2x\n",lfr_bp2[i*NB_BYTES_BP2+4], lfr_bp2[i*NB_BYTES_BP2+4]); | |||
|
905 | printf("lfr_bp2[i*NB_BYTES_BP2+5] : %3u or %2x\n",lfr_bp2[i*NB_BYTES_BP2+5], lfr_bp2[i*NB_BYTES_BP2+5]); | |||
|
906 | #endif | |||
|
907 | // S44 | |||
|
908 | significand = frexpf(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 21], &exponent); // 0.5 <= significand < 1 | |||
|
909 | // S44 = significand * 2^exponent | |||
|
910 | #ifdef DEBUG_TCH | |||
|
911 | printf("S44 : %16.8e\n",compressed_spec_mat[i*NB_VALUES_PER_SPECTRAL_MATRIX+21]); | |||
|
912 | printf("significand : %16.8e\n",significand); | |||
|
913 | printf("exponent : %d\n" ,exponent); | |||
|
914 | #endif | |||
|
915 | ||||
|
916 | if (exponent < expmin) { // value should be >= 0.5 * 2^expmin | |||
|
917 | exponent = expmin; | |||
|
918 | significand = 0.5; // min value that can be recorded | |||
|
919 | } | |||
|
920 | if (exponent > expmax) { // value should be < 0.5 * 2^(expmax+1) | |||
|
921 | exponent = expmax; | |||
|
922 | significand = 1.0; // max value that can be recorded | |||
|
923 | } | |||
|
924 | if (significand == 0) { // in that case exponent == 0 too | |||
|
925 | exponent = expmin; | |||
|
926 | significand = 0.5; // min value that can be recorded | |||
|
927 | } | |||
|
928 | ||||
|
929 | autocor = (uint16_t) ((((significand*2)-1)*rangesig )+ 0.5); // Shift and cast into a 16-bit unsigned int with rounding | |||
|
930 | // where just the first nbitsig bits are used (0, ..., 2^nbitsig-1) | |||
|
931 | exp = (uint16_t) (exponent-expmin); // Shift and cast into a 16-bit unsigned int where just | |||
|
932 | // the first nbitexp bits are used (0, ..., 2^nbitexp-1) | |||
|
933 | tmp_uint16 = autocor | (exp << nbitsig); // Put the exponent bits (nbitexp) next to the | |||
|
934 | // left place of the significand bits (nbitsig), | |||
|
935 | // making the 16-bit word to be recorded | |||
|
936 | pt_uint8 = (uint8_t*) &tmp_uint16; // Affect an uint8_t pointer with the adress of tmp_uint16 | |||
|
937 | #ifdef MSB_FIRST_TCH | |||
|
938 | lfr_bp2[(i*NB_BYTES_BP2) + 6] = pt_uint8[0]; // Record MSB of tmp_uint16 | |||
|
939 | lfr_bp2[(i*NB_BYTES_BP2) + 7] = pt_uint8[1]; // Record LSB of tmp_uint16 | |||
|
940 | #endif | |||
|
941 | #ifdef LSB_FIRST_TCH | |||
|
942 | lfr_bp2[(i*NB_BYTES_BP2) + 6] = pt_uint8[1]; // Record MSB of tmp_uint16 | |||
|
943 | lfr_bp2[(i*NB_BYTES_BP2) + 7] = pt_uint8[0]; // Record LSB of tmp_uint16 | |||
|
944 | #endif | |||
|
945 | #ifdef DEBUG_TCH | |||
|
946 | printf("autocor for S44 significand : %u\n",autocor); | |||
|
947 | printf("exp for S44 exponent : %u\n",exp); | |||
|
948 | printf("pt_uint8[1] for S44 exponent + significand : %.3d or %2x\n",pt_uint8[1], pt_uint8[1]); | |||
|
949 | printf("pt_uint8[0] for S44 significand : %.3d or %2x\n",pt_uint8[0], pt_uint8[0]); | |||
|
950 | printf("lfr_bp2[i*NB_BYTES_BP2+6] : %3u or %2x\n",lfr_bp2[i*NB_BYTES_BP2+6], lfr_bp2[i*NB_BYTES_BP2+6]); | |||
|
951 | printf("lfr_bp2[i*NB_BYTES_BP2+7] : %3u or %2x\n",lfr_bp2[i*NB_BYTES_BP2+7], lfr_bp2[i*NB_BYTES_BP2+7]); | |||
|
952 | #endif | |||
|
953 | // S55 | |||
|
954 | significand = frexpf(compressed_spec_mat[(i*NB_VALUES_PER_SPECTRAL_MATRIX) + 24], &exponent); // 0.5 <= significand < 1 | |||
|
955 | // S55 = significand * 2^exponent | |||
|
956 | #ifdef DEBUG_TCH | |||
|
957 | printf("S55 : %16.8e\n",compressed_spec_mat[i*NB_VALUES_PER_SPECTRAL_MATRIX+24]); | |||
|
958 | printf("significand : %16.8e\n",significand); | |||
|
959 | printf("exponent : %d\n" ,exponent); | |||
|
960 | #endif | |||
|
961 | if (exponent < expmin) { // value should be >= 0.5 * 2^expmin | |||
|
962 | exponent = expmin; | |||
|
963 | significand = 0.5; // min value that can be recorded | |||
|
964 | } | |||
|
965 | if (exponent > expmax) { // value should be < 0.5 * 2^(expmax+1) | |||
|
966 | exponent = expmax; | |||
|
967 | significand = 1.0; // max value that can be recorded | |||
|
968 | } | |||
|
969 | if (significand == 0) { // in that case exponent == 0 too | |||
|
970 | exponent = expmin; | |||
|
971 | significand = 0.5; // min value that can be recorded | |||
|
972 | } | |||
|
973 | ||||
|
974 | autocor = (uint16_t) ((((significand*2)-1)*rangesig) + 0.5); // Shift and cast into a 16-bit unsigned int with rounding | |||
|
975 | // where just the first nbitsig bits are used (0, ..., 2^nbitsig-1) | |||
|
976 | exp = (uint16_t) (exponent-expmin); // Shift and cast into a 16-bit unsigned int where just | |||
|
977 | // the first nbitexp bits are used (0, ..., 2^nbitexp-1) | |||
|
978 | tmp_uint16 = autocor | (exp << nbitsig); // Put the exponent bits (nbitexp) next to the | |||
|
979 | // left place of the significand bits (nbitsig), | |||
|
980 | // making the 16-bit word to be recorded | |||
|
981 | pt_uint8 = (uint8_t*) &tmp_uint16; // Affect an uint8_t pointer with the adress of tmp_uint16 | |||
|
982 | #ifdef MSB_FIRST_TCH | |||
|
983 | lfr_bp2[(i*NB_BYTES_BP2) + 8] = pt_uint8[0]; // Record MSB of tmp_uint16 | |||
|
984 | lfr_bp2[(i*NB_BYTES_BP2) + 9] = pt_uint8[1]; // Record LSB of tmp_uint16 | |||
|
985 | //printf("MSB:\n"); | |||
|
986 | #endif | |||
|
987 | #ifdef LSB_FIRST_TCH | |||
|
988 | lfr_bp2[(i*NB_BYTES_BP2) + 8] = pt_uint8[1]; // Record MSB of tmp_uint16 | |||
|
989 | lfr_bp2[(i*NB_BYTES_BP2) + 9] = pt_uint8[0]; // Record LSB of tmp_uint16 | |||
|
990 | //printf("LSB:\n"); | |||
|
991 | #endif | |||
|
992 | #ifdef DEBUG_TCH | |||
|
993 | printf("autocor for S55 significand : %u\n",autocor); | |||
|
994 | printf("exp for S55 exponent : %u\n",exp); | |||
|
995 | printf("pt_uint8[1] for S55 exponent + significand : %.3d or %2x\n",pt_uint8[1], pt_uint8[1]); | |||
|
996 | printf("pt_uint8[0] for S55 significand : %.3d or %2x\n",pt_uint8[0], pt_uint8[0]); | |||
|
997 | printf("lfr_bp2[i*NB_BYTES_BP2+8] : %3u or %2x\n",lfr_bp2[i*NB_BYTES_BP2+8], lfr_bp2[i*NB_BYTES_BP2+8]); | |||
|
998 | printf("lfr_bp2[i*NB_BYTES_BP2+9] : %3u or %2x\n",lfr_bp2[i*NB_BYTES_BP2+9], lfr_bp2[i*NB_BYTES_BP2+9]); | |||
|
999 | #endif | |||
|
1000 | } | |||
|
1001 | } | |||
|
1002 |
@@ -0,0 +1,61 | |||||
|
1 | // In the frame of RPW LFR Sofware ICD Issue1 Rev8 (05/07/2013) => R2 FSW | |||
|
2 | // version 1.0: 31/07/2013 | |||
|
3 | // version 1.1: 02/04/2014 | |||
|
4 | // version 1.2: 30/04/2014 | |||
|
5 | // version 1.3: 02/05/2014 | |||
|
6 | // version 1.4: 16/05/2014 | |||
|
7 | // version 1.5: 20/05/2014 | |||
|
8 | // version 1.6: 19/12/2014 | |||
|
9 | // version 1.7: 15/01/2015 (modifs de Paul + correction erreurs qui se compensaient (LSB <=> MSB + indices [0,2] <=> [1,3]) | |||
|
10 | // version 1.8: 02/02/2015 (gestion des divisions par zéro) | |||
|
11 | // In the frame of RPW LFR Sofware ICD Issue3 Rev6 (27/01/2015) => R3 FSW | |||
|
12 | // version 2.0: 19/06/2015 | |||
|
13 | // version 2.1: 22/06/2015 (modifs de Paul) | |||
|
14 | // version 2.2: 23/06/2015 (modifs de l'ordre de déclaration/définition de init_k_coefficients dans basic_parameters.c ... + maintien des declarations dans le .h) | |||
|
15 | // version 2.3: 01/07/2015 (affectation initiale des octets 7 et 9 dans les BP1 corrigée ...) | |||
|
16 | // version 2.4: 05/10/2018 (mise en conformité LOGISCOPE) | |||
|
17 | // version 2.5: 09/10/2018 (dans main.c #include "basic_parameters_utilities.h" est changé par les déclarations extern correspondantes ...! | |||
|
18 | // + delta mise en conformité LOGISCOPE) | |||
|
19 | ||||
|
20 | /*------------------------------------------------------------------------------ | |||
|
21 | -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW), | |||
|
22 | -- This file is a part of the LFR FSW | |||
|
23 | -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS | |||
|
24 | -- | |||
|
25 | -- This program is free software; you can redistribute it and/or modify | |||
|
26 | -- it under the terms of the GNU General Public License as published by | |||
|
27 | -- the Free Software Foundation; either version 2 of the License, or | |||
|
28 | -- (at your option) any later version. | |||
|
29 | -- | |||
|
30 | -- This program is distributed in the hope that it will be useful, | |||
|
31 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
32 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
33 | -- GNU General Public License for more details. | |||
|
34 | -- | |||
|
35 | -- You should have received a copy of the GNU General Public License | |||
|
36 | -- along with this program; if not, write to the Free Software | |||
|
37 | -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
|
38 | -------------------------------------------------------------------------------*/ | |||
|
39 | /*-- Author : Thomas Chust | |||
|
40 | -- Contact : Thomas Chust | |||
|
41 | -- Mail : thomas.chust@lpp.polytechnique.fr | |||
|
42 | ----------------------------------------------------------------------------*/ | |||
|
43 | ||||
|
44 | #ifndef BASIC_PARAMETERS_H_INCLUDED | |||
|
45 | #define BASIC_PARAMETERS_H_INCLUDED | |||
|
46 | ||||
|
47 | #include <stdint.h> | |||
|
48 | ||||
|
49 | #include "basic_parameters_params.h" | |||
|
50 | ||||
|
51 | void init_k_coefficients( float *k_coeff_intercalib, unsigned char nb_binscompressed_matrix ); | |||
|
52 | ||||
|
53 | //*********************************** | |||
|
54 | // STATIC INLINE FUNCTION DEFINITIONS | |||
|
55 | ||||
|
56 | void BP1_set( float * compressed_spec_mat, float * k_coeff_intercalib, uint8_t nb_bins_compressed_spec_mat, uint8_t * lfr_bp1 ); | |||
|
57 | ||||
|
58 | void BP2_set( float * compressed_spec_mat, uint8_t nb_bins_compressed_spec_mat, uint8_t * lfr_bp2 ); | |||
|
59 | ||||
|
60 | ||||
|
61 | #endif // BASIC_PARAMETERS_H_INCLUDED |
@@ -0,0 +1,93 | |||||
|
1 | // In the frame of RPW LFR Sofware ICD Issue1 Rev8 (05/07/2013) => R2 FSW | |||
|
2 | // version 1.4: 16/05/2014 | |||
|
3 | // version 1.5: 20/05/2014 | |||
|
4 | // version 1.6: 19/12/2014 | |||
|
5 | // version 1.7: 15/01/2015 (modifs de Paul + correction erreurs qui se compensaient (LSB <=> MSB + indices [0,2] <=> [1,3]) | |||
|
6 | // version 1.8: 02/02/2015 (gestion des divisions par zéro) | |||
|
7 | // In the frame of RPW LFR Sofware ICD Issue3 Rev6 (27/01/2015) => R3 FSW | |||
|
8 | // version 2.0: 19/06/2015 | |||
|
9 | // version 2.1: 22/06/2015 (modifs de Paul) | |||
|
10 | // version 2.2: 23/06/2015 (modifs de l'ordre de déclaration/définition de init_k_coefficients dans basic_parameters.c ... + maintien des declarations dans le .h) | |||
|
11 | // version 2.3: 01/07/2015 (affectation initiale des octets 7 et 9 dans les BP1 corrigée ...) | |||
|
12 | // version 2.4: 05/10/2018 (added GPL headers) | |||
|
13 | // version 2.5: 09/10/2018 (dans main.c #include "basic_parameters_utilities.h" est changé par les déclarations extern correspondantes ...! | |||
|
14 | // + delta mise en conformité LOGISCOPE) | |||
|
15 | ||||
|
16 | /*------------------------------------------------------------------------------ | |||
|
17 | -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW), | |||
|
18 | -- This file is a part of the LFR FSW | |||
|
19 | -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS | |||
|
20 | -- | |||
|
21 | -- This program is free software; you can redistribute it and/or modify | |||
|
22 | -- it under the terms of the GNU General Public License as published by | |||
|
23 | -- the Free Software Foundation; either version 2 of the License, or | |||
|
24 | -- (at your option) any later version. | |||
|
25 | -- | |||
|
26 | -- This program is distributed in the hope that it will be useful, | |||
|
27 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
28 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
29 | -- GNU General Public License for more details. | |||
|
30 | -- | |||
|
31 | -- You should have received a copy of the GNU General Public License | |||
|
32 | -- along with this program; if not, write to the Free Software | |||
|
33 | -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
|
34 | -------------------------------------------------------------------------------*/ | |||
|
35 | /*-- Author : Thomas Chust | |||
|
36 | -- Contact : Thomas Chust | |||
|
37 | -- Mail : thomas.chust@lpp.polytechnique.fr | |||
|
38 | ----------------------------------------------------------------------------*/ | |||
|
39 | ||||
|
40 | #ifndef BASIC_PARAMETERS_PARAMS_H | |||
|
41 | #define BASIC_PARAMETERS_PARAMS_H | |||
|
42 | ||||
|
43 | #define NB_VALUES_PER_SPECTRAL_MATRIX 25 | |||
|
44 | ||||
|
45 | #define NB_BINS_COMPRESSED_MATRIX_f0 11 | |||
|
46 | #define NB_BINS_COMPRESSED_MATRIX_f1 13 | |||
|
47 | #define NB_BINS_COMPRESSED_MATRIX_f2 12 | |||
|
48 | ||||
|
49 | #define NB_BYTES_BP1 11 | |||
|
50 | #define NB_BYTES_BP2 30 | |||
|
51 | ||||
|
52 | //******************************************** | |||
|
53 | // K-COEFFICIENTS FOR ONBOARD INTERCALIBRATION | |||
|
54 | ||||
|
55 | #define NB_K_COEFF_PER_BIN 32 | |||
|
56 | ||||
|
57 | #define K44_PE 0 | |||
|
58 | #define K55_PE 1 | |||
|
59 | #define K45_PE_RE 2 | |||
|
60 | #define K45_PE_IM 3 | |||
|
61 | ||||
|
62 | #define K14_SX_RE 4 | |||
|
63 | #define K14_SX_IM 5 | |||
|
64 | #define K15_SX_RE 6 | |||
|
65 | #define K15_SX_IM 7 | |||
|
66 | #define K24_SX_RE 8 | |||
|
67 | #define K24_SX_IM 9 | |||
|
68 | #define K25_SX_RE 10 | |||
|
69 | #define K25_SX_IM 11 | |||
|
70 | #define K34_SX_RE 12 | |||
|
71 | #define K34_SX_IM 13 | |||
|
72 | #define K35_SX_RE 14 | |||
|
73 | #define K35_SX_IM 15 | |||
|
74 | ||||
|
75 | #define K24_NY_RE 16 | |||
|
76 | #define K24_NY_IM 17 | |||
|
77 | #define K25_NY_RE 18 | |||
|
78 | #define K25_NY_IM 19 | |||
|
79 | #define K34_NY_RE 20 | |||
|
80 | #define K34_NY_IM 21 | |||
|
81 | #define K35_NY_RE 22 | |||
|
82 | #define K35_NY_IM 23 | |||
|
83 | ||||
|
84 | #define K24_NZ_RE 24 | |||
|
85 | #define K24_NZ_IM 25 | |||
|
86 | #define K25_NZ_RE 26 | |||
|
87 | #define K25_NZ_IM 27 | |||
|
88 | #define K34_NZ_RE 28 | |||
|
89 | #define K34_NZ_IM 29 | |||
|
90 | #define K35_NZ_RE 30 | |||
|
91 | #define K35_NZ_IM 31 | |||
|
92 | ||||
|
93 | #endif // BASIC_PARAMETERS_PARAMS_H |
@@ -0,0 +1,54 | |||||
|
1 | // In the frame of RPW LFR Sofware ICD Issue1 Rev8 (05/07/2013) => R2 FSW | |||
|
2 | // version 1.6: 19/12/2014 | |||
|
3 | // version 1.7: 15/01/2015 (modifs de Paul + correction erreurs qui se compensaient (LSB <=> MSB + indices [0,2] <=> [1,3]) | |||
|
4 | // version 1.8: 02/02/2015 (gestion des divisions par zéro) | |||
|
5 | // In the frame of RPW LFR Sofware ICD Issue3 Rev6 (27/01/2015) => R3 FSW | |||
|
6 | // version 2.0: 19/06/2015 | |||
|
7 | // version 2.1: 22/06/2015 (modifs de Paul) | |||
|
8 | // version 2.2: 23/06/2015 (modifs de l'ordre de déclaration/définition de init_k_coefficients dans basic_parameters.c ... + maintien des declarations dans le .h) | |||
|
9 | // version 2.3: 01/07/2015 (affectation initiale des octets 7 et 9 dans les BP1 corrigée ...) | |||
|
10 | // version 2.4: 05/10/2018 (mise en conformité LOGISCOPE) | |||
|
11 | // version 2.5: 09/10/2018 (dans main.c #include "basic_parameters_utilities.h" est changé par les déclarations extern correspondantes ...! | |||
|
12 | // + delta mise en conformité LOGISCOPE) | |||
|
13 | ||||
|
14 | /*------------------------------------------------------------------------------ | |||
|
15 | -- Solar Orbiter's Low Frequency Receiver Flight Software (LFR FSW), | |||
|
16 | -- This file is a part of the LFR FSW | |||
|
17 | -- Copyright (C) 2012-2018, Plasma Physics Laboratory - CNRS | |||
|
18 | -- | |||
|
19 | -- This program is free software; you can redistribute it and/or modify | |||
|
20 | -- it under the terms of the GNU General Public License as published by | |||
|
21 | -- the Free Software Foundation; either version 2 of the License, or | |||
|
22 | -- (at your option) any later version. | |||
|
23 | -- | |||
|
24 | -- This program is distributed in the hope that it will be useful, | |||
|
25 | -- but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
|
26 | -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
|
27 | -- GNU General Public License for more details. | |||
|
28 | -- | |||
|
29 | -- You should have received a copy of the GNU General Public License | |||
|
30 | -- along with this program; if not, write to the Free Software | |||
|
31 | -- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |||
|
32 | -------------------------------------------------------------------------------*/ | |||
|
33 | /*-- Author : Thomas Chust | |||
|
34 | -- Contact : Thomas Chust | |||
|
35 | -- Mail : thomas.chust@lpp.polytechnique.fr | |||
|
36 | ----------------------------------------------------------------------------*/ | |||
|
37 | ||||
|
38 | #ifndef BASIC_PARAMETERS_UTILITIES_H | |||
|
39 | #define BASIC_PARAMETERS_UTILITIES_H | |||
|
40 | ||||
|
41 | #include <stdio.h> | |||
|
42 | #include <malloc.h> | |||
|
43 | ||||
|
44 | #include "basic_parameters_params.h" | |||
|
45 | ||||
|
46 | float compressed_spectral_matrix_f0[NB_BINS_COMPRESSED_MATRIX_f0 * NB_VALUES_PER_SPECTRAL_MATRIX] = {0.0}; | |||
|
47 | float k_coefficients_f0[NB_BINS_COMPRESSED_MATRIX_f0 * NB_K_COEFF_PER_BIN] = {0.0}; | |||
|
48 | float k_coefficients_f1[NB_BINS_COMPRESSED_MATRIX_f1 * NB_K_COEFF_PER_BIN] = {0.0}; | |||
|
49 | float k_coefficients_f2[NB_BINS_COMPRESSED_MATRIX_f2 * NB_K_COEFF_PER_BIN] = {0.0}; | |||
|
50 | ||||
|
51 | unsigned char LFR_BP1_f0[NB_BINS_COMPRESSED_MATRIX_f0*NB_BYTES_BP1] = {0}; | |||
|
52 | unsigned char LFR_BP2_f0[NB_BINS_COMPRESSED_MATRIX_f0*NB_BYTES_BP2] = {0}; | |||
|
53 | ||||
|
54 | #endif // BASIC_PARAMETERS_UTILITIES_H |
@@ -0,0 +1,27 | |||||
|
1 | from ctypes import * | |||
|
2 | import numpy as np | |||
|
3 | import os | |||
|
4 | import sys | |||
|
5 | ||||
|
6 | import unittest | |||
|
7 | ||||
|
8 | class init_k_coefficients(unittest.TestCase): | |||
|
9 | def setUp(self): | |||
|
10 | self.lib_basic_params = cdll.LoadLibrary(f'{os.path.dirname(os.path.realpath(__file__))}/../../build-LFR_basic-parameters-Desktop-Default/liblfr_basic_params.so') | |||
|
11 | ||||
|
12 | def tearDown(self): | |||
|
13 | pass | |||
|
14 | ||||
|
15 | def test_init_k_coefficients_f0(self): | |||
|
16 | nb_bins = 11 | |||
|
17 | nb_binscompressed_matrix = c_char(nb_bins) | |||
|
18 | k_coefficients = (c_float * (32 * nb_bins))() | |||
|
19 | ||||
|
20 | for i in range(len(k_coefficients)): | |||
|
21 | k_coefficients[i] = 100.*np.random.random() | |||
|
22 | ||||
|
23 | self.lib_basic_params.init_k_coefficients(k_coefficients, nb_binscompressed_matrix) | |||
|
24 | self.assertTrue(all([ v==1. if i not in ( 2, 3, 34, 35, 66, 67, 98, 99, 130, 131, 162, 163, 194, 195, 226, 227, 258, 259, 290, 291, 322, 323) else v==0. for i,v in enumerate(k_coefficients) ])) | |||
|
25 | ||||
|
26 | if __name__ == '__main__': | |||
|
27 | unittest.main() |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed | ||
This diff has been collapsed as it changes many lines, (1003 lines changed) Show them Hide them |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed, binary diff hidden |
|
NO CONTENT: file was removed, binary diff hidden |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
1 | NO CONTENT: file was removed |
|
NO CONTENT: file was removed |
General Comments 0
You need to be logged in to leave comments.
Login now