1
|
|
|
# Copyright (C) 2019 NRL |
2
|
|
|
# Author: Angeline Burrell |
3
|
|
|
# Disclaimer: This code is under the MIT license, whose details can be found at |
4
|
|
|
# the root in the LICENSE file |
5
|
|
|
# |
6
|
|
|
# -*- coding: utf-8 -*- |
7
|
|
|
"""Executed when aacgmv2 is invoked with python -m aacgmv2.""" |
8
|
|
|
|
9
|
|
|
|
10
|
|
|
import argparse |
11
|
|
|
import datetime as dt |
12
|
|
|
import numpy as np |
13
|
|
|
import sys |
14
|
|
|
|
15
|
|
|
import aacgmv2 |
16
|
|
|
|
17
|
|
|
|
18
|
|
|
def main(): |
19
|
|
|
"""Entry point for the script.""" |
20
|
|
|
desc = 'Converts between geographical coordinates, AACGM-v2, and MLT' |
21
|
|
|
parser = argparse.ArgumentParser(description=desc) |
22
|
|
|
|
23
|
|
|
desc = 'for help, run %(prog)s SUBCOMMAND -h' |
24
|
|
|
subparsers = parser.add_subparsers(title='Subcommands', prog='aacgmv2', |
25
|
|
|
dest='subcommand', description=desc) |
26
|
|
|
subparsers.required = True |
27
|
|
|
|
28
|
|
|
desc = 'convert to/from geomagnetic coordinates. Input file must have lines' |
29
|
|
|
desc += 'of the form "LAT LON ALT".' |
30
|
|
|
parser_convert = subparsers.add_parser('convert', help=(desc)) |
31
|
|
|
|
32
|
|
|
desc = 'convert between magnetic local time (MLT) and AACGM-v2 longitude. ' |
33
|
|
|
desc += 'Input file must have a single number on each line.' |
34
|
|
|
parser_convert_mlt = subparsers.add_parser('convert_mlt', help=(desc)) |
35
|
|
|
|
36
|
|
|
desc = 'input file (stdin if none specified)' |
37
|
|
|
for pp in [parser_convert, parser_convert_mlt]: |
38
|
|
|
pp.add_argument('-i', '--input', dest='file_in', metavar='FILE_IN', |
39
|
|
|
type=argparse.FileType('r'), default=sys.stdin.buffer, |
40
|
|
|
help=desc) |
41
|
|
|
pp.add_argument('-o', '--output', dest='file_out', metavar='FILE_OUT', |
42
|
|
|
type=argparse.FileType('w'), default=sys.stdout.buffer, |
43
|
|
|
help='output file (stdout if none specified)') |
44
|
|
|
|
45
|
|
|
desc = 'date for magnetic field model (1900-2020, default: today)' |
46
|
|
|
parser_convert.add_argument('-d', '--date', dest='date', metavar='YYYYMMDD', |
47
|
|
|
help=desc) |
48
|
|
|
|
49
|
|
|
desc = 'invert - convert AACGM to geographic instead of geographic to AACGM' |
50
|
|
|
parser_convert.add_argument('-v', '--a2g', dest='a2g', action='store_true', |
51
|
|
|
default=False, help=desc) |
52
|
|
|
|
53
|
|
|
desc = 'use field-line tracing instead of coefficients' |
54
|
|
|
parser_convert.add_argument('-t', '--trace', dest='trace', |
55
|
|
|
action='store_true', default=False, help=desc) |
56
|
|
|
|
57
|
|
|
desc = 'automatically use field-line tracing above 2000 km' |
58
|
|
|
parser_convert.add_argument('-a', '--allowtrace', dest='allowtrace', |
59
|
|
|
action='store_true', default=False, help=desc) |
60
|
|
|
|
61
|
|
|
desc = 'allow use of coefficients above 2000 km (bad idea!)' |
62
|
|
|
parser_convert.add_argument('-b', '--badidea', dest='badidea', |
63
|
|
|
action='store_true', default=False, help=desc) |
64
|
|
|
|
65
|
|
|
desc = 'assume inputs are geocentric with Earth radius 6371.2 km' |
66
|
|
|
parser_convert.add_argument('-g', '--geocentric', dest='geocentric', |
67
|
|
|
action='store_true', default=False, help=desc) |
68
|
|
|
|
69
|
|
|
parser_convert_mlt.add_argument('datetime', metavar='YYYYMMDDHHMMSS', |
70
|
|
|
help='date and time for conversion') |
71
|
|
|
|
72
|
|
|
desc = 'invert - convert MLT to AACGM longitude instead of AACGM longitude' |
73
|
|
|
desc += ' to MLT' |
74
|
|
|
parser_convert_mlt.add_argument('-v', '--m2a', dest='m2a', |
75
|
|
|
action='store_true', default=False, |
76
|
|
|
help=desc) |
77
|
|
|
|
78
|
|
|
args = parser.parse_args() |
79
|
|
|
array = np.loadtxt(args.file_in, ndmin=2) |
80
|
|
|
|
81
|
|
|
if args.subcommand == 'convert': |
82
|
|
|
if args.date is None: |
83
|
|
|
date = dt.date.today() |
84
|
|
|
else: |
85
|
|
|
date = dt.datetime.strptime(args.date, '%Y%m%d') |
86
|
|
|
|
87
|
|
|
code = aacgmv2.convert_bool_to_bit(a2g=args.a2g, trace=args.trace, |
88
|
|
|
allowtrace=args.allowtrace, |
89
|
|
|
badidea=args.badidea, |
90
|
|
|
geocentric=args.geocentric) |
91
|
|
|
lats, lons, alts = aacgmv2.convert_latlon_arr(array[:, 0], array[:, 1], |
92
|
|
|
array[:, 2], dtime=date, |
93
|
|
|
method_code=code) |
94
|
|
|
|
95
|
|
|
np.savetxt(args.file_out, np.column_stack((lats, lons, alts)), |
96
|
|
|
fmt='%.8f') |
97
|
|
|
elif args.subcommand == 'convert_mlt': |
98
|
|
|
dtime = dt.datetime.strptime(args.datetime, '%Y%m%d%H%M%S') |
99
|
|
|
out = np.array(aacgmv2.convert_mlt(array[:, 0], dtime, m2a=args.m2a)) |
100
|
|
|
|
101
|
|
|
if len(out.shape) == 0: |
102
|
|
|
out = np.array([out]) |
103
|
|
|
|
104
|
|
|
np.savetxt(args.file_out, out, fmt='%.8f') |
105
|
|
|
|
106
|
|
|
# If not a pipe to STDOUT or STDERR, ensure the file is closed |
107
|
|
|
not_pipe = ((args.file_out.name.find('stdout') < 0) |
108
|
|
|
& (args.file_out.name.find('stderr') < 0)) |
109
|
|
|
if not_pipe: |
110
|
|
|
args.file_out.close() |
111
|
|
|
|
112
|
|
|
|
113
|
|
|
if __name__ == '__main__': |
114
|
|
|
sys.exit(main()) |
115
|
|
|
|