Skip to content

Commit aa5c34c

Browse files
author
Chad Trabant
committed
Round FSDH start time to nearest tenths of milliseconds and make range of microsecond offset between -50 and +49. Fixes bug in microsecond offset calculation before Jan 1, 1970
1 parent a2d2dd6 commit aa5c34c

File tree

6 files changed

+79
-27
lines changed

6 files changed

+79
-27
lines changed

ChangeLog

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,18 @@
1+
2015.213: 2.17
2+
- Round Fixed Section Data Header start time values to the nearest
3+
tenth of millisecond and restrict the microsecond offset value
4+
to a range between -50 and +49 as recommended in SEED. Previously
5+
start times were truncated at tenths of millisecond resolution
6+
and the microsecond offset value was between 0 and +99. This also
7+
addresses a bug where microsecond offsets were off by 100ms for times
8+
before Jan 1 1970. Thanks to Lion Krischer for reporting.
9+
10+
Note to future hackers: the definition of HPTMODULUS governing the
11+
time tick interval for high precision time values implies that this
12+
tick interval may be changed. In reality, this should not be changed
13+
from the default, microsecond tick value without thorough testing.
14+
Some logic is know to be dependent on the microsecond tick.
15+
116
2015.134: 2.16m
217
- Add defines for needed integer types and macros from inttypes.h
318
missing in older MSVC versions. MSVC 2010 and later appear to have

Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
# CFLAGS : Specify compiler options to use
66

77
MAJOR_VER = 2
8-
MINOR_VER = 16
8+
MINOR_VER = 17
99
CURRENT_VER = $(MAJOR_VER).$(MINOR_VER)
1010
COMPAT_VER = $(MAJOR_VER).$(MINOR_VER)
1111

genutils.c

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* ORFEUS/EC-Project MEREDIAN
88
* IRIS Data Management Center
99
*
10-
* modified: 2015.108
10+
* modified: 2015.213
1111
***************************************************************************/
1212

1313
#include <stdio.h>
@@ -589,6 +589,46 @@ ms_btime2seedtimestr (BTime *btime, char *seedtimestr)
589589
} /* End of ms_btime2seedtimestr() */
590590

591591

592+
/***************************************************************************
593+
* ms_hptime2tomsusecoffset:
594+
*
595+
* Convert a high precision epoch time to a time value in tenths of
596+
* milliseconds (aka toms) and a microsecond offset (aka usecoffset).
597+
*
598+
* The tenths of milliseconds value will be rounded to the nearest
599+
* value having a microsecond offset value between -50 to +49.
600+
*
601+
* Returns 0 on success and -1 on error.
602+
***************************************************************************/
603+
int
604+
ms_hptime2tomsusecoffset (hptime_t hptime, hptime_t *toms, int8_t *usecoffset)
605+
{
606+
if ( toms == NULL || usecoffset == NULL )
607+
return -1;
608+
609+
/* Split time into tenths of milliseconds and microseconds */
610+
*toms = hptime / (HPTMODULUS / 10000);
611+
*usecoffset = hptime - (*toms * (HPTMODULUS / 10000));
612+
613+
/* Round tenths and adjust microsecond offset to -50 to +49 range */
614+
if ( *usecoffset > 49 && *usecoffset < 100 )
615+
{
616+
*toms += 1;
617+
*usecoffset -= 100;
618+
}
619+
else if ( *usecoffset < -50 && *usecoffset > -100 )
620+
{
621+
*toms -= 1;
622+
*usecoffset += 100;
623+
}
624+
625+
/* Convert tenths of milliseconds to be in hptime_t (HPTMODULUS) units */
626+
*toms *= (HPTMODULUS / 10000);
627+
628+
return 0;
629+
} /* End of ms_hptime2tomsusecoffset() */
630+
631+
592632
/***************************************************************************
593633
* ms_hptime2btime:
594634
*

libmseed.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,8 +30,8 @@ extern "C" {
3030

3131
#include "lmplatform.h"
3232

33-
#define LIBMSEED_VERSION "2.16m"
34-
#define LIBMSEED_RELEASE "2015.134"
33+
#define LIBMSEED_VERSION "2.17"
34+
#define LIBMSEED_RELEASE "2015.213"
3535

3636
#define MINRECLEN 128 /* Minimum Mini-SEED record length, 2^7 bytes */
3737
/* Note: the SEED specification minimum is 256 */
@@ -658,6 +658,7 @@ extern hptime_t ms_btime2hptime (BTime *btime);
658658
extern char* ms_btime2isotimestr (BTime *btime, char *isotimestr);
659659
extern char* ms_btime2mdtimestr (BTime *btime, char *mdtimestr);
660660
extern char* ms_btime2seedtimestr (BTime *btime, char *seedtimestr);
661+
extern int ms_hptime2tomsusecoffset (hptime_t hptime, hptime_t *toms, int8_t *usecoffset);
661662
extern int ms_hptime2btime (hptime_t hptime, BTime *btime);
662663
extern char* ms_hptime2isotimestr (hptime_t hptime, char *isotimestr, flag subsecond);
663664
extern char* ms_hptime2mdtimestr (hptime_t hptime, char *mdtimestr, flag subsecond);

