common.h

00001 /*
00002  * DB-ALLe - Archive for punctual meteorological data
00003  *
00004  * Copyright (C) 2005,2006  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 /* For round() */
00026 #define _ISOC99_SOURCE
00027 
00028 /*
00029  * Common functions for all AOF decoders.
00030  */
00031 
00032 #include <dballe/core/conv.h>
00033 #include <dballe/msg/msg.h>
00034 
00035 #include <stdio.h>
00036 #include <stdint.h>     /* uint32_t */
00037 #include <math.h>
00038 
00039 // #define TRACE_DECODER
00040 
00041 #ifdef TRACE_DECODER
00042 #define TRACE(...) fprintf(stderr, __VA_ARGS__)
00043 #define IFTRACE if (1)
00044 #else
00045 #define TRACE(...) do { } while (0)
00046 #define IFTRACE if (0)
00047 #endif
00048 
00049 #define AOF_UNDEF 0x7fffffff
00050 
00051 #define OBS(n) (obs[n-1])
00052 
00053 
00054 /* Parse a 2 bit confidence interval into a percent confidence interval */
00055 static inline int get_conf2(int conf)
00056 {
00057     switch (conf & 3)
00058     {
00059         case 0: return 76; break;
00060         case 1: return 51; break;
00061         case 2: return 26; break;
00062         case 3: return 0; break;
00063     }
00064     return 0;
00065 }
00066 
00067 /* Parse a 6 bit confidence interval into a percent confidence interval */
00068 static inline int get_conf6(int conf)
00069 {
00070     return get_conf2(conf >> 3);
00071 }
00072 
00073 /* Convert Kelvin into Celsius */
00074 static inline double totemp(double k) { return k / 10.0; }
00075 
00076 /* Dump a word */
00077 void dba_aof_dump_word(const char* prefix, uint32_t x);
00078 
00079 /* Parse latitude, longitude, date and time in the Observation Header */
00080 dba_err dba_aof_parse_lat_lon_datetime(dba_msg msg, const uint32_t* obs);
00081 
00082 /* Parse WMO block and station numbers in the Observation Header */
00083 dba_err dba_aof_parse_st_block_station(dba_msg msg, const uint32_t* obs);
00084 
00085 /* Parse string ident in the Observation Header */
00086 dba_err dba_aof_parse_st_ident(dba_msg msg, const uint32_t* obs);
00087 
00088 /* Parse station altitude the Observation Header */
00089 dba_err dba_aof_parse_altitude(dba_msg msg, const uint32_t* obs);
00090 
00091 /* Parse 27 Weather group in Synop observations */
00092 dba_err dba_aof_parse_weather_group(dba_msg msg, const uint32_t* obs);
00093 
00094 /* Parse 28 General cloud group in Synop observations */
00095 dba_err dba_aof_parse_general_cloud_group(dba_msg msg, const uint32_t* obs);
00096 
00097 /* Parse a bit-packed cloud group in Synop observations */
00098 dba_err dba_aof_parse_cloud_group(uint32_t val, int* ns, int* c, int* h);
00099 
00100 uint32_t dba_aof_get_extra_conf(const uint32_t* obs, int idx);
00101 
00102 /* Count the number of bits present in a word */
00103 static inline int count_bits(uint32_t v)
00104 {
00105     /* Algoritmo basato su Magic Binary Numbers
00106      * http://graphics.stanford.edu/~seander/bithacks.html
00107     const int S[] = {1, 2, 4, 8, 16}; // Magic Binary Numbers
00108     const int B[] = {0x55555555, 0x33333333, 0x0F0F0F0F, 0x00FF00FF, 0x0000FFFF};
00109 
00110     v = ((v >> S[0]) & B[0]) + (v & B[0]);
00111     v = ((v >> S[1]) & B[1]) + (v & B[1]);
00112     v = ((v >> S[2]) & B[2]) + (v & B[2]);
00113     v = ((v >> S[3]) & B[3]) + (v & B[3]);
00114     v = ((v >> S[4]) & B[4]) + (v & B[4]);
00115 
00116     return c;
00117     */
00118 
00119     /* Algoritmo di Kernigan (1 iterazione per bit settato a 1): ci va bene
00120      * perché solitamente sono pochi */
00121 
00122     unsigned int c; // c accumulates the total bits set in v
00123     for (c = 0; v; c++)
00124     {
00125         v &= v - 1; // clear the least significant bit set
00126     }
00127 
00128     return c;
00129 }
00130 
00131 /* vim:set ts=4 sw=4: */
00132 #endif

Generated on Fri Jun 22 13:06:52 2007 for libdballe-db by  doxygen 1.5.2