nmxp_data.h 9.76 KB
Newer Older
1
2
/*! \file
 *
Matteo Quintiliani's avatar
Matteo Quintiliani committed
3
 * \brief Data for Nanometrics Protocol Library
4
5
6
7
8
9
 *
 * Author:
 * 	Matteo Quintiliani
 * 	Istituto Nazionale di Geofisica e Vulcanologia - Italy
 *	quintiliani@ingv.it
 *
10
 * $Id: nmxp_data.h,v 1.36 2009-08-17 08:19:46 mtheo Exp $
Matteo Quintiliani's avatar
Matteo Quintiliani committed
11
 *
12
13
14
15
16
 */

#ifndef NMXP_DATA_H
#define NMXP_DATA_H 1

17
#include <stdint.h>
18
#include <stdio.h>
19
#include <time.h>
20

21

22
23
24
25
26
27
28
29
/*! \brief struct tm plus ten thousandth second field */
typedef struct {
    struct tm t;
    uint32_t d;
} NMXP_TM_T;



30
31
32
/*! First 4 bytes of all messages. */
#define NMX_SIGNATURE 0x7abcde0f

33
34
35
36
/*! */
#define NMXP_DATA_IS_LEAP(yr)     ( yr%400==0 || (yr%4==0 && yr%100!=0) )


37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*! \brief Defines the type for reason of shutdown */
typedef enum {
    NMXP_SHUTDOWN_NORMAL		= 1,
    NMXP_SHUTDOWN_ERROR			= 2,
    NMXP_SHUTDOWN_TIMEOUT		= 3
} NMXP_SHUTDOWN_REASON;

/*! \brief Defines the client message types */
typedef enum {
   NMXP_MSG_CONNECT			= 100,
   NMXP_MSG_REQUESTPENDING		= 110,
   NMXP_MSG_CANCELREQUEST		= 205,
   NMXP_MSG_TERMINATESUBSCRIPTION	= 200,

   NMXP_MSG_ADDTIMESERIESCHANNELS	= 120,
   NMXP_MSG_ADDSOHCHANNELS		= 121,
   NMXP_MSG_ADDSERIALCHANNELS		= 124,
   NMXP_MSG_ADDTRIGGERCHANNELS		= 122,
   NMXP_MSG_ADDEVENTS			= 123,

   NMXP_MSG_REMOVETIMESERIESCHANNELS	= 130,
   NMXP_MSG_REMOVESOHCHANNELS		= 131,
   NMXP_MSG_REMOVESERIALCHANNELS	= 134,
   NMXP_MSG_REMOVETRIGGERCHANNELS	= 132,
   NMXP_MSG_REMOVEEVENTS		= 133,

   NMXP_MSG_CONNECTREQUEST		= 206,
   NMXP_MSG_CHANNELLISTREQUEST		= 209,
   NMXP_MSG_PRECISLISTREQUEST		= 203,
   NMXP_MSG_CHANNELINFOREQUEST		= 226,
   NMXP_MSG_DATASIZEREQUEST		= 229,
   NMXP_MSG_DATAREQUEST			= 227,
   NMXP_MSG_TRIGGERREQUEST		= 231,
   NMXP_MSG_EVENTREQUEST		= 232
   
} NMXP_MSG_CLIENT;

/*! \brief Defines the server message types. */
typedef enum {
    NMXP_MSG_CHANNELLIST		= 150,
    NMXP_MSG_ERROR			= 190,
    NMXP_MSG_COMPRESSED			= 1,
    NMXP_MSG_DECOMPRESSED		= 4,
    NMXP_MSG_TRIGGER			= 5,
    NMXP_MSG_EVENT			= 6,

    NMXP_MSG_READY			= 208,
    NMXP_MSG_PRECISLIST			= 253,
    NMXP_MSG_CHANNELHEADER		= 256,
    NMXP_MSG_DATASIZE			= 257,
    NMXP_MSG_NAQSEVENT			= 260,
    NMXP_MSG_NAQSTRIGGER		= 259

} NMXP_MSG_SERVER;