msrutils.c

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* ORFEUS/EC-Project MEREDIAN
88
* IRIS Data Management Center
99
*
10-
* modified: 2015.108
10+
* modified: 2015.213
1111
***************************************************************************/
1212

1313
#include <stdio.h>
@@ -257,6 +257,8 @@ int
257257
msr_normalize_header ( MSRecord *msr, flag verbose )
258258
{
259259
struct blkt_link_s *cur_blkt;
260+
hptime_t hptimems;
261+
int8_t usecoffset;
260262
char seqnum[7];
261263
int offset = 0;
262264
int blktcnt = 0;
@@ -266,6 +268,9 @@ msr_normalize_header ( MSRecord *msr, flag verbose )
266268
if ( ! msr )
267269
return -1;
268270

271+
/* Get start time rounded to tenths of milliseconds and microsecond offset */
272+
ms_hptime2tomsusecoffset (msr->starttime, &hptimems, &usecoffset);
273+
269274
/* Update values in fixed section of data header */
270275
if ( msr->fsdh )
271276
{
@@ -285,7 +290,7 @@ msr_normalize_header ( MSRecord *msr, flag verbose )
285290
ms_strncpopen (msr->fsdh->station, msr->station, 5);
286291
ms_strncpopen (msr->fsdh->location, msr->location, 2);
287292
ms_strncpopen (msr->fsdh->channel, msr->channel, 3);
288-
ms_hptime2btime (msr->starttime, &(msr->fsdh->start_time));
293+
ms_hptime2btime (hptimems, &(msr->fsdh->start_time));
289294

290295
/* When the sampling rate is <= 32767 Hertz determine the factor
291296
* and multipler through rational approximation. For higher rates
@@ -311,7 +316,7 @@ msr_normalize_header ( MSRecord *msr, flag verbose )
311316
msr->fsdh->blockette_offset = 0;
312317
}
313318

314-
/* Traverse blockette chain and performs necessary updates*/
319+
/* Traverse blockette chain and perform necessary updates*/
315320
cur_blkt = msr->blkts;
316321

317322
if ( cur_blkt && verbose > 2 )
@@ -352,14 +357,7 @@ msr_normalize_header ( MSRecord *msr, flag verbose )
352357

353358
else if ( cur_blkt->blkt_type == 1001 )
354359
{
355-
hptime_t sec, usec;
356-
357-
/* Insert microseconds offset */
358-
sec = msr->starttime / (HPTMODULUS / 10000);
359-
usec = msr->starttime - (sec * (HPTMODULUS / 10000));
360-
usec /= (HPTMODULUS / 1000000);
361-
362-
msr->Blkt1001->usec = (int8_t) usec;
360+
msr->Blkt1001->usec = usecoffset;
363361
offset += sizeof (struct blkt_1001_s);
364362
}
365363

pack.c

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Written by Chad Trabant,
88
* IRIS Data Management Center
99
*
10-
* modified: 2015.062
10+
* modified: 2015.213
1111
***************************************************************************/
1212

1313
#include <stdio.h>
@@ -847,6 +847,8 @@ msr_update_header ( MSRecord *msr, char *rawrec, flag swapflag,
847847
struct blkt_1001_s *blkt1001, flag verbose )
848848
{
849849
struct fsdh_s *fsdh;
850+
hptime_t hptimems;
851+
int8_t usecoffset;
850852
char seqnum[7];
851853

852854
if ( ! msr || ! rawrec )
@@ -861,30 +863,26 @@ msr_update_header ( MSRecord *msr, char *rawrec, flag swapflag,
861863
snprintf (seqnum, 7, "%06d", msr->sequence_number);
862864
memcpy (fsdh->sequence_number, seqnum, 6);
863865

866+
/* Get start time rounded to tenths of milliseconds and microsecond offset */
867+
ms_hptime2tomsusecoffset (msr->starttime, &hptimems, &usecoffset);
868+
864869
/* Update fixed-section start time */
865-
ms_hptime2btime (msr->starttime, &(fsdh->start_time));
870+
ms_hptime2btime (hptimems, &(fsdh->start_time));
866871

867872
/* Swap byte order? */
868873
if ( swapflag )
869874
{
870875
MS_SWAPBTIME (&fsdh->start_time);
871876
}
872877

873-
/* Update microseconds if Blockette 1001 is present */
878+
/* Update microsecond offset value if Blockette 1001 is present */
874879
if ( msr->Blkt1001 && blkt1001 )
875880
{
876-
hptime_t sec, usec;
877-
878-
/* Calculate microseconds offset */
879-
sec = msr->starttime / (HPTMODULUS / 10000);
880-
usec = msr->starttime - (sec * (HPTMODULUS / 10000));
881-
usec /= (HPTMODULUS / 1000000);
882-
883881
/* Update microseconds offset in blockette chain entry */
884-
msr->Blkt1001->usec = (int8_t) usec;
882+
msr->Blkt1001->usec = usecoffset;
885883

886884
/* Update microseconds offset in packed header */
887-
blkt1001->usec = (int8_t) usec;
885+
blkt1001->usec = usecoffset;
888886
}
889887

890888
return 0;

0 commit comments

Comments
 (0)