Skip to content
Snippets Groups Projects
make_cal.py 4.46 KiB
Newer Older
  • Learn to ignore specific revisions
  • #! /usr/bin/env python
    
    """
    Usage:
        python make_cal.py OBSERVATORY YEAR
    """
    
    
    from datetime import datetime
    import itertools
    import json
    import os
    import sys
    import urllib2
    
    
    ############################################################################
    # CONFIGURATION
    
    # format used to output files
    # "{OBSERVATORY}" and "{YEAR}" are replaced with argument values
    FILENAME_FORMAT = './{OBSERVATORY}{YEAR}WebAbsMaster.cal'
    
    # url for observation web service
    SERVICE_URL = 'https://geomag.usgs.gov/baselines/observation.json.php'
    
    ############################################################################
    # DO NOT EDIT BELOW THIS LINE
    
    
    # parse observatory and year arguments
    if len(sys.argv) != 3:
        cmd = sys.argv[0]
        print >> sys.stderr, 'Usage:   {} OBSERVATORY YEAR'.format(cmd)
        print >> sys.stderr, 'Example: {} BOU 2016'.format(cmd)
        sys.exit(1)
    
    OBSERVATORY = sys.argv[1]
    YEAR = int(sys.argv[2])
    
    
    # request observations from service
    url = SERVICE_URL + '?' + '&'.join([
        'observatory=' + OBSERVATORY,
        'starttime=' + str(YEAR) + '-01-01',
        'endtime=' + str(YEAR + 1) + '-01-01',
    ])
    
    try:
        print >> sys.stderr, 'Loading data from web service\n\t{}'.format(url)
        response = urllib2.urlopen(url,
            # allow environment certificate bundle override
            cafile=os.environ.get('SSL_CERT_FILE'))
        data = response.read()
        observations = json.loads(data)
    except Exception, e:
        print >> sys.stderr, 'Error loading data ({})'.format(str(e))
        sys.exit(1)
    
    
    # extract all valid cal values
    cals = []
    for observation in observations['data']:
        for reading in observation['readings']:
            for channel in ['H', 'D', 'Z']:
                cal = reading[channel]
                if not cal['absolute'] or \
                        not cal['baseline'] or \
                        not cal['end'] or \
                        not cal['start'] or \
                        not cal['valid']:
                    # not a valid cal value
                    continue
                # convert D values from degrees to minutes
                multiplier = 60 if channel == 'D' else 1
                absolute = cal['absolute'] * multiplier
                baseline = cal['baseline'] * multiplier
                end = datetime.utcfromtimestamp(cal['end'])
                start = datetime.utcfromtimestamp(cal['start'])
                cals.append({
                    'absolute': absolute,
                    'baseline': baseline,
                    'channel': channel,
                    'end': end,
                    'start': start
                })
    
    
    # format calfile
    CAL_HEADER_FORMAT = '--{date:%Y %m %d} ({channel})'
    CAL_LINE_FORMAT = '{start:%H%M}-{end:%H%M} c{baseline:9.1f}{absolute:9.1f}'
    
    calfile = []
    # output by date in order
    cals = sorted(cals, key=lambda c: c['start'])
    # group by date
    for date, cals in itertools.groupby(cals, key=lambda c: c['start'].date()):
    
        # convert group to list so it can be reused
        cals = list(cals)
    
        # within each day, order by H, then D, then Z
        for channel in ['H', 'D', 'Z']:
            channel_cals = [c for c in cals if c['channel'] == channel]
            if not channel_cals:
                # no matching values
                continue
            # add channel header
            calfile.append(CAL_HEADER_FORMAT.format(channel=channel, date=date))
            calfile.extend([CAL_LINE_FORMAT.format(**c) for c in channel_cals])
    
    
    
    # write calfile
    filename = FILENAME_FORMAT.format(OBSERVATORY=OBSERVATORY, YEAR=YEAR)
    print >> sys.stderr, 'Writing cal file to {}'.format(filename)
    with open(filename, 'wb', -1) as f:
    
        f.write(os.linesep.join(calfile))
    
    
    
    """
    CAL format example:
    - ordered by date
    - within date, order by H, then D, then Z component
    - component values order by start time
    - D component values in minutes.
    
    
    --2015 03 30 (H)
    2140-2143 c    175.0  12531.3
    2152-2156 c    174.9  12533.3
    2205-2210 c    174.8  12533.1
    2220-2223 c    174.9  12520.7
    --2015 03 30 (D)
    2133-2137 c   1128.3   1118.5
    2145-2149 c   1128.4   1116.4
    2159-2203 c   1128.3   1113.1
    2212-2216 c   1128.4   1113.5
    --2015 03 30 (Z)
    2140-2143 c    -52.9  55403.4
    2152-2156 c    -52.8  55403.8
    2205-2210 c    -52.8  55404.0
    2220-2223 c    -52.8  55410.5
    --2015 07 27 (H)
    2146-2151 c    173.5  12542.5
    2204-2210 c    173.8  12542.5
    2225-2229 c    173.8  12547.2
    2240-2246 c    173.6  12538.7
    --2015 07 27 (D)
    2137-2142 c   1127.8   1109.2
    2154-2158 c   1128.3   1106.3
    2213-2220 c   1128.0   1106.3
    2232-2237 c   1128.3   1104.7
    --2015 07 27 (Z)
    2146-2151 c    -53.9  55382.7
    2204-2210 c    -54.0  55382.5
    2225-2229 c    -54.1  55383.7
    2240-2246 c    -54.1  55389.0
    """