libdballe 5.10
common.h
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