/*! \brief Header for all messages. */
typedef struct {
95
96
97
    int32_t signature;
    int32_t type;
    int32_t length;
98
99
100
} NMXP_MESSAGE_HEADER;


101
102
#define NMXP_DATA_MAX_SIZE_DATE 200

103
/*! \brief Length in bytes of channel strings */
104
#define NMXP_DATA_NETWORK_LENGTH 10
105

106
/*! \brief Length in bytes of station strings */
107
#define NMXP_DATA_STATION_LENGTH 10
108
109

/*! \brief Length in bytes of channel strings */
110
#define NMXP_DATA_CHANNEL_LENGTH 10
111

112
113
/*! \brief Parameter structure for functions that process data */
typedef struct {
114
    int32_t key;			/*!< \brief Channel Key */
115
116
117
    char network[NMXP_DATA_NETWORK_LENGTH];	/*!< \brief Network code */
    char station[NMXP_DATA_STATION_LENGTH];	/*!< \brief Station code */
    char channel[NMXP_DATA_CHANNEL_LENGTH];	/*!< \brief Channel code */
118
119
120
121
122
123
    int32_t packet_type;			/*!< \brief Packet type */
    int32_t x0;				/*!< \brief First sample. It is significant only if x0n_significant != 0 */
    int32_t xn;				/*!< \brief Last sample. It is significant only if x0n_significant != 0 */
    int32_t x0n_significant;			/*!< \brief Declare if xn significant */
    int32_t oldest_seq_no;			/*!< \brief Oldest Sequence number */
    int32_t seq_no;				/*!< \brief Sequence number */
124
125
    double time;			/*!< \brief Time first sample. Epochs. */
    int *pDataPtr;			/*!< \brief Array of samples */
126
127
    int32_t nSamp;				/*!< \brief Number or samples */
    int32_t sampRate;			/*!< \brief Sample rate */
128
} NMXP_DATA_PROCESS;
129
130


131
132
133
134
135
136
137
138
/*! \brief For SDS or BUD directory structure */
typedef enum {
    NMXP_TYPE_WRITESEED_SDS = 0,
    NMXP_TYPE_WRITESEED_BUD
} NMXP_DATA_SEED_TYPEWRITE;

#define NMXP_DATA_MAX_SIZE_FILENAME 1024
#define NMXP_DATA_MAX_NUM_OPENED_FILE 200
139
140
/*! \brief Parameter structure for functions that handle mini-seed records */
typedef struct {
141
142
143
    int n_open_files;
    int last_open_file;
    int cur_open_file;
144
145
    int err_general;
    int err_outfile_mseed[NMXP_DATA_MAX_NUM_OPENED_FILE];
146
147
148
149
150
151
    FILE *outfile_mseed[NMXP_DATA_MAX_NUM_OPENED_FILE];
    char filename_mseed[NMXP_DATA_MAX_NUM_OPENED_FILE][NMXP_DATA_MAX_SIZE_FILENAME];
    char outdirseed[NMXP_DATA_MAX_SIZE_FILENAME];
    char default_network[5];
    NMXP_DATA_SEED_TYPEWRITE type_writeseed;
    NMXP_DATA_PROCESS *pd;
152
153
} NMXP_DATA_SEED;

154
/*! \brief Initialize a structure NMXP_DATA_PROCESS
155
 *
156
 *  \param pd Pointer to a NMXP_DATA_PROCESS structure.
157
158
 *
 */
159
int nmxp_data_init(NMXP_DATA_PROCESS *pd);
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174


/*! \brief Unpack a 17-byte Nanometrics compressed data bundle.           
 *
 * \param[out] outdata
 * \param indata
 * \param prev
 *
 * \return Number of unpacked data samples, -1 if null bundle. 
 *
 * Author:  Doug Neuhauser
 *          UC Berkeley Seismological Laboratory
 *          doug@seismo.berkeley.edu
 *
 */
