1
|
|
|
# -*- coding: utf-8 -*- |
2
|
|
|
|
3
|
|
|
"""Entry point for the Command Line Interface""" |
4
|
|
|
|
5
|
|
|
import argparse |
6
|
|
|
import datetime as dt |
7
|
|
|
import numpy as np |
8
|
|
|
import sys |
9
|
|
|
|
10
|
|
|
import apexpy |
11
|
|
|
|
12
|
|
|
STDIN = sys.stdin.buffer |
13
|
|
|
STDOUT = sys.stdout.buffer |
14
|
|
|
|
15
|
|
|
|
16
|
|
|
def main(): |
17
|
|
|
"""Entry point for the script""" |
18
|
|
|
|
19
|
|
|
# Construct the description and parser for command-line arguments |
20
|
|
|
desc = 'Converts between geodetic, modified apex, quasi-dipole and MLT' |
21
|
|
|
parser = argparse.ArgumentParser(description=desc, prog='apexpy') |
22
|
|
|
|
23
|
|
|
parser.add_argument('source', metavar='SOURCE', |
24
|
|
|
choices=['geo', 'apex', 'qd', 'mlt'], |
25
|
|
|
help='Convert from {geo, apex, qd, mlt}') |
26
|
|
|
parser.add_argument('dest', metavar='DEST', |
27
|
|
|
choices=['geo', 'apex', 'qd', 'mlt'], |
28
|
|
|
help='Convert to {geo, apex, qd, mlt}') |
29
|
|
|
desc = ''.join(['YYYY[MM[DD[HHMMSS]]] date/time for IGRF coefficients, ', |
30
|
|
|
'time part required for MLT calculations']) |
31
|
|
|
parser.add_argument('date', metavar='DATE', help=desc) |
32
|
|
|
parser.add_argument('--height', dest='height', default=0, metavar='HEIGHT', |
33
|
|
|
type=float, help='height for conversion') |
34
|
|
|
parser.add_argument('--refh', dest='refh', metavar='REFH', type=float, |
35
|
|
|
default=0, |
36
|
|
|
help='reference height for modified apex coordinates') |
37
|
|
|
parser.add_argument('-i', '--input', dest='file_in', metavar='FILE_IN', |
38
|
|
|
type=argparse.FileType('r'), default=STDIN, |
39
|
|
|
help='input file (stdin if none specified)') |
40
|
|
|
parser.add_argument('-o', '--output', dest='file_out', metavar='FILE_OUT', |
41
|
|
|
type=argparse.FileType('wb'), default=STDOUT, |
42
|
|
|
help='output file (stdout if none specified)') |
43
|
|
|
|
44
|
|
|
# Get the command line arguements |
45
|
|
|
args = parser.parse_args() |
46
|
|
|
arg_array = np.loadtxt(args.file_in, ndmin=2) |
47
|
|
|
|
48
|
|
|
# Test the input arguments |
49
|
|
|
if 'mlt' in [args.source, args.dest] and len(args.date) < 14: |
50
|
|
|
desc = 'full date/time YYYYMMDDHHMMSS required for MLT calculations' |
51
|
|
|
raise ValueError(desc) |
52
|
|
|
if 9 <= len(args.date) and len(args.date) <= 13: |
53
|
|
|
desc = 'full date/time must be given as YYYYMMDDHHMMSS, not ' \ |
54
|
|
|
+ 'YYYYMMDDHHMMSS'[:len(args.date)] |
55
|
|
|
raise ValueError(desc) |
56
|
|
|
|
57
|
|
|
# Format the time input |
58
|
|
|
in_time = dt.datetime.strptime(args.date, |
59
|
|
|
'%Y%m%d%H%M%S'[:len(args.date) - 2]) |
60
|
|
|
|
61
|
|
|
# Run the desired apex conversion |
62
|
|
|
apex_obj = apexpy.Apex(date=in_time, refh=args.refh) |
63
|
|
|
lats, lons = apex_obj.convert(arg_array[:, 0], arg_array[:, 1], args.source, |
64
|
|
|
args.dest, args.height, datetime=in_time) |
65
|
|
|
|
66
|
|
|
# Save the output to a file. Use the name for non-stdout inputs |
67
|
|
|
if args.file_out.name.lower().find('stdout') >= 0: |
68
|
|
|
fout_name = args.file_out |
69
|
|
|
else: |
70
|
|
|
fout_name = args.file_out.name |
71
|
|
|
np.savetxt(fout_name, np.column_stack((lats, lons)), fmt='%.8f') |
72
|
|
|
|
73
|
|
|
return |
74
|
|
|
|
75
|
|
|
|
76
|
|
|
if __name__ == '__main__': |
77
|
|
|
sys.exit(main()) |
78
|
|
|
|