From c1bf44cbe1afd808dc56c003069901dc474fd814 Mon Sep 17 00:00:00 2001
From: Stefan Mauerberger <mauerber@uni-potsdam.de>
Date: Fri, 24 Jul 2020 07:01:15 +0200
Subject: [PATCH 1/3] Custom Action-class to specify attributes `model` and
 `input`

---
 pymagglobal/__main__.py | 30 +++++++++++++++---------------
 1 file changed, 15 insertions(+), 15 deletions(-)

diff --git a/pymagglobal/__main__.py b/pymagglobal/__main__.py
index 3b774fd..0a8b79c 100644
--- a/pymagglobal/__main__.py
+++ b/pymagglobal/__main__.py
@@ -54,6 +54,20 @@ class ListModelsAction(argparse.Action):
         parser.exit()
 
 
+class ModelAction(argparse.Action):
+    '''Custom action for parsing the positional argument `model`'''
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        '''If the string passed is not a built-in model it is assumed to a
+        custom model file name'''
+        try:
+            namespace.input = models[values]
+        except KeyError:
+            namespace.input = values
+            namespace.model = 'custom model'
+
+
+
 def argument_parser():
     '''the argument parser'''
     # the main parsing
@@ -210,7 +224,7 @@ def argument_parser():
     parser.add_argument('model', type=str, help=f'one of the included models.'
                         f'use pymagglobal --list-models to get a list of '
                         f'the included models or pass a <path/to/your_model> '
-                        f'to parse your own model')
+                        f'to parse your own model', action=ModelAction)
     return parser
 
 
@@ -221,20 +235,6 @@ def main():
     parser = argument_parser()
     # parse the command line arguments
     args = parser.parse_args()
-    # check whether model and input are consistent
-    if args.model in models:
-        args.input = models[args.model]
-    else:
-        args.input = args.model
-        args.model = 'custom model'
-    """
-    if args.input is None and args.model not in models:
-        raise parser.error(f'Model {args.model} is not include in pymagglobal.'
-                           f' To process your own model, specify an input '
-                           f'file using \n'
-                           f'    $ pymagglobal --input <path/to/{args.model}> '
-                           f'... {args.model}')
-    """
     # get the right time units
     if args.longterm:
         args.t_unit = 'ka'
-- 
GitLab


From b98d982b1fd9c52f71147949092a94e8e6df6b79 Mon Sep 17 00:00:00 2001
From: Stefan Mauerberger <mauerber@uni-potsdam.de>
Date: Fri, 24 Jul 2020 09:55:55 +0200
Subject: [PATCH 2/3] Custom parser Action for the `--longterm` flag

---
 pymagglobal/__main__.py | 18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/pymagglobal/__main__.py b/pymagglobal/__main__.py
index 0a8b79c..75fb0c1 100644
--- a/pymagglobal/__main__.py
+++ b/pymagglobal/__main__.py
@@ -66,6 +66,12 @@ class ModelAction(argparse.Action):
             namespace.input = values
             namespace.model = 'custom model'
 
+class LongtermAction(argparse._StoreTrueAction):
+
+    def __call__(self, parser, namespace, values, option_string=None):
+        namespace.t_unit = 'ka'
+        namespace.t_label = r'age [ka]'
+
 
 
 def argument_parser():
@@ -89,12 +95,14 @@ def argument_parser():
     base_parser.add_argument('-o', '--output', metavar='<path/to/output>',
                              type=str, help='where to store the outputs. if '
                              f'not given, no output is stored')
-    base_parser.add_argument('--longterm', action='store_true',
+    base_parser.add_argument('--longterm', action=LongtermAction,
                              help=f'this flag is intended for longterm models.'
                              f' if given, all times will be interpreted as '
                              f'ages before the year 1950 in ka (kiloyears), '
                              f'i.e. the epoch 10 refers to the year -8050 '
                              f'without the flag')
+    # The default time unit is years AD
+    base_parser.set_defaults(t_unit='yrs.', t_label='age [yrs.]')
     # parser for arguments that are shared between time series commands
     series_base_parser = argparse.ArgumentParser(add_help=False)
 
@@ -235,14 +243,6 @@ def main():
     parser = argument_parser()
     # parse the command line arguments
     args = parser.parse_args()
-    # get the right time units
-    if args.longterm:
-        args.t_unit = 'ka'
-        args.t_label = r'age [ka]'
-    else:
-        args.t_unit = 'yrs.'
-        args.t_label = r't [yrs.]'
-
     # call the respective function, specified using .set_defaults(func=...)
     args.func(args)
     if not args.no_show:
-- 
GitLab


From bcc8c964087d28316e4e777edf51930506607f57 Mon Sep 17 00:00:00 2001
From: Stefan Mauerberger <mauerber@uni-potsdam.de>
Date: Fri, 24 Jul 2020 10:51:19 +0200
Subject: [PATCH 3/3] Coefficients: Simple plotting command

---
 pymagglobal/_commands.py | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)

diff --git a/pymagglobal/_commands.py b/pymagglobal/_commands.py
index 2b90ded..8525246 100644
--- a/pymagglobal/_commands.py
+++ b/pymagglobal/_commands.py
@@ -308,6 +308,34 @@ def coefficients(args):
             print(f'{l:d}\t{m:>{right}d}\t{g:>11.4e}')
 
 
+def plot_coeffs(gs, ls, ms):
+    """Plot Gauss coefficients
+
+    Parameters
+    ----------
+    gs : ndarray
+        Gauss-coefficients
+    ls : ndarray
+        SH degrees
+    ms : ndarray
+        SH orders
+    """
+    ms = np.array(ms)
+    lmax = np.max(ls)
+    fig, axs = plt.subplots(ncols=1, nrows=lmax, sharex=True,
+        subplot_kw={'xlim': (-lmax-0.1, lmax+0.1)})
+    fig.subplots_adjust(hspace=0)
+    for l, ax in enumerate(axs, start=1):
+        mask = np.equal(ls, l)
+        ax.scatter(ms[mask], gs[mask], marker='.')
+        ymax = 1.1*np.abs(gs[mask]).max()
+        ax.set_ylim(-ymax, ymax)
+        ax.hlines(0, *ax.get_xlim(), color='gray', lw=0.5)
+    #axs[-1].set_xticks(range(-lmax, lmax+1))
+    #axs[-1].set_xlabel('degree $m$')
+    plt.draw()
+
+
 def maps(args):
     '''Handle the map command and create field map of the model for a given
     epoch.
-- 
GitLab