175
int nmxp_data_unpack_bundle (int32_t *outdata, unsigned char *indata, int32_t *prev);
176

177

178
179
180
181
182
183
/* \brief Value for parameter exclude_bitmap in the function nmxp_data_trim() */
#define NMXP_DATA_TRIM_EXCLUDE_FIRST 2

/* \brief Value for parameter exclude_bitmap in the function nmxp_data_trim() */
#define NMXP_DATA_TRIM_EXCLUDE_LAST  4

184
185
186
187
188
/*! \brief Convert epoch in string
 */
int nmxp_data_to_str(char *out_str, double time_d);


189
190
191
192
193
194
195
196
197
198
/*! \brief Return year from epoch
 */
int nmxp_data_year_from_epoch(double time_d);


/*! \brief Return julian day from epoch
 */
int nmxp_data_yday_from_epoch(double time_d);


199
200
201
202
203
/*! \brief Trim data within a time interval
 *
 * \param pd Pointer to struct NMXP_DATA_PROCESS
 * \param trim_start_time Start time.
 * \param trim_end_time End time.
204
 * \param exclude_bitmap Bitmap for excluding or not the first and/or the last sample.
205
206
207
208
209
210
 *
 * \retval 2 On success, data has not been trimmed.
 * \retval 1 On success, data has been trimmed.
 * \retval 0 On error.
 *
 */
211
int nmxp_data_trim(NMXP_DATA_PROCESS *pd, double trim_start_time, double trim_end_time, unsigned char exclude_bitmap);
212
213


214
215
216
217
218
219
/*! \brief Return number of epochs in GMT 
 *
 */
time_t nmxp_data_gmtime_now();


220
221
222
223
224
225
226
227
/*! \brief Compute latency from current time and struct NMXP_DATA_PROCESS
 *
 * \param pd Pointer to struct NMXP_DATA_PROCESS
 *
 */
double nmxp_data_latency(NMXP_DATA_PROCESS *pd);


228
/*! \brief Print info about struct NMXP_DATA_PROCESS
229
 *
230
 * \param pd Pointer to struct NMXP_DATA_PROCESS
231
 * \param flag_sample If it is not equal to zero sample values will be printed
232
233
 *
 */
234
int nmxp_data_log(NMXP_DATA_PROCESS *pd, int flag_sample);
235

236

237
238
239
240
/*! \brief Parse string and set value in ret_tm
 *
 *
 */
241
int nmxp_data_parse_date(const char *pstr_date, NMXP_TM_T *ret_tmt);
242
243
244
245
246
247


/*! \brief Wrapper for timegm
 *
 *
 */
248
double nmxp_data_tm_to_time(NMXP_TM_T *tmt);
249

250
251
252
253

/*! \brief Return path of the current directory
 *
 * Return value need to be freed!
254
255
256
 */
char *nmxp_data_gnu_getcwd ();

257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278

/*! \brief Check if the directory exists
 *
 * \retval 1 exists, 0 otherwise.
 */
int nmxp_data_dir_exists (char *dirname);


/*! \brief Check if the directory exists
 *
 * Return value need to be freed!
 */
char *nmxp_data_dir_abspath (char *dirname);


/*! \brief Create the directory.
 * Wrapper for mkdir() over different systems.
 */
int nmxp_data_mkdir(const char *dirname);


/*! \brief Create the directory and subdirectories if is needed
279
280
 */
int nmxp_data_mkdirp(const char *filename);
281

282

283
284
285
/*! \brief Initialize a structure NMXP_DATA_SEED
 *
 *  \param data_seed Pointer to a NMXP_DATA_SEED structure.
Matteo Quintiliani's avatar
Matteo Quintiliani committed
286
287
288
 *  \param default_network String containing default network code.
 *  \param outdirseed Root output directory for SDS or BUD structure.
 *  \param type_writeseed Declare SDS or BUD structure.
289
290
 *
 */
