libdballe 5.10
|
00001 /* 00002 * DB-ALLe - Archive for punctual meteorological data 00003 * 00004 * Copyright (C) 2005--2010 ARPA-SIM <urpsim@smr.arpa.emr.it> 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License. 00009 * 00010 * This program is distributed in the hope that it will be useful, 00011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00013 * GNU General Public License for more details. 00014 * 00015 * You should have received a copy of the GNU General Public License 00016 * along with this program; if not, write to the Free Software 00017 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 00018 * 00019 * Author: Enrico Zini <enrico@enricozini.com> 00020 */ 00021 00022 #ifndef DBA_AOF_IMPORTERS_COMMON_H 00023 #define DBA_AOF_IMPORTERS_COMMON_H 00024 00025 /* 00026 * Common functions for all AOF decoders. 00027 */ 00028 00029 #include <dballe/msg/msg.h> 00030 #include <dballe/msg/aof_codec.h> 00031 00032 #include <stdio.h> 00033 #include <stdint.h> /* uint32_t */ 00034 #include <math.h> 00035 00036 // #define TRACE_DECODER 00037 00038 #ifdef TRACE_DECODER 00039 #define TRACE(...) fprintf(stderr, __VA_ARGS__) 00040 #define IFTRACE if (1) 00041 #else 00042 #define TRACE(...) do { } while (0) 00043 #define IFTRACE if (0) 00044 #endif 00045 00046 #define AOF_UNDEF 0x7fffffff 00047 00048 #define OBS(n) (obs[n-1]) 00049 00050 namespace dballe { 00051 namespace msg { 00052 00053 /* Parse a 2 bit confidence interval into a percent confidence interval */ 00054 static inline int get_conf2(uint32_t conf) 00055 { 00056 switch (conf & 3) 00057 { 00058 case 0: return 76; break; 00059 case 1: return 51; break; 00060 case 2: return 26; break; 00061 case 3: return 0; break; 00062 } 00063 return 0; 00064 } 00065 00066 /* Parse a 6 bit confidence interval into a percent confidence interval */ 00067 static inline int get_conf6(uint32_t conf) 00068 { 00069 return get_conf2(conf >> 3); 00070 } 00071 00072 /* Count the number of bits present in a word */ 00073 static inline int count_bits(uint32_t v) 00074 { 00075 /* Algorithm based on Magic Binary Numbers 00076 * http://graphics.stanford.edu/~seander/bithacks.html 00077 const int S[] = {1, 2, 4, 8, 16}; // Magic Binary Numbers 00078 const int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF}; 00079 00080 v = ((v >> S[0]) & B[0]) + (v & B[0]); 00081 v = ((v >> S[1]) & B[1]) + (v & B[1]); 00082 v = ((v >> S[2]) & B[2]) + (v & B[2]); 00083 v = ((v >> S[3]) & B[3]) + (v & B[3]); 00084 v = ((v >> S[4]) & B[4]) + (v & B[4]); 00085 00086 return c; 00087 */ 00088 00089 // Kernigan algorithm (1 iteration per bit set to 1): better because where 00090 // this function is used the bits set to 1 are usually few 00091 00092 unsigned int c; // c accumulates the total bits set in v 00093 for (c = 0; v; c++) 00094 v &= v - 1; // clear the least significant bit set 00095 00096 return c; 00097 } 00098 00099 static inline uint32_t get_extra_conf(const uint32_t* obs, int idx) 00100 { 00101 int count = count_bits(OBS(32)); 00102 uint32_t w = OBS(33+count+idx/4); 00103 return (w >> ((idx % 4) * 6)) & 0x3f; 00104 00105 } 00106 00107 /* Convert Kelvin from AOF to Kelvins */ 00108 static inline double totemp(double k) { return k / 10.0; } 00109 00110 #if 0 00111 /* Dump a word */ 00112 void dba_aof_dump_word(const char* prefix, uint32_t x); 00113 00114 00115 uint32_t dba_aof_get_extra_conf(const uint32_t* obs, int idx); 00116 00117 #endif 00118 00119 } // namespace msg 00120 } // namespace dballe 00121 00122 /* vim:set ts=4 sw=4: */ 00123 #endif