|
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
|
|
|
|