291
292
293
294
295
int nmxp_data_seed_init(NMXP_DATA_SEED *data_seed, char *default_network, char *outdirseed, NMXP_DATA_SEED_TYPEWRITE type_writeseed);

/*! \brief Open file in a structure NMXP_DATA_SEED, in case close file before.
 *
 *  \param data_seed Pointer to a NMXP_DATA_SEED structure.
Matteo Quintiliani's avatar
Matteo Quintiliani committed
296
297
 *  
 *  N.B. nmxp_data_seed_fopen() reads information from data_seed->pd.
298
299
 *
 */
300
int nmxp_data_seed_fopen(NMXP_DATA_SEED *data_seed);
301

302
303
304
/*! \brief Close file in a structure NMXP_DATA_SEED
 *
 *  \param data_seed Pointer to a NMXP_DATA_SEED structure.
Matteo Quintiliani's avatar
Matteo Quintiliani committed
305
 *  \param i Index of the file descriptor to delete.
306
307
308
309
310
311
312
313
314
315
 *
 */
int nmxp_data_seed_fclose(NMXP_DATA_SEED *data_seed, int i);

/*! \brief Close all file in a structure NMXP_DATA_SEED
 *
 *  \param data_seed Pointer to a NMXP_DATA_SEED structure.
 *
 */
int nmxp_data_seed_fclose_all(NMXP_DATA_SEED *data_seed);
316

317
318
319
320
321
322
323

/*! \brief
 *
 */
int nmxp_data_get_filename_ms(NMXP_DATA_SEED *data_seed, char *dirseedchan, char *filenameseed);


324
325
/*! \brief Write mini-seed records from a NMXP_DATA_PROCESS structure.
 *
Matteo Quintiliani's avatar
Matteo Quintiliani committed
326
327
328
 * \param pd Pointer to struct NMXP_DATA_PROCESS.
 * \param data_seed Pointer to struct NMXP_DATA_SEED.
 * \param pmsr Pointer to mini-SEED record.
Matteo Quintiliani's avatar
Matteo Quintiliani committed
329
330
 *
 * \warning pmsr is used like (void *) but it has to be a pointer to MSRecord !!!
331
332
333
334
 *
 * \return Returns the number records created on success and -1 on error. Return value of msr_pack().
 *
 */
335
int nmxp_data_msr_pack(NMXP_DATA_PROCESS *pd, NMXP_DATA_SEED *data_seed, void *pmsr);
336

337
338
339
340
341

/*! \brief Swap 2 bytes. 
 *
 * \param in Variable length 2 bytes.
 *
Matteo Quintiliani's avatar
Matteo Quintiliani committed
342
 */
343
344
345
346
347
348
349
void nmxp_data_swap_2b (int16_t *in);


/*! \brief Swap 3 bytes. 
 *
 * \param in Variable length 3 bytes.
 *
Matteo Quintiliani's avatar
Matteo Quintiliani committed
350
 */
351
352
353
354
355
356
357
void nmxp_data_swap_3b (unsigned char *in);


/*! \brief Swap 4 bytes. 
 *
 * \param in Variable length 4 bytes.
 *
Matteo Quintiliani's avatar
Matteo Quintiliani committed
358
 */
359
360
361
362
363
364
365
void nmxp_data_swap_4b (int32_t *in);


/*! \brief Swap 8 bytes. 
 *
 * \param in Variable length 8 bytes.
 *
Matteo Quintiliani's avatar
Matteo Quintiliani committed
366
 */
367
void nmxp_data_swap_8b (double *in);
368
369


Matteo Quintiliani's avatar
Matteo Quintiliani committed
370
371
372
373
374
375
376
377
378
379
380
/*! \brief Determine the byte order of the host machine. 
 *  Due to the lack of portable defines to determine host byte order this
 *  run-time test is provided.  The code below actually tests for
 *  little-endianess, the only other alternative is assumed to be big endian.
 *
 *  \retval 0 if the host is little endian.
 *  \retval 1 otherwise.
 */
int nmxp_data_bigendianhost ();


381
382
#endif