libdballe 4.0.18
|
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(uint32_t 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(uint32_t 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