Index: /issm/trunk-jpl/externalpackages/geocode/geoCode.m
===================================================================
--- /issm/trunk-jpl/externalpackages/geocode/geoCode.m	(revision 28011)
+++ /issm/trunk-jpl/externalpackages/geocode/geoCode.m	(revision 28012)
@@ -15,5 +15,5 @@
 
 % Copyright(c) 2012, Stuart P. Layton <stuart.layton@gmail.com>
-% http://stuartlayton.com
+% https://stuartlayton.com
 %
 % Revision History
@@ -46,5 +46,5 @@
 switch lower(service)
     case('google')
-        SERVER_URL = 'http://maps.google.com';
+        SERVER_URL = 'https://maps.google.com';
         queryUrl = sprintf('%s/maps/geo?output=xml&q=%s',SERVER_URL, address);
         parseFcn = @parseGoogleMapsXML;
@@ -52,5 +52,5 @@
     case('yahoo')
       
-        SERVER_URL = 'http://where.yahooapis.com/geocode';
+        SERVER_URL = 'https://where.yahooapis.com/geocode';
         queryUrl = sprintf('%s?location=%s',SERVER_URL, address);
        
@@ -67,5 +67,5 @@
     case {'osm', 'openstreetmaps', 'open street maps'}
         
-		SERVER_URL = 'https://nominatim.openstreetmap.org/search';
+        SERVER_URL = 'https://nominatim.openstreetmap.org/search';
         queryUrl = sprintf('%s?format=xml&q=%s', SERVER_URL, address);
         parseFcn = @parseOpenStreetMapXML;
Index: /issm/trunk-jpl/externalpackages/geocode/install.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/geocode/install.sh	(revision 28011)
+++ /issm/trunk-jpl/externalpackages/geocode/install.sh	(revision 28012)
@@ -1,2 +1,3 @@
 #/bin/bash
 unzip geoCode.zip
+sed -i -e 's/http:/https:/g' geoCode.m
Index: /issm/trunk-jpl/externalpackages/hdf5/install-1-parallel-with_tests.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/hdf5/install-1-parallel-with_tests.sh	(revision 28011)
+++ /issm/trunk-jpl/externalpackages/hdf5/install-1-parallel-with_tests.sh	(revision 28012)
@@ -5,5 +5,5 @@
 ## Constants
 #
-VER="1.10.9"
+VER="1.14.0"
 
 PREFIX="${ISSM_DIR}/externalpackages/hdf5/install" # Set to location where external package should be installed
Index: /issm/trunk-jpl/externalpackages/hdf5/install-1-parallel.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/hdf5/install-1-parallel.sh	(revision 28011)
+++ /issm/trunk-jpl/externalpackages/hdf5/install-1-parallel.sh	(revision 28012)
@@ -5,5 +5,5 @@
 ## Constants
 #
-VER="1.10.9"
+VER="1.14.0"
 
 PREFIX="${ISSM_DIR}/externalpackages/hdf5/install" # Set to location where external package should be installed
Index: /issm/trunk-jpl/externalpackages/hdf5/install-1-with_tests.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/hdf5/install-1-with_tests.sh	(revision 28011)
+++ /issm/trunk-jpl/externalpackages/hdf5/install-1-with_tests.sh	(revision 28012)
@@ -5,5 +5,5 @@
 ## Constants
 #
-VER="1.10.9"
+VER="1.14.0"
 
 PREFIX="${ISSM_DIR}/externalpackages/hdf5/install" # Set to location where external package should be installed
Index: /issm/trunk-jpl/externalpackages/hdf5/install-1.sh
===================================================================
--- /issm/trunk-jpl/externalpackages/hdf5/install-1.sh	(revision 28011)
+++ /issm/trunk-jpl/externalpackages/hdf5/install-1.sh	(revision 28012)
@@ -5,5 +5,5 @@
 ## Constants
 #
-VER="1.10.9"
+VER="1.14.0"
 
 PREFIX="${ISSM_DIR}/externalpackages/hdf5/install" # Set to location where external package should be installed
Index: /issm/trunk-jpl/src/m/classes/stressbalance.py
===================================================================
--- /issm/trunk-jpl/src/m/classes/stressbalance.py	(revision 28011)
+++ /issm/trunk-jpl/src/m/classes/stressbalance.py	(revision 28012)
@@ -30,5 +30,5 @@
         self.isnewton = 0
         self.FSreconditioning = 0
-        self.icefront = np.nan
+        #self.icefront = np.nan -- no longer in use
         self.maxiter = 0
         self.shelf_dampening = 0
@@ -58,5 +58,5 @@
         s += '{}\n'.format(fielddisplay(self, 'spcvy', 'y-axis velocity constraint (NaN means no constraint) [m / yr]'))
         s += '{}\n'.format(fielddisplay(self, 'spcvz', 'z-axis velocity constraint (NaN means no constraint) [m / yr]'))
-        s += '{}\n'.format(fielddisplay(self, 'icefront', 'segments on ice front list (last column 0: Air, 1: Water, 2: Ice'))
+        #s += '{}\n'.format(fielddisplay(self, 'icefront', 'segments on ice front list (last column 0: Air, 1: Water, 2: Ice'))
         s += '      MOLHO boundary conditions:\n'
         s += '{}\n'.format(fielddisplay(self, 'spcvx_base', 'x-axis basal velocity constraint (NaN means no constraint) [m / yr]'))
Index: /issm/trunk-jpl/src/m/contrib/musselman/HEDUnet_filter_plots.ipynb
===================================================================
--- /issm/trunk-jpl/src/m/contrib/musselman/HEDUnet_filter_plots.ipynb	(revision 28012)
+++ /issm/trunk-jpl/src/m/contrib/musselman/HEDUnet_filter_plots.ipynb	(revision 28012)
@@ -0,0 +1,316 @@
+{
+ "cells": [
+  {
+   "cell_type": "code",
+   "execution_count": 187,
+   "id": "a8eb592a-c7cf-4615-897b-42fc2bbfe29b",
+   "metadata": {
+    "tags": []
+   },
+   "outputs": [],
+   "source": [
+    "import shutil\n",
+    "import yaml\n",
+    "from datetime import datetime\n",
+    "from pathlib import Path\n",
+    "\n",
+    "import matplotlib.pyplot as plt\n",
+    "import numpy as np\n",
+    "import torch\n",
+    "import torch.nn as nn\n",
+    "import torch.nn.functional as F\n",
+    "from docopt import docopt\n",
+    "from torch.optim import Adam\n",
+    "from torch.utils.data import DataLoader, Subset, ConcatDataset\n",
+    "from tqdm import tqdm\n",
+    "from torch.optim import lr_scheduler\n",
+    "import math\n",
+    "\n",
+    "from data_loading_4x import get_swed_dataset, get_sentinel2_dataset, get_sentinel2_4x_dataset\n",
+    "from deep_learning import get_loss, get_model, Metrics, flatui_cmap, jaccard_loss, bce_loss\n",
+    "from deep_learning.utils.data_4x import Augment\n",
+    "\n",
+    "import os"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 188,
+   "id": "c3db51cb",
+   "metadata": {},
+   "outputs": [
+    {
+     "name": "stdout",
+     "output_type": "stream",
+     "text": [
+      "Resuming training from checkpoint logs/2023-07-11_10-59-57/checkpoints/06.pt\n",
+      "Training on cpu device\n"
+     ]
+    }
+   ],
+   "source": [
+    "\n",
+    "torch.backends.cudnn.benchmark = True\n",
+    "\n",
+    "#cli_args = docopt(__doc__, version=\"Usecase 2 Training Script 1.0\")\n",
+    "#config_file = Path(cli_args['--config'])\n",
+    "config_file = Path('config_4x.yml').resolve()\n",
+    "config = yaml.load(config_file.open(), Loader=yaml.SafeLoader)\n",
+    "\n",
+    "# How to load in model (copy this and stick segformer loading model here)\n",
+    "modelclass = get_model(config['model'])\n",
+    "model = modelclass(**config['model_args'])\n",
+    "\n",
+    "#if cli_args['--resume']:\n",
+    "#    config['resume'] = cli_args['--resume']\n",
+    "\n",
+    "if 'resume' in config and config['resume']:\n",
+    "    checkpoint = Path(config['resume'])\n",
+    "    if not checkpoint.exists():\n",
+    "        raise ValueError(f\"There is no Checkpoint at {config['resume']} to resume from!\")\n",
+    "    if checkpoint.is_dir():\n",
+    "        # Load last checkpoint in run dir\n",
+    "        ckpt_nums = [int(ckpt.stem) for ckpt in checkpoint.glob('checkpoints/*.pt')]\n",
+    "        last_ckpt = max(ckpt_nums)\n",
+    "        config['resume'] = checkpoint / 'checkpoints' / f'{last_ckpt:02d}.pt'\n",
+    "    print(f\"Resuming training from checkpoint {config['resume']}\")\n",
+    "    # remove map_location=torch.device('cpu') if gpu is available\n",
+    "    model.load_state_dict(torch.load(config['resume'], map_location=torch.device('cpu')))\n",
+    "\n",
+    "cuda = True if torch.cuda.is_available() else False\n",
+    "dev = torch.device(\"cpu\") if not cuda else torch.device(\"cuda\")\n",
+    "print(f'Training on {dev} device')\n",
+    "model = model.to(dev)\n",
+    "\n",
+    "epoch = 0\n",
+    "metrics = Metrics()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 189,
+   "id": "db08d9f8",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "text/plain": [
+       "=================================================================\n",
+       "Layer (type:depth-idx)                   Param #\n",
+       "=================================================================\n",
+       "HEDUNet                                  --\n",
+       "├─Conv2d: 1-1                            224\n",
+       "├─ModuleList: 1-2                        --\n",
+       "│    └─DownBlock: 2-1                    --\n",
+       "│    │    └─Conv2d: 3-1                  4,096\n",
+       "│    │    └─BatchNorm2d: 3-2             64\n",
+       "│    │    └─ReLU: 3-3                    --\n",
+       "│    │    └─Convx2: 3-4                  55,552\n",
+       "│    └─DownBlock: 2-2                    --\n",
+       "│    │    └─Conv2d: 3-5                  16,384\n",
+       "│    │    └─BatchNorm2d: 3-6             128\n",
+       "│    │    └─ReLU: 3-7                    --\n",
+       "│    │    └─Convx2: 3-8                  221,696\n",
+       "│    └─DownBlock: 2-3                    --\n",
+       "│    │    └─Conv2d: 3-9                  65,536\n",
+       "│    │    └─BatchNorm2d: 3-10            256\n",
+       "│    │    └─ReLU: 3-11                   --\n",
+       "│    │    └─Convx2: 3-12                 885,760\n",
+       "│    └─DownBlock: 2-4                    --\n",
+       "│    │    └─Conv2d: 3-13                 262,144\n",
+       "│    │    └─BatchNorm2d: 3-14            512\n",
+       "│    │    └─ReLU: 3-15                   --\n",
+       "│    │    └─Convx2: 3-16                 3,540,992\n",
+       "├─ModuleList: 1-3                        --\n",
+       "│    └─UpBlock: 2-5                      --\n",
+       "│    │    └─ConvTranspose2d: 3-17        524,288\n",
+       "│    │    └─BatchNorm2d: 3-18            512\n",
+       "│    │    └─ReLU: 3-19                   --\n",
+       "│    │    └─Convx2: 3-20                 1,770,496\n",
+       "│    └─UpBlock: 2-6                      --\n",
+       "│    │    └─ConvTranspose2d: 3-21        131,072\n",
+       "│    │    └─BatchNorm2d: 3-22            256\n",
+       "│    │    └─ReLU: 3-23                   --\n",
+       "│    │    └─Convx2: 3-24                 442,880\n",
+       "│    └─UpBlock: 2-7                      --\n",
+       "│    │    └─ConvTranspose2d: 3-25        32,768\n",
+       "│    │    └─BatchNorm2d: 3-26            128\n",
+       "│    │    └─ReLU: 3-27                   --\n",
+       "│    │    └─Convx2: 3-28                 110,848\n",
+       "│    └─UpBlock: 2-8                      --\n",
+       "│    │    └─ConvTranspose2d: 3-29        8,192\n",
+       "│    │    └─BatchNorm2d: 3-30            64\n",
+       "│    │    └─ReLU: 3-31                   --\n",
+       "│    │    └─Convx2: 3-32                 27,776\n",
+       "├─ModuleList: 1-4                        --\n",
+       "│    └─Conv2d: 2-9                       1,026\n",
+       "│    └─Conv2d: 2-10                      514\n",
+       "│    └─Conv2d: 2-11                      258\n",
+       "│    └─Conv2d: 2-12                      130\n",
+       "│    └─Conv2d: 2-13                      66\n",
+       "├─ModuleList: 1-5                        --\n",
+       "│    └─Conv2d: 2-14                      1,026\n",
+       "│    └─Conv2d: 2-15                      514\n",
+       "│    └─Conv2d: 2-16                      258\n",
+       "│    └─Conv2d: 2-17                      130\n",
+       "│    └─Conv2d: 2-18                      66\n",
+       "=================================================================\n",
+       "Total params: 8,106,612\n",
+       "Trainable params: 8,106,612\n",
+       "Non-trainable params: 0\n",
+       "================================================================="
+      ]
+     },
+     "execution_count": 189,
+     "metadata": {},
+     "output_type": "execute_result"
+    }
+   ],
+   "source": [
+    "from torchinfo import summary\n",
+    "summary(model)"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 191,
+   "id": "05a370ee",
+   "metadata": {},
+   "outputs": [],
+   "source": [
+    "import numpy as np\n",
+    "import matplotlib.pyplot as plt\n",
+    "from torchvision import utils\n",
+    "\n",
+    "def visTensordown(tensors, ch=0, allkernels=False, nrow=8, padding=1):\n",
+    "    no_plots = len(tensors)\n",
+    "    fig, axs = plt.subplots(1, no_plots)\n",
+    "\n",
+    "    idx = no_plots - 1\n",
+    "    for tensor in tensors:\n",
+    "        tensor = tensor.__dict__['_modules']['convdown'].__dict__['_parameters']['weight']\n",
+    "        n,c,w,h = tensor.shape\n",
+    "        subtitle = f'{n} x {c}'\n",
+    "        \n",
+    "        ax = axs[idx]\n",
+    "        \n",
+    "\n",
+    "        if allkernels: tensor = tensor.view(n*c, -1, w, h)\n",
+    "        elif c != 3: tensor = tensor[:,ch,:,:].unsqueeze(dim=1)\n",
+    "\n",
+    "        cols = np.min((tensor.shape[0] // nrow + 1, 64))    \n",
+    "        grid = utils.make_grid(tensor, nrow=nrow, normalize=True, padding=padding)\n",
+    "        ax.set_title(subtitle)\n",
+    "        #ax.figsize=(nrow,cols)\n",
+    "        ax.imshow(grid.numpy().transpose((1, 2, 0)))\n",
+    "\n",
+    "        idx -= 1\n",
+    "\n",
+    "\n",
+    "\n",
+    "def visTensorup(tensors, ch=0, allkernels=False, nrow=8, padding=1):\n",
+    "    no_plots = len(tensors)\n",
+    "    fig, axs = plt.subplots(1, no_plots)\n",
+    "\n",
+    "    idx = no_plots - 1\n",
+    "    for tensor in tensors:\n",
+    "        tensor = tensor.__dict__['_modules']['up'].__dict__['_parameters']['weight']\n",
+    "        n,c,w,h = tensor.shape\n",
+    "        subtitle = f'{n} x {c}'\n",
+    "        \n",
+    "        ax = axs[idx]\n",
+    "        \n",
+    "\n",
+    "        if allkernels: tensor = tensor.view(n*c, -1, w, h)\n",
+    "        elif c != 3: tensor = tensor[:,ch,:,:].unsqueeze(dim=1)\n",
+    "\n",
+    "        cols = np.min((tensor.shape[0] // nrow + 1, 64))    \n",
+    "        grid = utils.make_grid(tensor, nrow=nrow, normalize=True, padding=padding)\n",
+    "        ax.set_title(subtitle)\n",
+    "        #ax.figsize=(nrow,cols)\n",
+    "        ax.imshow(grid.numpy().transpose((1, 2, 0)))\n",
+    "\n",
+    "        idx -= 1"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 193,
+   "id": "a763e660",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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ZcuWZcWDWX2regMqBzOTq6ysHPRaveltCQ99azuOVZLJJC0tLeJ3vPeqgtfrFeep+hN+v59QKASQ5cGhymf3nhf+JdSo+mooioLb7c6qb1EFsHoLVanXVBSFuro68dqQ3hwSiUQikRxhFBUVcfnll+NwODCbzezfv5/XXnuNSZMmceGFF2KxWDCbzaxatYoPPviAs88+m5NPPplgMEgkEuHdd9+lubmZr3/964wfPx5FUfD5fDz77LPodDq+8Y1vYLfbCYVCNDQ08M9//pORI0dy+umnC/OuXbt2sWnTJs4880xOO+00sa2xdOlS9u3bx9lnn83o0aPR6/VEIhGWLl0qFDmHC/3BTzk8PProo4wbNw6r1crcuXNZu3bt4X5KRxX33nsvxx9/PE6nk5KSEi699FIhsKKiKAp33303I0aMwGazccYZZ7Br164hX0e1lf4855VIJJIjAavVSmVlJVOnTmXmzJmMHTsWnU6Hy+WiqqqKyZMnM3XqVEpKSoAeFedZs2Yxc+ZM0Tqq1+uZOHEic+bMYfbs2UybNk0kIePHj6eqqoqqqioqKirQ6/U4HA4mTJjAxIkTqaqqori4GOhZPZo9ezbTp09n6tSp5ObmotPpqKiooKqqikmTJjFx4sTD0ql3RCYTL7/8Mrfddht33XUXW7Zs4bTTTmPhwoVCrlRycFavXs3NN9/MJ598wvLly0mlUpx77rmEw2Fxzv3338+DDz7Iww8/zIYNGygrK+Occ845ZPW0DRs28OSTTzJz5sys4//uvBKJRHKkkEwm6ejooKuri0gkIiSs29vbef/993nvvfd49913xVZZKBSio6MDq9XKyJEjRSFlJBIhGAwSDoeJRCIoioLH4+G5557j+eefZ8uWLdTV1QmL80Qigc1mY8yYMaKzIx6PEwwGcbvdtLW1CUt5dXtELdaUBZj/Pw8++CA33ngjN910EwAPPfQQ7733Ho899hj33nvvYX52RwfvvvtuVvz0009TUlLCpk2bOP3001EUhYceeoi77rqLr371qwA8++yzlJaW8uKLL/Ld73530PlDoRDXXXcdTz31VFYf/L8772D052Fw7rnnZsWq0IvKnXfe2WfMtddemxXPmDEjK/7LX/7SZ4wqMKOi7cnXahxAT396b2644Yas+K233sqK1T3U3lx22WVZ8dlnn50Vq3+oBptXqz2g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",
+      "text/plain": [
+       "<Figure size 640x480 with 4 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "layer = 1\n",
+    "#filter = model.features[layer].weight.data.clone()\n",
+    "filter = model.__dict__['_modules']['up_blocks']\n",
+    "visTensorup(filter, ch=0, allkernels=False)\n",
+    "\n",
+    "plt.axis('off')\n",
+    "plt.suptitle('Decoding Layer Filters')\n",
+    "plt.ioff()\n",
+    "plt.show()"
+   ]
+  },
+  {
+   "cell_type": "code",
+   "execution_count": 192,
+   "id": "8dac8aa0",
+   "metadata": {},
+   "outputs": [
+    {
+     "data": {
+      "image/png": "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",
+      "text/plain": [
+       "<Figure size 640x480 with 4 Axes>"
+      ]
+     },
+     "metadata": {},
+     "output_type": "display_data"
+    }
+   ],
+   "source": [
+    "layer = 1\n",
+    "#filter = model.features[layer].weight.data.clone()\n",
+    "filter = model.__dict__['_modules']['down_blocks']\n",
+    "visTensordown(filter, ch=0, allkernels=False)\n",
+    "\n",
+    "plt.axis('off')\n",
+    "plt.suptitle('Encoding Layer Filters')\n",
+    "plt.ioff()\n",
+    "plt.show()"
+   ]
+  }
+ ],
+ "metadata": {
+  "kernelspec": {
+   "display_name": "Python 3 (ipykernel)",
+   "language": "python",
+   "name": "python3"
+  },
+  "language_info": {
+   "codemirror_mode": {
+    "name": "ipython",
+    "version": 3
+   },
+   "file_extension": ".py",
+   "mimetype": "text/x-python",
+   "name": "python",
+   "nbconvert_exporter": "python",
+   "pygments_lexer": "ipython3",
+   "version": "3.7.12"
+  }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 5
+}
Index: /issm/trunk-jpl/src/m/contrib/musselman/README.txt
===================================================================
--- /issm/trunk-jpl/src/m/contrib/musselman/README.txt	(revision 28011)
+++ /issm/trunk-jpl/src/m/contrib/musselman/README.txt	(revision 28012)
@@ -51,3 +51,3 @@
 To add functionality for these additional cases, one must simply create a function to handle the case and call it using a 
 conditional case within the create_var() function. To read the data from the NetCDF4 file, add the case to the 
-copy_variable_data_to_new_model() function so that the data can be added to a new model() instance. 
+copy_variable_data_to_new_model() function so that the data can be added to a new model() instance.
Index: /issm/trunk-jpl/src/m/contrib/musselman/read_netCDF.m
===================================================================
--- /issm/trunk-jpl/src/m/contrib/musselman/read_netCDF.m	(revision 28012)
+++ /issm/trunk-jpl/src/m/contrib/musselman/read_netCDF.m	(revision 28012)
@@ -0,0 +1,526 @@
+%{
+Given a NetCDF4 file, this set of functions will perform the following:
+    1. Enter each group of the file.
+    2. For each variable in each group, update an empty model with the variable's data
+    3. Enter nested groups and repeat
+
+
+If the model you saved has subclass instances that are not in the standard model() class
+you can:
+    1. Copy lines 30-35, set the "results" string to the name of the subclass instance,
+    2. Copy and modify the make_results_subclasses() function to create the new subclass 
+        instances you need. 
+From there, the rest of this script will automatically create the new subclass 
+instance in the model you're writing to and store the data from the netcdf file there.
+%}
+
+
+function model_copy = read_netCDF(filename, varargin)
+    if nargin > 1
+        verbose = true;
+    else
+        verbose = false;
+    end
+    
+    if verbose
+        fprintf('NetCDF42C v1.1.14\n');
+    end
+    % make a model framework to fill that is in the scope of this file
+    model_copy = model();
+
+    % Check if path exists
+    if exist(filename, 'file')
+        if verbose
+            fprintf('Opening %s for reading\n', filename);
+        end
+
+        % Open the given netCDF4 file
+        NCData = netcdf.open(filename, 'NOWRITE');
+        % Remove masks from netCDF data for easy conversion: NOT WORKING
+        %netcdf.setMask(NCData, 'NC_NOFILL');
+
+        % see if results is in there, if it is we have to instantiate some classes
+        try
+            results_group_id = netcdf.inqNcid(NCData, "results");
+            model_copy = make_results_subclasses(model_copy, NCData, verbose);
+        catch
+        end % 'results' group doesn't exist 
+
+        % see if inversion is in there, if it is we may have to instantiate some classes
+        try
+            inversion_group_id = netcdf.inqNcid(NCData, "inversion");
+            model_copy = check_inversion_class(model_copy, NCData, verbose);
+        catch
+        end % 'inversion' group doesn't exist 
+        
+        % loop over first layer of groups in netcdf file
+        for group = netcdf.inqGrps(NCData)
+            group_id = netcdf.inqNcid(NCData, netcdf.inqGrpName(group));
+            %disp(netcdf.inqGrpNameFull(group_id))
+            % hand off first level to recursive search
+            model_copy = walk_nested_groups(group_id, model_copy, NCData, verbose);
+        end
+        
+        % Close the netCDF file
+        netcdf.close(NCData);
+        if verbose
+            disp('Model Successfully Copied')
+        end
+    else
+        fprintf('File %s does not exist.\n', filename);
+    end
+end
+
+
+function model_copy = make_results_subclasses(model_copy, NCData, verbose)
+    resultsGroup = netcdf.inqNcid(NCData, "results");
+    variables = netcdf.inqVarIDs(resultsGroup);
+    for name = variables
+        class_instance = netcdf.inqVar(resultsGroup, name);
+        class_instance_names_raw = netcdf.getVar(resultsGroup, name, 'char').';
+        class_instance_names = cellstr(class_instance_names_raw);
+        for index = 1:numel(class_instance_names)
+            class_instance_name = class_instance_names{index};
+            model_copy.results = setfield(model_copy.results, class_instance_name, struct());
+        end
+        %model_copy.results = setfield(model_copy.results, class_instance, class_instance_name);
+    end
+    model_copy = model_copy;
+    if verbose
+        disp('Successfully recreated results structs:')
+        for fieldname = string(fieldnames(model_copy.results))
+            disp(fieldname)
+        end
+    end
+end
+
+
+function model_copy = check_inversion_class(model_copy, NCData, verbose)
+    % get the name of the inversion class: either inversion or m1qn3inversion or taoinversion
+    inversionGroup = netcdf.inqNcid(NCData, "inversion");
+    varid = netcdf.inqVarID(inversionGroup, 'inversion_class_name');
+    inversion_class = convertCharsToStrings(netcdf.getVar(inversionGroup, varid,'char'));
+    if strcmp(inversion_class, 'm1qn3inversion')
+        model_copy.inversion = m1qn3inversion();
+        if verbose
+            disp('Successfully created inversion class instance: m1qn3inversion')
+        end
+    elseif strcmp(inversion_class, 'taoinversion')
+        model_copy.inversion = taoinversion();
+        if verbose
+            disp('Successfully created inversion class instance: taoinversion')
+        end
+    else
+        if verbose
+            disp('No inversion class was found')
+        end
+    end
+    model_copy = model_copy;
+end
+
+
+function model_copy = walk_nested_groups(group_location_in_file, model_copy, NCData, verbose)  
+    % we search the current group level for variables by getting this struct
+    variables = netcdf.inqVarIDs(group_location_in_file); 
+
+    % from the variables struct get the info related to the variables
+    for variable = variables
+        [varname, xtype, dimids, numatts] = netcdf.inqVar(group_location_in_file, variable);
+        
+        % keep an eye out for nested structs:
+        if strcmp(varname, 'this_is_a_nested')
+            is_object = true;
+            model_copy = copy_nested_struct(group_location_in_file, model_copy, NCData, verbose);
+        elseif strcmp(varname, 'name_of_cell_array')
+            is_object = true;
+            model_copy = copy_cell_array_of_objects(variables, group_location_in_file, model_copy, NCData, verbose);
+        elseif strcmp(varname, 'solution')
+            % band-aid pass..
+        else
+            if logical(exist('is_object', 'var'))
+                % already handled
+            else
+                model_copy = copy_variable_data_to_new_model(group_location_in_file, varname, xtype, model_copy, NCData, verbose);
+            end
+        end
+    end
+
+    % try to find groups in current level, if it doesn't work it's because there is nothing there
+    %try
+    % if it's a nested struct the function copy_nested_struct has already been called
+    if logical(exist('is_object', 'var'))
+        % do nothing
+    else
+        % search for nested groups in the current level to feed back to this function
+        groups = netcdf.inqGrps(group_location_in_file);
+        if not(isempty(groups))
+            for group = groups
+                group_id = netcdf.inqNcid(group_location_in_file, netcdf.inqGrpName(group));
+                %disp(netcdf.inqGrpNameFull(group_id))
+                model_copy = walk_nested_groups(group, model_copy, NCData, verbose);
+            end
+        end
+    end
+    %catch % no nested groups here
+    %end
+end
+
+
+% to read cell arrays with objects: 
+function model_copy = copy_cell_array_of_objects(variables, group_location_in_file, model_copy, NCData, verbose);
+    %{
+        The structure in netcdf for groups with the name_of_cell_array variable is like:
+
+        group: 2x6_cell_array_of_objects {
+            name_of_cell_array = <name_of_cell_array>
+
+            group: Row_1_of_2 {
+                group: Col_1_of_6 {
+                    ... other groups can be here that refer to objects
+                } // group Col_6_of_6
+            } // group Row_1_of_2
+
+            group: Row_2_of_2 {
+                group: Col_1_of_6 {
+                    ... other groups can be here that refer to objects
+                } // group Col_6_of_6
+            } // group Row_2_of_2
+        } // group 2x6_cell_array_of_objects
+
+        We have to navigate this structure to extract all the data and recreate the 
+        original structure when the model was saved
+    %}
+
+    % get the name_of_cell_array, rows and cols vars
+    name_of_cell_array_varID = netcdf.inqVarID(group_location_in_file, 'name_of_cell_array');
+    rows_varID = netcdf.inqVarID(group_location_in_file, 'rows');
+    cols_varID = netcdf.inqVarID(group_location_in_file, 'cols');
+
+    name_of_cell_array = netcdf.getVar(group_location_in_file, name_of_cell_array_varID).'; % transpose
+    rows = netcdf.getVar(group_location_in_file, rows_varID);
+    cols = netcdf.getVar(group_location_in_file, cols_varID);
+
+    % now we work backwards: make the cell array, fill it in, and assign it to the model
+
+    % make the cell array
+    cell_array_placeholder = cell(rows, cols);
+
+    % get subgroups which are elements of the cell array
+    subgroups = netcdf.inqGrps(group_location_in_file); % numerical cell array with ID's of subgroups
+
+    % enter each subgroup, get the data, assign it to the corresponding index of cell array
+    if rows > 1
+        % we go over rows
+        % set index for cell array rows
+        row_idx = 1;
+        for row = subgroups
+            % now columns
+            columns = netcdf.inqGrps(group_location_in_file);
+            
+            % set index for cell array cols
+            col_idx = 1;
+            for column = columns
+                % now variables
+                current_column_varids = netcdf.inqVarIDs(column);
+
+                % if 'class_is_a' or 'this_is_a_nested' variables is present at this level we have to handle them accordingly
+                try
+                    class_is_aID = netcdf.inqVarID(column, 'class_is_a');
+                    col_data = deserialize_class(column, NCData, verbose);
+                    is_object = true;
+                catch
+                end
+                
+                try
+                    this_is_a_nestedID = netcdf.inqVarID(column, 'this_is_a_nested');
+                    % functionality not supported
+                    disp('Error: Cell Arrays of structs not yet supported!')
+                    % copy_nested_struct(column, model_copy, NCData, verbose)
+                    is_object = true;
+                catch
+                end
+
+                if logical(exist('is_object', 'var'))
+                    % already taken care of
+                else
+                    % store the variables as normal -- to be added later
+                    disp('Error: Cell Arrays of mixed objects not yet supported!')
+                    for var = current_column_varids
+                        % not supported
+                    end
+                end
+
+                cell_array_placeholder{row_idx, col_idx} = col_data;
+                col_idx = col_idx + 1;
+            end
+            row_idx = row_idx + 1;
+        end 
+    else
+        % set index for cell array
+        col_idx = 1;
+        for column = subgroups
+            % now variables
+            current_column_varids = netcdf.inqVarIDs(column);
+
+            % if 'class_is_a' or 'this_is_a_nested' variables is present at this level we have to handle them accordingly
+            try
+                classID = netcdf.inqVarID(column, 'class_is_a');
+                col_data = deserialize_class(classID, column, NCData, verbose);
+                is_object = true;
+            catch ME
+                rethrow(ME)
+            end
+            
+            try
+                this_is_a_nestedID = netcdf.inqVarID(column, 'this_is_a_nested');
+                % functionality not supported
+                disp('Error: Cell Arrays of structs not yet supported!')
+                % col_data = copy_nested_struct(column, model_copy, NCData, verbose);
+                is_object = true;
+            catch
+            end
+            if logical(exist('is_object', 'var'))
+                % already taken care of
+            else
+                % store the variables as normal -- to be added later
+                disp('Error: Cell Arrays of mixed objects not yet supported!')
+                for var = current_column_varids
+                    % col_data = not supported
+                end
+            end
+
+            cell_array_placeholder{col_idx} = col_data;
+            col_idx = col_idx + 1;
+
+        end 
+    end
+   
+
+    % Like in copy_nested_struct, we can only handle things 1 layer deep.
+    % assign cell array to model
+    address_to_attr_list = split(netcdf.inqGrpNameFull(group_location_in_file), '/');
+    address_to_attr = address_to_attr_list{2};
+    if isprop(model_copy.(address_to_attr), name_of_cell_array);
+        model_copy.(address_to_attr).(name_of_cell_array) = cell_array_placeholder;
+    else
+        model_copy = addprop(model_copy.(address_to_attr), name_of_cell_array, cell_array_placeholder);
+    end
+
+    if verbose
+        fprintf("Successfully loaded cell array %s to %s\n", name_of_cell_array,address_to_attr_list{2})
+    end
+end
+
+
+
+
+function output = deserialize_class(classID, group, NCData, verbose)
+    %{
+        This function will recreate a class
+    %}
+
+    % get the name of the class
+    name = netcdf.getVar(group, classID).';
+
+    % instantiate it
+    class_instance = eval([name, '()']);
+
+    % get and assign properties
+    subgroups = netcdf.inqGrps(group); % numerical cell array with ID's of subgroups
+
+    if numel(subgroups) == 1
+        % get properties
+        varIDs = netcdf.inqVarIDs(subgroups);
+        for varID = varIDs
+            % var metadata
+            [varname, xtype, dimids, numatts] = netcdf.inqVar(subgroups, varID);
+            % data
+            data = netcdf.getVar(subgroups, varID);
+
+            % netcdf uses Row Major Order but MATLAB uses Column Major Order so we need to transpose all arrays w/ more than 1 dim
+            if all(size(data)~=1) || xtype == 2
+                data = data.';
+            end
+
+            % some classes have permissions... so we skip those
+            try
+                % if property already exists, assign new value
+                if isprop(class_instance, varname)
+                    class_instance.(varname) = data;
+                else
+                    addprop(class_instance, varname, data);
+                end
+            catch
+            end
+        end
+    else
+        % not supported
+    end
+    output = class_instance;
+end
+
+
+function model_copy = copy_nested_struct(group_location_in_file, model_copy, NCData, verbose)
+    %{
+        A common multidimensional struct array is the 1xn md.results.TransientSolution struct. 
+        The process to recreate is as follows:
+            1. Get the name of the struct from group name
+            2. Get the fieldnames from the subgroups 
+            3. Recreate the struct with fieldnames 
+            4. Populate the fields with their respective values
+    %}
+
+    % step 1
+    name_of_struct = netcdf.inqGrpName(group_location_in_file);
+
+    % step 2
+    subgroups = netcdf.inqGrps(group_location_in_file); % numerical cell array with ID's of subgroups
+    % get single subgroup's data
+    single_subgroup_ID = subgroups(1);
+    subgroup_varids = netcdf.inqVarIDs(single_subgroup_ID);
+    fieldnames = {};
+    for variable = subgroup_varids
+        [varname, xtype, dimids, numatts] = netcdf.inqVar(single_subgroup_ID, variable);
+        fieldnames{end+1} = varname;
+    end
+
+    % step 3
+    address_in_model_raw = split(netcdf.inqGrpNameFull(group_location_in_file), '/');
+    address_in_model = address_in_model_raw{2};
+    
+    % we cannot assign a variable to represent this object as MATLAB treats all variables as copies
+    % and not pointers to the same memory address
+    % this means that if address_in_model has more than 1 layer, we need to modify the code. For now, 
+    % we just hope this will do. An example of a no-solution would be model().abc.def.ghi.field whereas we're only assuming model().abc.field now
+    
+    model_copy.(address_in_model).(name_of_struct) = struct();
+    % for every fieldname in the subgroup, create an empty field
+    for fieldname = string(fieldnames)
+        model_copy.(address_in_model).(name_of_struct).(fieldname) = {};
+    end
+
+    % use repmat to make the struct array multidimensional along the fields axis
+    number_of_dimensions = numel(subgroups);
+    model_copy.(address_in_model).(name_of_struct) = repmat(model_copy.(address_in_model).(name_of_struct), 1, number_of_dimensions);
+    
+    % step 4
+    % for every layer of the multidimensional struct array, populate the fields
+    for current_layer = 1:number_of_dimensions
+        % choose subgroup
+        current_layer_subgroup_ID = subgroups(current_layer);
+        % get all vars
+        current_layer_subgroup_varids = netcdf.inqVarIDs(current_layer_subgroup_ID);
+        % get individual vars and set fields at layer current_layer
+        for varid = current_layer_subgroup_varids
+            [varname, xtype, dimids, numatts] = netcdf.inqVar(current_layer_subgroup_ID, varid);
+            data = netcdf.getVar(current_layer_subgroup_ID, varid);
+
+            % netcdf uses Row Major Order but MATLAB uses Column Major Order so we need to transpose all arrays w/ more than 1 dim
+            if all(size(data)~=1) || xtype == 2
+                data = data.';
+            end
+            
+            % set the field
+            model_copy.(address_in_model).(name_of_struct)(current_layer).(varname) = data;
+            %address_to_struct_in_model = setfield(address_to_struct_in_model(current_layer), varname, data)
+        end
+        model_copy.(address_in_model).(name_of_struct)(current_layer);
+        if verbose
+            fprintf("Successfully loaded layer %s to multidimension struct array\n", num2str(current_layer))
+        end
+    end
+    model_copy = model_copy;
+    if verbose
+        fprintf('Successfully recreated multidimensional structure array %s in md.%s\n', name_of_struct, address_in_model)
+    end
+end
+
+
+
+
+%{
+Since there are two types of objects that MATLAB uses (classes and structs), we have to check 
+which object we're working with before we can set any fields/attributes of it. After this is completed,
+we can write the data to that location in the model.
+%}
+
+function model_copy = copy_variable_data_to_new_model(group_location_in_file, varname, xtype, model_copy, NCData, verbose)
+    %disp(varname)
+    % this is an inversion band-aid
+    if strcmp(varname, 'inversion_class_name') || strcmp(varname, 'name_of_struct') || strcmp(varname, 'solution')
+        % we don't need this
+    else
+        % putting try/catch here so that any errors generated while copying data are logged and not lost by the try/catch in walk_nested_groups function
+        try
+            %disp(netcdf.inqGrpNameFull(group_location_in_file))
+            %disp(class(netcdf.inqGrpNameFull(group_location_in_file)))
+            address_to_attr = strrep(netcdf.inqGrpNameFull(group_location_in_file), '/', '.');
+            varid = netcdf.inqVarID(group_location_in_file, varname);
+            data = netcdf.getVar(group_location_in_file, varid);
+            
+    
+            % if we have an empty string
+            if xtype == 2 && isempty(all(data))
+                data = cell(char());
+            % if we have an empty cell-char array
+            elseif numel(data) == 1 && xtype == 3 && data == -32767
+                data = cell(char());
+            elseif isempty(all(data))
+                data = []
+            end
+            % band-aid for some cell-char-arrays:
+            if xtype == 2 && strcmp(data, 'default')
+                data = {'default'};
+            end
+            
+            % netcdf uses Row Major Order but MATLAB uses Column Major Order so we need to transpose all arrays w/ more than 1 dim
+            if all(size(data)~=1) || xtype == 2
+                data = data.';
+            end
+    
+            % if we have a list of strings
+            if xtype == 2
+                try
+                    if strcmp(netcdf.getAtt(group_location_in_file, varid, "type_is"), 'cell_array_of_strings')
+                        data = cellstr(data);
+                    end
+                catch
+                    % no attr found so we pass
+                end
+            end
+            
+            % the issm c compiler does not work with int64 datatypes, so we need to convert those to int16
+            % reference this (very hard to find) link for netcdf4 datatypes: https://docs.unidata.ucar.edu/netcdf-c/current/netcdf_8h_source.html
+            %xtype
+            if xtype == 10
+                arg_to_eval = ['model_copy', address_to_attr, '.', varname, ' = ' , 'double(data);'];
+                eval(arg_to_eval);
+                %disp('Loaded int64 as int16')
+            else
+                arg_to_eval = ['model_copy', address_to_attr, '.', varname, ' = data;'];
+                eval(arg_to_eval);
+            end
+            
+            if verbose
+                full_addy = netcdf.inqGrpNameFull(group_location_in_file);
+                %disp(xtype)
+                %class(data)
+                fprintf('Successfully loaded %s to %s\n', varname, full_addy);
+            end
+
+        catch ME %ME is an MException struct
+            % Some error occurred if you get here.
+            fprintf(1,'There was an error with %s! \n', varname)
+            errorMessage = sprintf('Error in function %s() at line %d.\n\nError Message:\n%s', ME.stack.name, ME.stack.line, ME.message);
+            fprintf(1, '%s\n', errorMessage);
+            uiwait(warndlg(errorMessage));
+            %line = ME.stack.line
+            %fprintf(1,'There was an error with %s! \n', varname)
+            %fprintf('The message was:\n%s\n',ME.message);
+            %fprintf(1,'The identifier was:\n%s\n',ME.identifier);
+            
+            % more error handling...
+        end
+    end
+    model_copy = model_copy;
+end
Index: /issm/trunk-jpl/src/m/contrib/musselman/read_netCDF.py
===================================================================
--- /issm/trunk-jpl/src/m/contrib/musselman/read_netCDF.py	(revision 28012)
+++ /issm/trunk-jpl/src/m/contrib/musselman/read_netCDF.py	(revision 28012)
@@ -0,0 +1,501 @@
+# imports
+from netCDF4 import Dataset
+import numpy as np
+import numpy.ma as ma
+from os import path, remove
+from model import *
+import re
+from results import *
+from m1qn3inversion import m1qn3inversion
+from taoinversion import taoinversion
+from collections import OrderedDict
+import sys
+from massfluxatgate import massfluxatgate
+
+
+
+'''
+Given a NetCDF4 file, this set of functions will perform the following:
+    1. Enter each group of the file.
+    2. For each variable in each group, update an empty model with the variable's data
+    3. Enter nested groups and repeat
+'''
+
+
+# make a model framework to fill that is in the scope of this file
+model_copy = model()
+
+def read_netCDF(filename, verbose = False):
+    if verbose:
+        print('NetCDF42C v1.2.0')
+
+    '''
+    filename = path and name to save file under
+    verbose = T/F = show or muted log statements. Naturally muted
+    '''
+
+    # this is a precaution so that data is not lost
+    try:
+        # check if path exists
+        if path.exists(filename):
+            if verbose:
+                print('Opening {} for reading'.format(filename))
+            else: pass
+    
+            # open the given netCDF4 file
+            NCData = Dataset(filename, 'r')
+            # remove masks from numpy arrays for easy conversion
+            NCData.set_auto_mask(False)
+        else:
+            return 'The file you entered does not exist or cannot be found in the current directory'
+        
+        # in order to handle some subclasses in the results class, we have to utilize this band-aid
+        # there will likely be more band-aids added unless a class name library is created with all class names that might be added to a md
+        try:
+            # if results has meaningful data, save the name of the subclass and class instance
+            NCData.groups['results']
+            make_results_subclasses(NCData, verbose)
+        except:
+            pass
+    
+        # similarly, we need to check and see if we have an m1qn3inversion class instance
+        try:
+            NCData.groups['inversion']
+            check_inversion_class(NCData, verbose)
+        except:
+            pass
+        
+        # walk through each group looking for subgroups and variables
+        for group in NCData.groups.keys():
+            if 'debris' in group:
+                pass
+            else:
+                # have to send a custom name to this function: filename.groups['group']
+                name = "NCData.groups['" + str(group) + "']"
+                walk_nested_groups(name, NCData, verbose)
+        
+        if verbose:
+            print("Model Successfully Loaded.")
+            
+        NCData.close()
+        
+        return model_copy
+
+    # just in case something unexpected happens
+    except Exception as e:
+        if 'NCData' in locals():
+            NCData.close()
+        raise e
+
+def make_results_subclasses(NCData, verbose = False):
+    '''
+        There are 3 possible subclasses: solution, solutionstep, resultsdakota.
+        In the NetCDF file these are saved as a list of strings. Ie, say there are 2
+        instances of solution under results, StressbalanceSolution and TransientSolution. 
+        In the NetCDF file we would see solution = "StressbalanceSolution", "TransientSolution"
+        To deconstruct this, we need to iteratively assign md.results.StressbalanceSolution = solution()
+        and md.results.TransientSolution = solution() and whatever else.
+    '''
+    # start with the subclasses
+    for subclass in NCData.groups['results'].variables.keys():
+        class_instance = subclass + '()'
+
+        # now handle the instances
+        for instance in NCData.groups['results'].variables[subclass][:]:
+            # this is an ndarray of numpy bytes_ that we have to convert to strings
+            class_instance_name = instance.tobytes().decode('utf-8').strip()
+            # from here we can make new subclasses named as they were in the model saved
+            setattr(model_copy.results, class_instance_name, eval(class_instance))
+            if verbose:
+                print(f'Successfully created results subclass instance {class_instance} named {class_instance_name}.')
+
+
+def check_inversion_class(NCData, verbose = False):
+    # get the name of the inversion class: either inversion or m1qn3inversion or taoinversion
+    inversion_class_is = NCData.groups['inversion'].variables['inversion_class_name'][:][...].tobytes().decode()
+    if inversion_class_is == 'm1qn3inversion':
+        # if it is m1qn3inversion we need to instantiate that class since it's not native to model()
+        model_copy.inversion = m1qn3inversion(model_copy.inversion)
+        if verbose:
+            print('Conversion successful')
+    elif inversion_class_is == 'taoinversion':
+        # if it is taoinversion we need to instantiate that class since it's not native to model()
+        model_copy.inversion = taoinverion()
+        if verbose:
+            print('Conversion successful')
+    else: pass
+
+
+def walk_nested_groups(group_location_in_file, NCData, verbose = False):
+    # first, we enter the group by: filename.groups['group_name']
+    # second we search the current level for variables: filename.groups['group_name'].variables.keys()
+    # at this step we check for multidimensional structure arrays/ arrays of objects and filter them out
+    # third we get nested group keys by: filename.groups['group_name'].groups.keys()
+    # if a nested groups exist, repeat all
+
+    for variable in eval(group_location_in_file + '.variables.keys()'):
+        if 'is_object' not in locals():
+            if variable == 'this_is_a_nested' and 'results' in group_location_in_file and 'qmu' not in group_location_in_file:
+                # have to do some string deconstruction to get the name of the class instance/last group from 'NetCDF.groups['group1'].groups['group1.1']'
+                pattern = r"\['(.*?)'\]"
+                matches = re.findall(pattern, group_location_in_file)
+                name_of_struct = matches[-1] #eval(group_location_in_file + ".variables['solution']") 
+                deserialize_nested_results_struct(group_location_in_file, name_of_struct, NCData)
+                is_object = True
+    
+            elif variable == 'name_of_cell_array':
+                # reconstruct an array of elements
+                deserialize_array_of_objects(group_location_in_file, model_copy, NCData, verbose)
+                is_object = True
+    
+            elif variable == 'this_is_a_nested' and 'qmu' in group_location_in_file:
+                if verbose:
+                    print('encountered qmu structure that is not yet supported.')
+                else: pass
+                    
+                is_object = True
+        
+            else:
+                location_of_variable_in_file = group_location_in_file + ".variables['" + str(variable) + "']"
+                # group_location_in_file is like filename.groups['group1'].groups['group1.1'].groups['group1.1.1']
+                # Define the regex pattern to match the groups within brackets
+                pattern = r"\['(.*?)'\]"
+                # Use regex to find all matches and return something like 'group1.group1.1.group1.1.1 ...' where the last value is the name of the variable
+                matches = re.findall(pattern, location_of_variable_in_file)
+                variable_name = matches[-1]
+                location_of_variable_in_model = '.'.join(matches[:-1])
+                deserialize_data(location_of_variable_in_file, location_of_variable_in_model, variable_name, NCData, verbose=verbose)
+
+    # if one of the variables above was an object, further subclasses will be taken care of when reconstructing it
+    if 'is_object' in locals():
+        pass
+    else:
+        for nested_group in eval(group_location_in_file + '.groups.keys()'):
+            new_nested_group = group_location_in_file + ".groups['" + str(nested_group) + "']"
+            walk_nested_groups(new_nested_group, NCData, verbose=verbose)
+
+
+
+'''
+    MATLAB has Multidimensional Structure Arrays in 2 known classes: results and qmu.
+    The python classes results.py and qmu.py emulate this MATLAB object in their own
+    unique ways. The functions in this script will assign data to either of these 
+    classes such that the final structure is compatible with its parent class.
+'''
+
+def deserialize_nested_results_struct(group_location_in_file, name_of_struct, NCData, verbose = False):
+    '''
+    A common multidimensional array is the 1xn md.results.TransientSolution object.
+
+    The way that this object emulates the MATLAB mutli-dim. struct. array is with 
+    the solution().steps attr. which is a list of solutionstep() instances
+        The process to recreate is as follows:
+            1. Get instance of solution() with solution variable (the instance is made in make_results_subclasses)
+            2. For each subgroup, create a solutionstep() class instance
+             2a. Populate the instance with the key:value pairs
+             2b. Append the instance to the solution().steps list
+    '''
+    # step 1
+    class_instance_name = name_of_struct
+    
+    # for some reason steps is not already a list
+    setattr(model_copy.results.__dict__[class_instance_name], 'steps', list())
+
+    steps = model_copy.results.__dict__[class_instance_name].steps
+    
+    # step 2
+    layer = 1
+    for subgroup in eval(group_location_in_file + ".groups.keys()"):
+        solutionstep_instance = solutionstep()
+        # step 2a
+        subgroup_location_in_file = group_location_in_file + ".groups['" + subgroup + "']"
+        for key in eval(subgroup_location_in_file + ".variables.keys()"):
+            value = eval(subgroup_location_in_file + ".variables['" + str(key) + "'][:]")
+            setattr(solutionstep_instance, key, value)
+        # step 2b
+        steps.append(solutionstep_instance)
+        if verbose:
+            print('Succesfully loaded layer ' + str(layer) + ' to results.' + str(class_instance_name) + ' struct.')
+        else: pass
+        layer += 1
+
+    if verbose:
+        print('Successfully recreated results structure ' + str(class_instance_name))
+
+
+
+def deserialize_array_of_objects(group_location_in_file, model_copy, NCData, verbose):
+    '''
+        The structure in netcdf for groups with the name_of_cell_array variable is like:
+
+        group: 2x6_cell_array_of_objects {
+            name_of_cell_array = <name_of_cell_array>
+
+            group: Row_1_of_2 {
+                group: Col_1_of_6 {
+                    ... other groups can be here that refer to objects
+                } // group Col_6_of_6
+            } // group Row_1_of_2
+
+            group: Row_2_of_2 {
+                group: Col_1_of_6 {
+                    ... other groups can be here that refer to objects
+                } // group Col_6_of_6
+            } // group Row_2_of_2
+        } // group 2x6_cell_array_of_objects
+
+        We have to navigate this structure to extract all the data and recreate the 
+        original structure when the model was saved
+    '''
+
+    if verbose: 
+        print(f"Loading array of objects.")
+
+    # get the name_of_cell_array, rows and cols vars
+    name_of_cell_array_varID = eval(group_location_in_file + ".variables['name_of_cell_array']")
+    rows_varID = eval(group_location_in_file + ".variables['rows']")
+    cols_varID = eval(group_location_in_file + ".variables['cols']")
+
+    name_of_cell_array = name_of_cell_array_varID[:][...].tobytes().decode()
+    rows = rows_varID[:]
+    cols = cols_varID[:]
+
+    # now we work backwards: make the array, fill it in, and assign it to the model
+
+    # make the array
+    array = list()
+
+    subgroups = eval(group_location_in_file + ".groups") #.keys()")
+
+    # enter each subgroup, get the data, assign it to the corresponding index of cell array
+    if rows > 1:
+        # we go over rows
+        # set index for rows
+        row_idx = 0
+        for row in list(subgroups):
+            # make list for each row
+            current_row = list()
+            columns = subgroups[str(row)].groups.keys()
+
+            # set index for columns
+            col_idx = 0
+
+            # iterate over columns
+            for col in list(columns):
+                # now get the variables 
+                current_col_vars = columns.groups[str(col)].variables
+
+                # check for special datastructures                
+                if "class_is_a" in current_col_vars:
+                    class_name = subgroups[str(col)].variables['class_is_a'][:][...].tobytes().decode()
+                    col_data = deserialize_class_instance(class_name, columns.groups[str(col)], NCData, verbose)
+                    is_object = True
+                elif "this_is_a_nested" in current_col_vars:
+                    # functionality not yet supported
+                    print('Error: Cell Arrays of structs not yet supported!')
+                    is_object = True
+                else:
+                    if 'is_object_' in locals():
+                        pass
+                        # already taken care of
+                    else:
+                        # store the variables as normal -- to be added later
+                        print('Error: Arrays of mixed objects not yet supported!')
+                        for var in current_col_vars:
+                            # this is where that functionality would be handled
+                            pass
+                col_idx += 1
+                # add the entry to our row list
+                current_row.append(col_data)
+
+            # add the list of columns to the array
+            array.append(current_row)
+            row_idx += 1
+
+    else:
+        # set index for columns
+        col_idx = 0
+
+        # iterate over columns
+        for col in list(subgroups):
+            # now get the variables 
+            current_col_vars = subgroups[str(col)].variables
+            
+            # check for special datastructures
+            if "class_is_a" in current_col_vars:
+                class_name = subgroups[str(col)].variables['class_is_a'][:][...].tobytes().decode()
+                col_data = deserialize_class_instance(class_name, subgroups[str(col)], NCData, verbose)
+                is_object = True
+            elif "this_is_a_nested" in current_col_vars:
+                # functionality not yet supported
+                print('Error: Cell Arrays of structs not yet supported!')
+                is_object = True
+            else:
+                if 'is_object_' in locals():
+                    pass
+                    # already taken care of
+                else:
+                    # store the variables as normal -- to be added later
+                    print('Error: Arrays of mixed objects not yet supported!')
+                    for var in current_col_vars:
+                        # this is where that functionality would be handled
+                        pass
+            col_idx += 1
+            # add the list of columns to the array
+            array.append(col_data)
+
+    # finally, add the attribute to the model
+    pattern = r"\['(.*?)'\]"
+    matches = re.findall(pattern, group_location_in_file)
+    variable_name = matches[0]
+    setattr(model_copy.__dict__[variable_name], name_of_cell_array, array)
+
+    if verbose:
+        print(f"Successfully loaded array of objects: {name_of_cell_array} to {variable_name}")
+
+
+
+def deserialize_class_instance(class_name, group, NCData, verbose=False):
+
+    if verbose:
+        print(f"Loading class: {class_name}")
+
+    # this function requires the class module to be imported into the namespace of this file.
+    # we make a custom error in case the class module is not in the list of imported classes.
+    # most ISSM classes are imported by from <name> import <name>
+    class ModuleError(Exception):
+        pass
+    
+    if class_name not in sys.modules:
+        raise ModuleError(str('Model requires the following class to be imported from a module: ' + class_name + ". Please add the import to read_netCDF.py in order to continue."))
+
+    # Instantiate the class
+    class_instance = eval(class_name + "()")
+
+    # Get and assign properties
+    subgroups = list(group.groups.keys())
+
+    if len(subgroups) == 1:
+        # Get properties
+        subgroup = group[subgroups[0]]
+        varIDs = subgroup.variables.keys()
+        for varname in varIDs:
+            # Variable metadata
+            var = subgroup[varname]
+
+            # Data
+            if 'char' in var.dimensions[0]:
+                data = var[:][...].tobytes().decode()
+            else:
+                data = var[:]
+
+            # Some classes may have permissions, so we skip those
+            try:
+                setattr(class_instance, varname, data)
+            except:
+                pass
+    else:
+        # Not supported
+        pass
+
+    if verbose: 
+        print(f"Successfully loaded class instance {class_name} to model")
+    return class_instance
+
+
+
+def deserialize_data(location_of_variable_in_file, location_of_variable_in_model, variable_name, NCData, verbose = False):
+    # as simple as navigating to the location_of_variable_in_model and setting it equal to the location_of_variable_in_file
+    # NetCDF4 has a property called "_FillValue" that sometimes saves empty lists, so we have to catch those
+    FillValue = -9223372036854775806
+    try:
+        # results band-aid...
+        if str(location_of_variable_in_model + '.' + variable_name) in ['results.solutionstep', 'results.solution', 'results.resultsdakota']:
+            pass
+        # qmu band-aid
+        elif 'qmu.statistics.method' in str(location_of_variable_in_model + '.' + variable_name):
+            pass
+        # handle any strings:
+        elif 'char' in eval(location_of_variable_in_file + '.dimensions[0]'):
+            setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, eval(location_of_variable_in_file + '[:][...].tobytes().decode()'))
+        # handle ndarrays + lists
+        elif len(eval(location_of_variable_in_file + '[:]'))>1:
+            # check for bool
+            try: # there is only one datatype assigned the attribute 'units' and that is bool, so anything else will go right to except
+                if eval(location_of_variable_in_file + '.units') == 'bool':
+                    setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, np.array(eval(location_of_variable_in_file + '[:]'), dtype = bool))
+                else:
+                    setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, eval(location_of_variable_in_file + '[:]'))
+            except:
+                setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, eval(location_of_variable_in_file + '[:]'))
+        # catch everything else
+        else:
+            # check for FillValue. use try/except because try block will only work on datatypes like int64, float, single element lists/arrays ect and not nd-arrays/n-lists etc
+            try:
+                # this try block will only work on single ints/floats/doubles and will skip to the except block for all other cases
+                var_to_save = eval(location_of_variable_in_file + '[:][0]')  # note the [0] on the end
+                if FillValue == var_to_save:
+                    setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, [])
+                else:
+                    if var_to_save.is_integer():
+                        setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, int(var_to_save))
+                    else:
+                        # we have to convert numpy datatypes to native python types with .item()
+                        setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, var_to_save.item())
+            except:
+                setattr(eval('model_copy.' + location_of_variable_in_model), variable_name, eval(location_of_variable_in_file + '[:]'))
+    except AttributeError:
+        deserialize_dict(location_of_variable_in_file, location_of_variable_in_model, NCData, verbose=verbose)
+
+    if verbose:
+        print('Successfully loaded ' + location_of_variable_in_model + '.' + variable_name + ' into model.')
+
+
+
+def deserialize_dict(location_of_variable_in_file, location_of_variable_in_model, NCData, verbose = False):
+    FillValue = -9223372036854775806
+
+    # the key will be the last item in the location
+    key = ''.join(location_of_variable_in_model.split('.')[-1])
+
+    # update the location to point to the dict instead of the dict key
+    location_of_variable_in_model = '.'.join(location_of_variable_in_model.split('.')[:-1])
+
+    # verify we're working with a dict:
+    if isinstance(eval('model_copy.' + location_of_variable_in_model), OrderedDict):
+        dict_object = eval('model_copy.' + location_of_variable_in_model)
+        
+        # handle any strings:
+        if 'char' in eval(location_of_variable_in_file + '.dimensions[0]'):
+            data = eval(location_of_variable_in_file + '[:][...].tobytes().decode()')
+            dict_object.update({key: data})
+            
+        # handle ndarrays + lists
+        elif len(eval(location_of_variable_in_file + '[:]'))>1:
+            # check for bool
+            try: # there is only one datatype assigned the attribute 'units' and that is bool, so anything else will go right to except
+                if eval(location_of_variable_in_file + '.units') == 'bool':
+                    data = np.array(eval(location_of_variable_in_file + '[:]'), dtype = bool)
+                    dict_object.update({key: data})
+                else:
+                    data = eval(location_of_variable_in_file + '[:]')
+                    dict_object.update({key: data})
+            except:
+                data = eval(location_of_variable_in_file + '[:]')
+                dict_object.update({key: data})
+        # catch everything else
+        else:
+            # check for FillValue. use try/except because try block will only work on datatypes like int64, float, single element lists/arrays ect and not nd-arrays/n-lists etc
+            try:
+                # this try block will only work on single ints/floats/doubles and will skip to the except block for all other cases
+                if FillValue == eval(location_of_variable_in_file + '[:][0]'):
+                    dict_object.update({key: []})
+                else:
+                    # we have to convert numpy datatypes to native python types with .item()
+                    var_to_save = eval(location_of_variable_in_file + '[:][0]')  # note the [0] on the end
+                    dict_object.update({key:  var_to_save.item()})
+            except:
+                data = eval(location_of_variable_in_file + '[:]')
+                dict_object.update({key: data})
+    else:
+        print(f"Unrecognized object was saved to NetCDF file and cannot be reconstructed: {location_of_variable_in_model}")
Index: /issm/trunk-jpl/src/m/contrib/musselman/write_netCDF.m
===================================================================
--- /issm/trunk-jpl/src/m/contrib/musselman/write_netCDF.m	(revision 28012)
+++ /issm/trunk-jpl/src/m/contrib/musselman/write_netCDF.m	(revision 28012)
@@ -0,0 +1,768 @@
+%{
+Given a model, this set of functions will perform the following:
+    1. Enter each nested class of the model.
+    2. View each attribute of each nested class.
+    3. Compare state of attribute in the model to an empty model class.
+    4. If states are identical, pass.
+    5. Otherwise, create nested groups named after class structure.
+    6. Create variable named after class attribute and assign value to it.
+%}
+
+
+function write_netCDF(model_var, filename, varargin)
+    if nargin > 2
+        verbose = true;
+    else
+        verbose = false;
+    end
+    if verbose
+        disp('MATLAB C2NetCDF4 v1.1.14');
+    end
+    
+    % model_var = class object to be saved
+    % filename = path and name to save file under
+    
+    % Create a NetCDF file to write to
+    NetCDF = make_NetCDF(filename, verbose);
+    
+    % Create an instance of an empty model class to compare model_var against
+    empty_model = model();
+
+    % Walk through the model_var class and compare subclass states to empty_model
+    walk_through_model(model_var, empty_model, NetCDF, verbose);
+
+    % in order to handle some subclasses in the results class, we have to utilize this band-aid
+    % there will likely be more band-aids added unless a class name library is created with all class names that might be added to a model
+    try
+        % if results had meaningful data, save the name of the subclass and class instance
+        netcdf.inqNcid(NetCDF,'results');
+        results_subclasses_bandaid(model_var, NetCDF, verbose);
+        % otherwise, ignore
+    catch
+    end
+    
+    netcdf.close(NetCDF);
+    if verbose
+        disp('Model successfully saved as NetCDF4');
+    end
+end
+
+
+
+function NetCDF = make_NetCDF(filename, verbose)
+    % matlab can't handle input in the jupyter interface, so we just yell at the user to rename
+    % their file if needed
+    % If file already exists delete / rename it
+    if exist(filename, 'file') == 2
+        fprintf('File %s already exists\n', filename);
+        disp('Please rename your file.')
+        return
+    
+        % If so, inquire for a new name or to delete the existing file
+        %newname = input('Give a new name or input "delete" to replace: ', 's');
+
+        %if strcmpi(newname, 'delete')
+            %delete filename;
+        %else
+            %fprintf('New file name is %s\n', newname);
+            %filename = newname;
+        %end
+    else
+        % Otherwise create the file and define it globally so other functions can call it
+        
+        NetCDF = netcdf.create(filename, 'NETCDF4');
+        netcdf.putAtt(NetCDF, netcdf.getConstant('NC_GLOBAL'), 'history', ['Created ', datestr(now)]);
+        netcdf.defDim(NetCDF, 'Unlim', netcdf.getConstant('NC_UNLIMITED')); % unlimited dimension
+        netcdf.defDim(NetCDF, 'float', 1);     % single integer dimension
+        netcdf.defDim(NetCDF, 'int', 1);       % single float dimension
+
+        if verbose
+            fprintf('Successfully created %s\n', filename);
+        end
+
+        return 
+    end
+end
+
+
+%{
+    Since python uses subclass instances and MATLAB uses fields, we need to guess which subclass instance python will need
+    given the name of the sub-field in MATLAB. We make this guess based on the name of the MATLAB subfield that will contain
+    the name of the python subclass instance. For example, md.results.StressbalanceSolution is an subfield in MATLAB,
+    but a class instance of solution(). Notice that StressbalanceSolution contains the name "Solution" in it. This is what
+    we will save to the netCDF file for python to pick up.
+%}
+
+function results_subclasses_bandaid(model_var, NetCDF, verbose)
+    
+    % The results class may have nested fields within it, so we need to record the name of 
+    % the nested field as it appears in the model that we're trying to save
+    quality_control = {};
+    
+    % Access the results subclass of model_var
+    results_var = model_var.results;
+
+    % get the results group id so we can write to it
+    groupid = netcdf.inqNcid(NetCDF,'results');
+    
+    % Loop through each class instance in results
+    class_instance_names = fieldnames(results_var);
+
+    % we save lists of instances to the netcdf
+    solutions = {};
+    solutionsteps = {};
+    resultsdakotas = {};
+    
+    for i = 1:numel(class_instance_names)
+        class_instance_name = class_instance_names{i};
+        % there are often mutliple instances of the same class/struct so we have to number them
+        % Check to see if there is a solutionstep class instance
+        if contains(class_instance_name, 'solutionstep',IgnoreCase=true)
+            quality_control{end+1} = 1;
+            solutionsteps{end+1} = class_instance_name;
+            if verbose
+                disp('Successfully stored class python subclass instance: solutionstep')
+            end
+        end
+        
+        % Check to see if there is a solution class instance
+        if contains(class_instance_name, 'solution',IgnoreCase=true)
+            quality_control{end+1} = 1;
+            solutions{end+1} = class_instance_name;
+            if verbose
+                disp('Successfully stored class python subclass instance: solution')
+            end
+        end
+        
+        % Check to see if there is a resultsdakota class instance
+        if contains(class_instance_name, 'resultsdakota',IgnoreCase=true)
+            quality_control{end+1} = 1;
+            resultsdakotas{end+1} = class_instance_name;
+            if verbose
+                disp('Successfully stored class python subclass instance: resultsdakota')
+            end
+        end
+    end
+    if ~isempty(solutionsteps)
+        write_cell_with_strings('solutionstep', solutionsteps, groupid, NetCDF, verbose)
+    end
+    if ~isempty(solutions)
+        write_cell_with_strings('solution', solutions, groupid, NetCDF, verbose)
+    end
+    if ~isempty(resultsdakotas)
+        write_cell_with_strings('resultsdakota', resultsdakotas, groupid, NetCDF, verbose)
+    end
+    
+    
+
+    % Check if all class instances were processed correctly
+    if numel(quality_control) ~= numel(class_instance_names)
+        disp('Error: The class instance within your model.results class is not currently supported by this application');
+    else
+        if verbose
+            disp('The results class was successfully stored on disk');
+        end
+    end
+end
+
+
+
+function walk_through_model(model_var, empty_model, NetCDF, verbose)
+    % Iterate over first layer of model_var attributes and assume this first layer is only classes fundamental to the model() class
+    % note that groups are the same as class instances/subfields in this context
+    groups = fieldnames(model_var);
+    for group = 1:numel(groups)
+        % now this new variable takes the form model.mesh , model.damage etc.
+        model_subclass = model_var.(groups{group});
+        empty_model_subclass = empty_model.(groups{group});
+        % Now we can recursively walk through the remaining subclasses
+        list_of_layers = {groups{group}};
+        walk_through_subclasses(model_subclass, empty_model_subclass, list_of_layers, empty_model, NetCDF, verbose);
+    end
+end
+        
+
+function walk_through_subclasses(model_subclass, empty_model_subclass, given_list_of_layers, empty_model, NetCDF, verbose)
+    % Recursivley iterate over each subclass' attributes and look for more subclasses and variables with relevant data
+    % model_subclass is an object (ie, md.mesh.elements)
+    % list_of_layers is a cell array of subclasses/attributes/fields so that we can copy the structure into netcdf (ie, {'mesh', 'elements'})
+    % need to check if inversion or m1qn3inversion or taoinversion class
+    if numel(given_list_of_layers) == 1
+        if strcmp(given_list_of_layers{1}, 'inversion')
+            create_group(model_subclass, given_list_of_layers, NetCDF, verbose);
+            check_inversion_class(model_subclass, NetCDF, verbose);
+        end
+    end
+    
+    % Use try/except since model_subclass is either a subclass/struct w/ props/fields or it's not, no unknown exceptions
+    try 
+        % look for children - this is where the catch would be called
+        children = fieldnames(model_subclass);
+
+        % if there are children, loop through them and see if we need to save any data
+        for child = 1:numel(children)
+            % record our current location
+            list_of_layers = given_list_of_layers;
+            current_child = children{child};
+            list_of_layers{end+1} = current_child;
+        
+            % this is the value of the current location in the model (ie, md.mesh.elements)
+            location_of_child = model_subclass.(current_child);
+            
+            % if the empty model does not have this attribute, it's because it's new so we save it to netcdf
+            % there are 2 cases: the location is a struct, the location is a class
+            if isstruct(model_subclass)
+                % if the current field is a nested struct assume it has valuable data that needs to be saved
+                if isstruct(location_of_child) && any(size(location_of_child) > 1)
+                    create_group(location_of_child, list_of_layers, NetCDF, verbose);
+                
+                % this would mean that the layer above the layer we're interested in is a struct, so
+                % we can navigate our empty model as such
+                elseif isfield(empty_model_subclass, current_child)
+                    % the layer we're interested in does exist, we just need to compare states
+                    location_of_child_in_empty_model = empty_model_subclass.(current_child);
+
+                    % if the current attribute is a numerical array assume it has valuable data that needs to be saved
+                    if isnumeric(location_of_child) && logical(numel(location_of_child) > 1)
+                        create_group(location_of_child, list_of_layers, NetCDF, verbose);
+                    % if the attributes are identical we don't need to save anything
+                    elseif (all(isnan(location_of_child)) && all(isnan(location_of_child_in_empty_model))) || isempty(setxor(location_of_child, location_of_child_in_empty_model))
+                        walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, empty_model, NetCDF, verbose);
+                    % if the attributes are not the same we need to save ours
+                    else
+                        % THE ORDER OF THESE LINES IS CRITICAL
+                        walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, empty_model, NetCDF, verbose);
+                        create_group(location_of_child, list_of_layers, NetCDF, verbose);
+                    end
+                % this would mean that the layer we're interested in is not fundamental to the model architecture
+                % and thus needs to be saved to the netcdf
+                else
+                    walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, empty_model, NetCDF, verbose);
+                    create_group(location_of_child, list_of_layers, NetCDF, verbose);
+                end
+            % this would mean it's not a struct, and must be a class/subclass
+            % we now check the state of the class property
+            else 
+                try
+                    if isprop(empty_model_subclass, current_child)
+                        % the layer we're interested in does exist, we just need to compare states
+                        location_of_child_in_empty_model = empty_model_subclass.(current_child);
+                        % if the current attribute is a numerical array assume it has valuable data that needs to be saved
+                        if isnumeric(location_of_child) && logical(numel(location_of_child) > 1)
+                            create_group(location_of_child, list_of_layers, NetCDF, verbose);
+                        
+                        elseif iscell(location_of_child)
+                            % if the attributes are identical we don't need to save anything
+                            if isempty(setxor(location_of_child, location_of_child_in_empty_model))
+                                % pass
+                            else
+                            % otherwise we need to save
+                                walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, empty_model, NetCDF, verbose);
+                                create_group(location_of_child, list_of_layers, NetCDF, verbose);
+                            end
+                        elseif (all(isnan(location_of_child)) && all(isnan(location_of_child_in_empty_model)))
+                            walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, empty_model, NetCDF, verbose);
+                        % if the attributes are not the same we need to save ours
+                        else
+                            % THE ORDER OF THESE LINES IS CRITICAL
+                            walk_through_subclasses(location_of_child, location_of_child_in_empty_model, list_of_layers, empty_model, NetCDF, verbose);
+                            create_group(location_of_child, list_of_layers, NetCDF, verbose);
+                        end
+                    else
+                        walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, empty_model, NetCDF, verbose);
+                        create_group(location_of_child, list_of_layers, NetCDF, verbose);
+                    end
+                catch
+                    walk_through_subclasses(location_of_child, empty_model_subclass, list_of_layers, empty_model, NetCDF, verbose);
+                    create_group(location_of_child, list_of_layers, NetCDF, verbose);
+                end
+            end
+        end
+    catch ME
+        % If the caught error is a fieldname error, it's just saying that a variable has no fields and thus can be ignored
+        if strcmp(ME.identifier, 'MATLAB:fieldnames:InvalidInput')
+            % do nothing
+        % this is if we come accross instances/subfields in our model that are not fundamental to the model class (ie, taoinversion)
+        elseif strcmp(ME.identifier, 'MATLAB:UndefinedFunction')
+            walk_through_subclasses(location_of_child, empty_model_subclass, given_list_of_layers, empty_model, NetCDF, verbose);
+            create_group(location_of_child, list_of_layers, NetCDF, verbose);
+        % If it's a different error, rethrow it to MATLAB's default error handling
+        else
+            disp(ME.identifier)
+            disp(given_list_of_layers)
+            rethrow(ME);
+        end
+    end
+end 
+        
+
+function create_group(location_of_child, list_of_layers, NetCDF, verbose)
+    %disp(list_of_layers)
+    % location_of_child is an object
+    % list_of_layers is a list like {'inversion', 'StressbalanceSolution','cost_functions_coefficients'}
+    % first we make the group at the highest level (ie, inversion)
+    group_name = list_of_layers{1};
+    variable_name = list_of_layers{end};
+    
+    % if the group is already made, get it's ID instead of creating it again
+    try % group hasn't been made
+        group = netcdf.defGrp(NetCDF, group_name);
+    catch % group was already made
+        group = netcdf.inqNcid(NetCDF, group_name);    
+    end
+
+    % if the data is nested, create nested groups to match class structure
+    if numel(list_of_layers) > 2
+        % the string() method is really important here since matlab apparently can't handle the infinite complexity of a string without the string method.
+        for name = string(list_of_layers(2:end-1))
+            % the group levels may have already been made
+            try % group hasn't been made
+                group = netcdf.defGrp(group, name);
+            catch % group was already made
+                group = netcdf.inqNcid(group, name);
+            end
+        end
+    end
+    % sometimes objects are passed through twice so we account for that with this try/catch
+    try
+        % we may be dealing with an object
+        % first we screen for structs
+        if isstruct(location_of_child) % && any(size(location_of_child) > 1) -- this is being tested
+            % we have a struct
+            copy_nested_struct(variable_name, location_of_child, group, NetCDF, verbose);
+        
+        % now for cell arrays of datastructures:
+        elseif logical(~isstruct(location_of_child) && iscell(location_of_child) && isobject(location_of_child{1}))
+            copy_cell_array_of_objects(variable_name, location_of_child, group, NetCDF, verbose);
+        else
+            if ~isobject(location_of_child) && ~isstruct(location_of_child)
+                % we're dealing with raw data
+                create_var(variable_name, location_of_child, group, NetCDF, verbose);
+            end
+        end
+    catch
+        % do nothing
+    end
+end
+
+
+
+function copy_cell_array_of_objects(variable_name, address_of_child, group, NetCDF, verbose)
+    % make subgroup to represent the array
+    [rows, cols] = size(address_of_child);
+    name_of_subgroup = [num2str(rows), 'x', num2str(cols), '_cell_array_of_objects'];
+    subgroup = netcdf.defGrp(group, name_of_subgroup);
+
+    % save the name of the cell array
+    write_string_to_netcdf('name_of_cell_array', variable_name, subgroup, NetCDF, verbose);
+
+    % save the dimensions of the cell array
+    create_var('rows', rows, subgroup, NetCDF, verbose);
+    create_var('cols', cols, subgroup, NetCDF, verbose);
+
+    % if this is a multidimensional cell array, iterate over rows here and cols in copy_objects
+    if rows>1
+        for row = 1:rows
+            % make a subgroup for each row
+            name_of_subgroup = ['Row_', num2str(row), '_of_', num2str(rows)];
+            subgroup = netcdf.defGrp(group, name_of_subgroup);
+            copy_objects(address_of_child, subgroup, NetCDF, cols, verbose);
+        end
+    else
+        copy_objects(address_of_child, subgroup, NetCDF, cols, verbose);
+    end
+end
+
+
+
+function copy_objects(address_of_child, group, NetCDF, cols, verbose)
+    for col = 1:cols
+        % make subgroup to contain each col of array
+        name_of_subgroup = ['Col_', num2str(col), '_of_', num2str(cols)];
+        subgroup = netcdf.defGrp(group, name_of_subgroup);
+
+        % get the kind of object we're working with:
+        if isstruct(address_of_child{col})
+            % handle structs
+            name_raw = fields(address_of_child{col});
+            variable_name = name_raw{1};
+            copy_nested_struct(variable_name, address_of_child, subgroup, NetCDF, verbose);
+            
+        elseif numel(properties(address_of_child{col})) > 0
+            % handle class instances
+            copy_class_instance(address_of_child{col}, subgroup, NetCDF, verbose);
+        else
+            disp('ERROR: Cell arrays of mixed types are not yet supported in read_netCDF!\n Deserialization will not be able to complete!')
+            % handle regular datastructures that are already supported
+            name_raw = fields(address_of_child);
+            variable_name = name_raw{col};
+            create_var(variable_name, address_of_child, subgroup, NetCDF, verbose);
+        end
+    end
+end
+
+
+function copy_class_instance(address_of_child, subgroup, NetCDF, verbose)
+    % get parent class name
+    name = class(address_of_child);
+
+    % save the name of the class
+    write_string_to_netcdf('class_is_a', name, subgroup, NetCDF, verbose);
+    
+    % make subgroup to contain properties
+    name_of_subgroup = ['Properties_of_', name];
+    subgroup = netcdf.defGrp(subgroup, name_of_subgroup);
+
+    % get properties
+    props = properties(address_of_child);
+
+    for property = 1:length(props)
+        variable_name = props{property};
+        create_var(variable_name, address_of_child.(variable_name), subgroup, NetCDF, verbose);
+    end
+
+end
+
+
+function copy_nested_struct(parent_struct_name, address_of_struct, group, NetCDF, verbose)
+    %{
+        This function takes a struct of structs and saves them to netcdf. 
+
+        It also works with single structs.
+
+        To do this, we get the number of dimensions (substructs) of the parent struct.
+        Next, we iterate through each substruct and record the data. 
+        For each substruct, we create a subgroup of the main struct.
+        For each variable, we create dimensions that are assigned to each subgroup uniquely.
+    %}
+
+    % make a new subgroup to contain all the others:
+    group = netcdf.defGrp(group, parent_struct_name);
+    
+    % make sure other systems can flag the nested struct type
+    dimID = netcdf.defDim(group, 'struct', 6);
+    string_var = netcdf.defVar(group, 'this_is_a_nested', "NC_CHAR", dimID);
+    uint_method=uint8('struct').';
+    method_ID = char(uint_method);
+    netcdf.putVar(group, string_var, method_ID);
+
+    % other systems know the name of the parent struct because it's covered by the results/qmu functions above
+    
+    % 'a' will always be 1 and is not useful to us
+    [a, no_of_dims] = size(address_of_struct);
+
+    for substruct = 1:no_of_dims
+        % we start by making subgroups with nice names like "TransientSolution_substruct_44"
+        name_of_subgroup = ['1x', num2str(substruct)];
+        subgroup = netcdf.defGrp(group, name_of_subgroup);
+
+        % do some housekeeping to keep track of the current layer
+        current_substruct = address_of_struct(substruct);
+        substruct_fields = fieldnames(current_substruct)'; % transpose because matlab only interates over n x 1 arrays
+        
+        % now we need to iterate over each variable of the nested struct and save it to this new subgroup
+        for variable_name = string(substruct_fields)
+            address_of_child = current_substruct.(variable_name);
+            create_var(variable_name, address_of_child, subgroup, NetCDF, verbose);
+        end
+    end
+    if verbose
+        fprintf(["Succesfully transferred nested MATLAB struct ",  parent_struct_name, " to the NetCDF\n"])
+    end
+end
+
+
+
+% ironically inversion does not have the same problem as results as inversion subfields
+% are actually subclasses and not fields
+function check_inversion_class(model_var, NetCDF, verbose)
+    
+    % Define a persistent variable to ensure this function is only run once
+    persistent executed;
+    % Check if the function has already been executed
+    if isempty(executed)
+        if verbose
+            disp('Deconstructing Inversion class instance')
+        end
+        % Need to make sure that we have the right inversion class: inversion, m1qn3inversion, taoinversion
+        groupid = netcdf.inqNcid(NetCDF,'inversion');
+
+        if isa(model_var, 'm1qn3inversion')
+            write_string_to_netcdf('inversion_class_name', 'm1qn3inversion', groupid, NetCDF, verbose);
+            if verbose
+                disp('Successfully saved inversion class instance m1qn3inversion')
+            end
+        elseif isa(model_var, 'taoinversion')
+            write_string_to_netcdf('inversion_class_name', 'taoinversion', groupid, NetCDF, verbose);
+            if verbose 
+                disp('Successfully saved inversion class instance taoinversion')
+            end
+        else
+            write_string_to_netcdf('inversion_class_name', 'inversion', groupid, NetCDF,  verbose);
+            if verbose
+                disp('Successfully saved inversion class instance inversion')
+            end
+        end
+        % Set the persistent variable to indicate that the function has been executed
+        executed = true;
+    end
+end
+
+
+function create_var(variable_name, address_of_child, group, NetCDF, verbose)
+    % There are lots of different variable types that we need to handle from the model class
+    
+    % get the dimensions we'll need
+    intdim = netcdf.inqDimID(NetCDF,'int');
+    floatdim = netcdf.inqDimID(NetCDF,'float');
+    unlimdim = netcdf.inqDimID(NetCDF,'Unlim');
+    
+    % This first conditional statement will catch numeric arrays (matrices) of any dimension and save them
+    if any(size(address_of_child)>1) && ~iscellstr(address_of_child) && ~ischar(address_of_child)
+        write_numeric_array_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose);
+
+    % check if it's a string
+    elseif ischar(address_of_child)
+        write_string_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose);
+
+    % or an empty variable
+    elseif isempty(address_of_child)
+        variable = netcdf.defVar(group, variable_name, "NC_DOUBLE", intdim);
+
+    % or a list of strings
+    elseif iscellstr(address_of_child) || iscell(address_of_child) && ischar(address_of_child{1})
+        write_cell_with_strings(variable_name, address_of_child, group, NetCDF, verbose)
+        
+    % or an empty list
+    elseif iscell(address_of_child) && isempty(address_of_child) || isa(address_of_child, 'double') && isempty(address_of_child)
+        variable = netcdf.defVar(group, variable_name, "NC_INT", intdim);
+        netcdf.putVar(group,variable, -32767);
+
+    % or a bool
+    elseif islogical(address_of_child)
+        % netcdf4 can't handle bool types like true/false so we convert all to int 1/0 and add an attribute named units with value 'bool'
+        variable = netcdf.defVar(group, variable_name, 'NC_SHORT', intdim);
+        netcdf.putVar(group,variable,int8(address_of_child));
+        % make sure other systems can flag the bool type
+        netcdf.putAtt(group,variable,'units','bool');
+
+    % or a regular list
+    elseif iscell(address_of_child)
+        disp('made list w/ unlim dim')
+        variable = netcdf.defVar(group, variable_name, "NC_DOUBLE", unlimdim);
+        netcdf.putVar(group,variable,address_of_child);
+        
+    % or a float
+    elseif isfloat(address_of_child) && numel(address_of_child) == 1
+        variable = netcdf.defVar(group, variable_name, "NC_DOUBLE", floatdim);
+        netcdf.putVar(group,variable,address_of_child);
+        
+    % or a int
+    elseif mod(address_of_child,1) == 0 || isinteger(address_of_child) && numel(address_of_child) == 1
+        variable = netcdf.defVar(group, variable_name, "NC_SHORT", intdim);
+        netcdf.putVar(group,variable,address_of_child);
+
+    % anything else... (will likely need to add more cases; ie dict)
+    else
+        try
+            variable = netcdf.defVar(group, variable_name, "NC_DOUBLE", unlimdim);
+            netcdf.putVar(group,variable,address_of_child);
+        catch ME
+            disp(ME.message);
+            disp(['Datatype given: ', class(address_of_child)]);
+        end
+    end
+    if verbose
+        fprintf('Successfully transferred data from %s to the NetCDF\n', variable_name);
+    end
+end
+
+
+function write_cell_with_strings(variable_name, address_of_child, group, NetCDF, verbose)
+    %{
+    Write cell array (ie {'one' 'two' 'three'}) to netcdf
+    %}
+    
+    if isempty(address_of_child)
+        % if the char array is empty, save an empty char
+        name_of_dimension = ['char', num2str(0)];
+        try
+            dimID = netcdf.defDim(group, name_of_dimension, 0);
+        catch
+            dimID = netcdf.inqDimID(group, name_of_dimension);
+        end
+        % Now we can make a variable in this dimension:
+        string_var = netcdf.defVar(group, variable_name, "NC_CHAR", [dimID]);
+        % we leave empty now
+    else
+        % covert data to char array
+        method_ID = char(address_of_child);
+    
+        % make dimensions
+        [rows, cols] = size(method_ID);
+        
+        IDDim1 = netcdf.defDim(group,'cols',cols);
+        IDDim2 = netcdf.defDim(group,'rows',rows);
+    
+        % create the variable slot
+        IDVarId = netcdf.defVar(group,variable_name,'NC_CHAR', [IDDim1 IDDim2]);
+    
+        % save the variable
+        netcdf.putVar(group, IDVarId, method_ID'); %transpose
+    
+        % tell other platforms that this is a cell of strings
+        netcdf.putAtt(group, IDVarId, 'type_is','cell_array_of_strings');
+    end
+end
+
+
+function write_string_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose)
+    % netcdf and strings don't get along.. we have to do it 'custom':
+
+    the_string_to_save = address_of_child;
+
+    if isempty(the_string_to_save)
+        % if the char array is empty, save an empty char
+        name_of_dimension = ['char', num2str(0)];
+        try
+            dimID = netcdf.defDim(group, name_of_dimension, 0);
+        catch
+            dimID = netcdf.inqDimID(group, name_of_dimension);
+        end
+        % Now we can make a variable in this dimension:
+        string_var = netcdf.defVar(group, variable_name, "NC_CHAR", [dimID]);
+        % we leave empty now
+    else
+        % convert string to 
+        uint_method=uint8(the_string_to_save).';
+        method_ID = char(uint_method);
+        length_of_the_string = numel(method_ID);
+        
+        % Convert the string to character data using string array
+        %str_out = char(the_string_to_save)
+    
+        % Determine the length of the string
+        %length_of_the_string = numel(str_out)
+    
+        % Check if the dimension already exists, and if not, create it
+        name_of_dimension = ['char', num2str(length_of_the_string)];
+        try
+            dimID = netcdf.defDim(group, name_of_dimension, length_of_the_string);
+        catch
+            dimID = netcdf.inqDimID(group, name_of_dimension);
+        end
+        % Now we can make a variable in this dimension:
+        string_var = netcdf.defVar(group, variable_name, "NC_CHAR", [dimID]);
+        % Finally, we can write the variable (always transpose for matlab):
+        netcdf.putVar(group, string_var, method_ID);
+    end
+
+    if verbose
+        disp(['Successfully transferred data from ', variable_name, ' to the NetCDF']);
+    end
+end
+
+
+function write_numeric_array_to_netcdf(variable_name, address_of_child, group, NetCDF, verbose)
+
+    % get the dimensions we'll need
+    intdim = netcdf.inqDimID(NetCDF,'int');
+    floatdim = netcdf.inqDimID(NetCDF,'float');
+    unlimdim = netcdf.inqDimID(NetCDF,'Unlim');
+    
+    typeis = class(address_of_child);
+    
+    if isa(typeis, 'logical')
+            % because matlab transposes all data into and out of netcdf and because we want cross-platform-compat
+            % we need to transpose data before it goes into netcdf
+            data = address_of_child.';
+
+            % make the dimensions
+            dimensions = [];
+            for dimension = size(data)
+                dim_name = ['dim',int2str(dimension)];
+                % if the dimension already exists we can't have a duplicate
+                try
+                    dimID = netcdf.defDim(group, dim_name, dimension);
+                catch
+                    dimID = netcdf.inqDimID(group, dim_name);
+                end
+                % record the dimension for the variable
+                dimensions(end+1) = dimID;
+            end
+    
+            % write the variable
+            netcdf.putVar(group,variable,data);
+
+            % make sure other systems can flag the bool type
+            netcdf.putAtt(group,variable,'units','bool');
+            
+    % handle all other datatypes here
+    else
+        % sometimes an array has just 1 element in it, we account for those cases here:
+        if numel(address_of_child) == 1
+            if isinteger(address_of_child)
+                variable = netcdf.defVar(group, variable_name, "NC_SHORT", intdim);
+                netcdf.putVar(group,variable,address_of_child);
+            elseif isa(address_of_child, 'double') || isa(address_of_child, 'float')
+                variable = netcdf.defVar(group, variable_name, "NC_DOUBLE", floatdim);
+                netcdf.putVar(group,variable,address_of_child);
+            else 
+                disp('Encountered single datatype that was not float64 or int64, saving under unlimited dimension, may cause errors.')
+                variable = netcdf.defVar(group, variable_name, "NC_DOUBLE", unlimdim);
+                netcdf.putVar(group,variable,address_of_child);
+            end
+        % this is in case of lists so that python doesn't get a (nx1) numpy array and instead gets an n-element list
+        elseif any(size(address_of_child)==1)
+            % because matlab transposes all data into and out of netcdf and because we want cross-platform-compat
+            % we need to transpose data before it goes into netcdf
+            data = address_of_child.';
+
+            % make the dimensions
+            dimensions = [];
+            for dimension = size(data)
+                if dimension ~= 1
+                    dim_name = ['dim',int2str(dimension)];
+                    % if the dimension already exists we can't have a duplicate
+                    try
+                        dimID = netcdf.defDim(group, dim_name, dimension);
+                    catch
+                        dimID = netcdf.inqDimID(group, dim_name);
+                    end
+                    % record the dimension for the variable
+                    dimensions(end+1) = dimID;
+                end
+            end
+            % create the variable
+            variable = netcdf.defVar(group, variable_name, "NC_DOUBLE",dimensions);
+    
+            % write the variable
+            netcdf.putVar(group,variable,data);
+
+        % This catches all remaining arrays:
+        else
+            % because matlab transposes all data into and out of netcdf and because we want cross-platform-compat
+            % we need to transpose data before it goes into netcdf
+            data = address_of_child.';
+
+            % make the dimensions
+            dimensions = [];
+            for dimension = size(data)
+                dim_name = ['dim',int2str(dimension)];
+                % if the dimension already exists we can't have a duplicate
+                try
+                    dimID = netcdf.defDim(group, dim_name, dimension);
+                catch
+                    dimID = netcdf.inqDimID(group, dim_name);
+                end
+                % record the dimension for the variable
+                dimensions(end+1) = dimID;
+            end
+            % create the variable
+            variable = netcdf.defVar(group, variable_name, "NC_DOUBLE",dimensions);
+    
+            % write the variable
+            netcdf.putVar(group,variable,data);
+        end
+    end
+end
Index: /issm/trunk-jpl/src/m/contrib/musselman/write_netCDF.py
===================================================================
--- /issm/trunk-jpl/src/m/contrib/musselman/write_netCDF.py	(revision 28012)
+++ /issm/trunk-jpl/src/m/contrib/musselman/write_netCDF.py	(revision 28012)
@@ -0,0 +1,595 @@
+# imports
+import netCDF4
+from netCDF4 import Dataset
+import numpy as np
+import numpy.ma as ma
+import time
+import os
+from model import *
+from results import *
+from m1qn3inversion import m1qn3inversion
+from taoinversion import taoinversion
+#import OrderedStruct
+
+
+'''
+Given a md, this set of functions will perform the following:
+    1. View each attribute of each nested class.
+    2. Compare state of attribute in the model to an empty model.
+    3. If states are identical, pass. (except for np arrays which will always be saved)
+    4. Otherwise, create nested groups named after class structure.
+    5. Create variable named after class attribute and assign value to it.
+'''
+
+
+def write_netCDF(md, filename: str, verbose = False):
+    if verbose:
+        print('Python C2NetCDF4 v1.2.0')
+    else: pass
+    '''
+    md = model class instance to be saved
+    filename = path and name to save file under
+    verbose = T/F = show or muted log statements. Naturally muted
+    '''
+    # this is a precaution so that data is not lost
+    try:
+        # Create a NCData file to write to
+        NCData = create_NetCDF(filename, verbose)
+        
+        # Create an instance of an empty md class to compare md_var against
+        empty_model = model()
+    
+        # Walk through the md class and compare subclass states to empty_model
+        walk_through_model(md, empty_model, NCData, verbose)
+    
+        # in order to handle some subclasses in the results class, we have to utilize this band-aid
+        # there will likely be more band-aids added unless a class name library is created with all class names that might be added to a md
+        try:
+            # if results has meaningful data, save the name of the subclass and class instance
+            NCData.groups['results']
+            results_subclasses_bandaid(md, NCData, verbose)
+            # otherwise, ignore
+        except KeyError:
+            pass
+            
+        NCData.close()
+        if verbose:
+            print('Model successfully saved as NetCDF4')
+        else: pass
+
+    # just in case something unexpected happens
+    except Exception as e:
+        if 'NCData' in locals():
+            NCData.close()
+        raise e
+    
+
+def results_subclasses_bandaid(md, NCData, verbose = False):
+    # since the results class may have nested classes within it, we need to record the name of the 
+    # nested class instance variable as it appears in the md that we're trying to save
+    quality_control = []
+
+    # we save lists of instances to the NCData
+    solutions = []
+    solutionsteps = []
+    resultsdakotas = []
+    
+    for class_instance_name in md.results.__dict__.keys():
+        if verbose:
+            print(class_instance_name)
+        # for each class instance in results, see which class its from and record that info in the NCData to recreate structure later
+        # check to see if there is a solutionstep class instance
+        if isinstance(md.results.__dict__[class_instance_name],solutionstep):
+            quality_control.append(1)
+            solutionsteps.append(class_instance_name)
+
+        # check to see if there is a solution class instance
+        if isinstance(md.results.__dict__[class_instance_name],solution):
+            quality_control.append(1)
+            solutions.append(class_instance_name)
+
+        # check to see if there is a resultsdakota class instance
+        if isinstance(md.results.__dict__[class_instance_name],resultsdakota):
+            quality_control.append(1)
+            resultsdakotas.append(class_instance_name)
+
+    if solutionsteps != []:
+        serialize_string(variable_name=str('solutionstep'), address_of_child=solutionsteps, group=NCData.groups['results'], list=True, NCData=NCData, verbose=verbose)
+
+    if solutions != []:
+        serialize_string(variable_name=str('solution'), address_of_child=solutions, group=NCData.groups['results'], list=True, NCData=NCData, verbose=verbose)
+
+    if resultsdakotas != []:
+        serialize_string(variable_name=str('resultsdakota'), address_of_child=resultsdakotas, group=NCData.groups['results'], list=True, NCData=NCData, verbose=verbose)
+
+    
+    if len(quality_control) != len(md.results.__dict__.keys()):
+        print('Error: The class instance within your md.results class is not currently supported by this application')
+        print(type(md.results.__dict__[class_instance_name]))
+    else:
+        if verbose:
+            print('The results class was successfully stored on disk')
+        else: pass
+
+
+def create_NetCDF(filename: str, verbose = False):
+    # If file already exists delete / rename it
+    if os.path.exists(filename):
+        print('File {} allready exist'.format(filename))
+    
+        # If so, inqure for a new name or to do delete the existing file
+        newname = input('Give a new name or "delete" to replace: ')
+
+        if newname == 'delete':
+            os.remove(filename)
+        else:
+            print(('New file name is {}'.format(newname)))
+            filename = newname
+    else:
+        # Otherwise create the file and define it globally so other functions can call it
+        NCData = Dataset(filename, 'w', format='NETCDF4')
+        NCData.history = 'Created ' + time.ctime(time.time())
+        NCData.createDimension('Unlim', None)  # unlimited dimension
+        NCData.createDimension('float', 1)     # single integer dimension
+        NCData.createDimension('int', 1)       # single float dimension
+    
+    if verbose:
+        print('Successfully created ' + filename)
+
+    return NCData
+
+
+def walk_through_model(md, empty_model, NCData, verbose= False):
+    # Iterate over first layer of md attributes and assume this first layer is only classes
+    for group in md.__dict__.keys():
+        address = md.__dict__[group]
+        empty_address = empty_model.__dict__[group]
+        # we need to record the layers of the md so we can save them to the NCData file
+        layers = [group]
+
+        # Recursively walk through subclasses
+        walk_through_subclasses(address, empty_address, layers, NCData, empty_model, verbose)       
+
+
+def walk_through_subclasses(address, empty_address, layers: list, NCData, empty_model, verbose = False):
+    # See if we have an object with keys or a not
+    try:
+        address.__dict__.keys()
+        is_object = True
+    except: is_object = False # this is not an object with keys
+
+    if is_object:
+        # enter the subclass, see if it has nested classes and/or attributes
+        # then compare attributes between mds and write to NCData if they differ
+        # if subclass found, walk through it and repeat
+        for child in address.__dict__.keys():
+            # record the current location
+            current_layer = layers.copy()
+            current_layer.append(child)
+            
+            # navigate to child in each md
+            address_of_child = address.__dict__[child]
+            
+            # if the current object is a results.<solution> object and has nonzero steps attr it needs special treatment
+            if isinstance(address_of_child, solution) and len(address_of_child.steps) != 0:
+                create_group(address_of_child, current_layer, is_struct = True, is_special_list = False,  NCData=NCData, verbose = verbose)
+
+            # if the current object is a list of objects (currently only filters for lists/arrays of classes)
+            elif isinstance(address_of_child, list) and len(address_of_child) > 0 and hasattr(address_of_child[0], '__dict__'):
+                create_group(address_of_child, current_layer, is_struct = False, is_special_list = True, NCData=NCData, verbose = verbose)
+
+            # if the variable is an array, assume it has relevant data (this is because the next line cannot evaluate "==" with an array)
+            elif isinstance(address_of_child, np.ndarray):
+                create_group(address_of_child, current_layer, is_struct = False, is_special_list = False,  NCData=NCData, verbose = verbose)
+            
+            # see if the child exists in the empty md. If not, record it in the NCData
+            else:
+                try: 
+                    address_of_child_in_empty_class = empty_address.__dict__[child]
+                    # if that line worked, we can see how the mds' attributes at this layer compare:
+    
+                    # if the attributes are identical we don't need to save anything
+                    if address_of_child == address_of_child_in_empty_class:
+                        walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer, NCData, empty_model, verbose)
+    
+                    # If it has been modified, record it in the NCData file
+                    else:
+                        create_group(address_of_child, current_layer, is_struct = False, is_special_list = False,  NCData=NCData, verbose = verbose)
+                        walk_through_subclasses(address_of_child, address_of_child_in_empty_class, current_layer, NCData, empty_model, verbose)
+    
+                except KeyError: # record in NCData and continue to walk thru md
+                    walk_through_subclasses(address_of_child, empty_address, current_layer, NCData, empty_model, verbose)
+                    create_group(address_of_child, current_layer, is_struct = False, is_special_list = False,  NCData=NCData, verbose = verbose)
+    else: pass
+
+
+def create_group(address_of_child, layers, is_struct = False, is_special_list = False,  NCData=None, verbose = False):
+
+    # Handle the first layer of the group(s)
+    group_name = layers[0]
+    
+    # try to make a group unless the group is already made
+    try:
+        group = NCData.createGroup(str(group_name))
+    except:
+        group = NCData.groups[str(group_name)]
+
+    # need to check if inversion or m1qn3inversion class
+    if group_name == 'inversion':
+        check_inversion_class(address_of_child, NCData, verbose)
+    else: pass
+
+    # if the data is nested in md, create nested groups to match class structure
+    if len(layers) > 2:
+        for name in layers[1:-1]:
+            try:
+                group = group.createGroup(str(name))
+            except:
+                group = NCData.groups[str(name)]
+    else: pass
+
+    # Lastly, handle the variable(s)
+    if is_struct:
+        parent_struct_name = layers[-1]
+        serialize_nested_results_struct(parent_struct_name, address_of_child, group, NCData, verbose)
+
+    elif is_special_list:
+        list_name = layers[-1]
+        serialize_array_of_objects(list_name, address_of_child, group, NCData, verbose)
+    
+    else:
+        variable_name = layers[-1]
+        serialize_var(variable_name, address_of_child, group, NCData, verbose)
+            
+
+def singleton(func):
+    """
+    A decorator to ensure a function is only executed once.
+    """
+    def wrapper(*args, **kwargs):
+        if not wrapper.has_run:
+            wrapper.result = func(*args, **kwargs)
+            wrapper.has_run = True
+        return wrapper.result
+    wrapper.has_run = False
+    wrapper.result = None
+    return wrapper
+    
+
+@singleton
+def check_inversion_class(address_of_child, NCData, verbose = False):
+    # need to make sure that we have the right inversion class: inversion, m1qn3inversion, taoinversion
+    if isinstance(address_of_child, m1qn3inversion):
+        serialize_string(variable_name=str('inversion_class_name'), address_of_child=str('m1qn3inversion'), group=NCData.groups['inversion'], NCData=NCData, verbose = verbose)
+        if verbose:
+            print('Successfully saved inversion class instance ' + 'm1qn3inversion')
+    elif isinstance(address_of_child, taoinversion):
+        serialize_string(variable_name=str('inversion_class_name'), address_of_child=str('taoinversion'), group=NCData.groups['inversion'], NCData=NCData, verbose = verbose)
+        if verbose:
+            print('Successfully saved inversion class instance ' + 'taoinversion')
+    else:
+        serialize_string(variable_name=str('inversion_class_name'), address_of_child=str('inversion'), group=NCData.groups['inversion'], NCData=NCData, verbose = verbose)
+        if verbose:
+            print('Successfully saved inversion class instance ' + 'inversion')
+
+
+def serialize_nested_results_struct(parent_struct_name, address_of_struct, group, NCData, verbose = False):
+    '''
+        This function takes a results.solution class instance and saves the solutionstep instances from <solution>.steps to the NCData. 
+
+        To do this, we get the number of dimensions (substructs) of the parent struct (list).
+        Next, we iterate through each substruct and record the data. 
+        For each substruct, we create a subgroup of the main struct.
+        For each variable, we create dimensions that are assigned to each subgroup uniquely.
+    '''
+    if verbose:
+        print("Beginning transfer of nested MATLAB struct to the NCData")
+    
+    # make a new subgroup to contain all the others:
+    group = group.createGroup(str(parent_struct_name))
+
+    # make sure other systems can flag the nested struct type
+    serialize_string('this_is_a_nested', 'struct', group, list=False, NCData=NCData, verbose = verbose)
+
+    # other systems know the name of the parent struct because it's covered by the results/qmu functions above
+    no_of_dims = len(address_of_struct)
+    for substruct in range(0, no_of_dims):
+        # we start by making subgroups with nice names like "1x4"
+        name_of_subgroup = '1x' + str(substruct)
+        subgroup = group.createGroup(str(name_of_subgroup))
+
+        # do some housekeeping to keep track of the current layer
+        current_substruct = address_of_struct[substruct]
+        substruct_fields = current_substruct.__dict__.keys()
+
+        # now we need to iterate over each variable of the nested struct and save it to this new subgroup
+        for variable in substruct_fields:
+            address_of_child = current_substruct.__dict__[variable]
+            serialize_var(variable, address_of_child, subgroup, NCData, verbose = verbose)
+    
+    if verbose:
+        print(f'Successfully transferred struct {parent_struct_name} to the NCData\n')
+
+
+
+
+def serialize_array_of_objects(list_name, address_of_child, group, NCData, verbose):
+    if verbose: 
+        print(f"Serializing array of objects.")
+    
+    # Get the dimensions of the cell array
+    if len(np.shape(address_of_child)) > 1: 
+        rows, cols = np.shape(address_of_child)
+    else: rows, cols = 1, np.shape(address_of_child)[0]
+
+    # Make subgroup to represent the array
+    name_of_subgroup = f"{str(rows)}x{str(cols)}_cell_array_of_objects"
+    subgroup = group.createGroup(name_of_subgroup)
+
+    # Save the name of the cell array
+    serialize_string('name_of_cell_array', list_name, subgroup, NCData, verbose)
+
+    # Save the dimensions of the cell array
+    rowsID = subgroup.createVariable('rows', int, ('int',))
+    colsID = subgroup.createVariable('cols', int, ('int',))
+    rowsID[:] = rows
+    colsID[:] = cols
+
+
+    # If this is a multidimensional cell array, iterate over rows here and cols in serialize_objects
+    if rows > 1:
+        for row in range(rows):
+            # Make a subgroup for each row
+            name_of_subgroup = f"Row_{row+1}_of_{rows}"
+            subgroup = group.createGroup(name_of_subgroup)
+            serialize_objects(address_of_child, subgroup, NCData, cols, verbose)
+    else:
+        serialize_objects(address_of_child, subgroup, NCData, cols, verbose)
+        
+    if verbose:
+        print(f"Successfully serialized array of objects: {list_name}")
+
+
+def serialize_objects(address_of_child, group, NCData, cols, verbose):
+    for col in range(cols):
+        # Make subgroup to contain each col of array
+        name_of_subgroup = f'Col_{col+1}_of_{cols}'
+        subgroup = group.createGroup(name_of_subgroup)
+
+        # index the current item
+        variable = address_of_child[col]
+
+        # Get the kind of object we're working with:
+        # see if it's a solution instance
+        if isinstance(variable, solution) and len(variable.steps) != 0:
+            pass
+            # this needs more work...
+        
+        # see if it's a general class -- assume ISSM classes all have __dict__
+        elif hasattr(variable, '__dict__'):
+            # Handle class instances
+            serialize_class_instance(variable, subgroup, NCData, verbose)
+        else:
+            print('ERROR: Cell arrays of mixed types are not yet supported in read_NCData!')
+            print('Deserialization will not be able to complete!')
+            # Handle regular data structures that are already supported
+            serialize_var(variable_name, variable, subgroup, NCData, verbose)
+
+
+def serialize_class_instance(instance, group, NCData, verbose):
+    # get parent class name:
+    name = instance.__class__.__name__
+
+    # save the name of the class
+    serialize_string(variable_name='class_is_a', address_of_child=name, group=group, NCData=NCData, verbose = verbose)
+
+    # make subgroup to contain attributes
+    name_of_subgroup = 'Properties_of_' + name
+    subgroup = group.createGroup(name_of_subgroup)
+
+    # get attributes
+    keys = instance.__dict__.keys()
+
+    for name in keys:
+        serialize_var(name, instance.__dict__[name], subgroup, NCData, verbose)
+    
+
+
+        
+def serialize_var(variable_name, address_of_child, group, NCData, verbose = False):
+    # There are lots of different variable types that we need to handle from the md class
+    
+    # This first conditional statement will catch numpy arrays of any dimension and save them
+    if isinstance(address_of_child, np.ndarray):
+        serialize_numpy_array(variable_name, address_of_child, group, NCData, verbose=verbose)
+    
+    # check if it's an int
+    elif isinstance(address_of_child, int) or isinstance(address_of_child, np.integer):
+        variable = group.createVariable(variable_name, int, ('int',))
+        variable[:] = address_of_child
+    
+    # or a float
+    elif isinstance(address_of_child, float) or isinstance(address_of_child, np.floating):
+        variable = group.createVariable(variable_name, float, ('float',))
+        variable[:] = address_of_child
+
+    # or a string
+    elif isinstance(address_of_child, str):
+        serialize_string(variable_name, address_of_child, group, NCData, verbose=verbose)
+
+    #or a bool
+    elif isinstance(address_of_child, bool) or isinstance(address_of_child, np.bool_):
+        # NetCDF can't handle bool types like True/False so we convert all to int 1/0 and add an attribute named units with value 'bool'
+        variable = group.createVariable(variable_name, int, ('int',))
+        variable[:] = int(address_of_child)
+        variable.units = "bool"
+        
+    # or an empty list
+    elif isinstance(address_of_child, list) and len(address_of_child)==0:
+        variable = group.createVariable(variable_name, int, ('int',))
+
+    # or a list of strings -- this needs work as it can only handle a list of 1 string
+    elif isinstance(address_of_child,list) and isinstance(address_of_child[0],str):
+        for string in address_of_child:
+            serialize_string(variable_name, string, group, list=True, NCData=NCData, verbose=verbose)
+
+    # or a regular list
+    elif isinstance(address_of_child, list):
+        variable = group.createVariable(variable_name, type(address_of_child[0]), ('Unlim',))
+        variable[:] = address_of_child
+
+    # anything else... (will likely need to add more cases; ie helpers.OrderedStruct)
+    else:
+        try:
+            variable = group.createVariable(variable_name, type(address_of_child), ('Unlim',))
+            variable[:] = address_of_child
+            print(f'Unrecognized variable was saved {variable_name}')
+        except TypeError: pass # this would mean that we have an object, so we just let this continue to feed thru the recursive function above
+        except Exception as e:
+            print(f'There was error with {variable_name} in {group}')
+            print("The error message is:")
+            print(e)
+            print('Datatype given: ' + str(type(address_of_child)))
+    
+    if verbose:
+        print(f'Successfully transferred data from {variable_name} to the NCData')
+    
+
+def serialize_string(variable_name, address_of_child, group, list=False, NCData=None, verbose = False):
+    # NCData and strings dont get along.. we have to do it 'custom':
+    # if we hand it an address we need to do it this way:
+    if list:
+        """    
+        Convert a list of strings to a numpy.char_array with utf-8 encoded elements
+        and size rows x cols with each row the same # of cols and save to NCData
+        as char array.
+        """
+        try:
+            strings = address_of_child
+            # get dims of array to save
+            rows = len(strings)
+            cols = len(max(strings, key = len))
+    
+            # Define dimensions for the strings
+            rows_name = 'rows' + str(rows)
+            cols_name = 'cols' + str(cols)
+            try:
+                group.createDimension(rows_name, rows)
+            except: pass
+
+            try:
+                group.createDimension(cols_name, cols)
+            except: pass
+                
+            # Create a variable to store the strings
+            string_var = group.createVariable(str(variable_name), 'S1', (rows_name, cols_name))
+    
+            # break the list into a list of lists of words with the same length as the longest word:
+            # make words same sizes by adding spaces 
+            modded_strings = [word + ' ' * (len(max(strings, key=len)) - len(word)) for word in strings]
+            # encoded words into list of encoded lists
+            new_list = [[s.encode('utf-8') for s in word] for word in modded_strings]
+    
+            # make numpy char array with dims rows x cols
+            arr = np.chararray((rows, cols))
+    
+            # fill array with list of encoded lists
+            for i in range(len(new_list)):
+                arr[i] = new_list[i]
+    
+            # save array to NCData file
+            string_var[:] = arr
+
+            if verbose:
+                print(f'Saved {len(modded_strings)} strings to {variable_name}')
+    
+        except Exception as e:
+            print(f'Error: {e}')
+        
+    else:
+        the_string_to_save = address_of_child
+        length_of_the_string = len(the_string_to_save)
+        numpy_datatype = 'S' + str(length_of_the_string)
+        str_out = netCDF4.stringtochar(np.array([the_string_to_save], dtype=numpy_datatype))        
+    
+        # we'll need to make a new dimension for the string if it doesn't already exist
+        name_of_dimension = 'char' + str(length_of_the_string)
+        try: 
+            group.createDimension(name_of_dimension, length_of_the_string)
+        except: pass
+        # this is another band-aid to the results sub classes...
+        try:
+            # now we can make a variable in this dimension:
+            string = group.createVariable(variable_name, 'S1', (name_of_dimension))
+            #finally we can write the variable:
+            string[:] = str_out
+        #except RuntimeError: pass
+        except Exception as e:
+            print(f'There was an error saving a string from {variable_name}')
+            print(e)
+
+
+def serialize_numpy_array(variable_name, address_of_child, group, NCData, verbose = False):
+    # to make a nested array in NCData, we have to get the dimensions of the array,
+    # create corresponding dimensions in the NCData file, then we can make a variable
+    # in the NCData with dimensions identical to those in the original array
+    
+    # start by getting the data type at the lowest level in the array:
+    typeis = address_of_child.dtype
+
+    # catch boolean arrays here
+    if typeis == bool:
+        # sometimes an array has just 1 element in it, we account for those cases here:
+        if len(address_of_child) == 1:
+            variable = group.createVariable(variable_name, int, ('int',))
+            variable[:] = int(address_of_child)
+            variable.units = "bool"
+        else:
+            # make the dimensions
+            dimensions = []
+            for dimension in np.shape(address_of_child):
+                dimensions.append(str('dim' + str(dimension)))
+                # if the dimension already exists we can't have a duplicate
+                try:
+                    group.createDimension(str('dim' + str(dimension)), dimension)
+                except: pass # this would mean that the dimension already exists
+    
+            # create the variable:
+            variable = group.createVariable(variable_name, int, tuple(dimensions))
+            # write the variable:
+            variable[:] = address_of_child.astype(int)
+            variable.units = "bool"
+
+    # handle all other datatypes here
+    else:
+        # sometimes an array has just 1 element in it, we account for those cases here:
+        if len(address_of_child) == 1:
+            if typeis is np.dtype('float64'):
+                variable = group.createVariable(variable_name, typeis, ('float',))
+                variable[:] = address_of_child[0]
+            elif typeis is np.dtype('int64'):
+                variable = group.createVariable(variable_name, typeis, ('int',))
+                variable[:] = address_of_child[0]
+            else:
+                print(f'Encountered single datatype from {variable_name} that was not float64 or int64, saving under unlimited dimension, may cause errors.')
+                variable = group.createVariable(variable_name, typeis, ('Unlim',))
+                variable[:] = address_of_child[0]
+    
+        # This catches all arrays/lists:
+        else:
+            # make the dimensions
+            dimensions = []
+            for dimension in np.shape(address_of_child):
+                dimensions.append(str('dim' + str(dimension)))
+                # if the dimension already exists we can't have a duplicate
+                try:
+                    group.createDimension(str('dim' + str(dimension)), dimension)
+                except: pass # this would mean that the dimension already exists
+    
+            # create the variable:
+            variable = group.createVariable(variable_name, typeis, tuple(dimensions))
+    
+            # write the variable:
+            variable[:] = address_of_child
+
+            
Index: /issm/trunk-jpl/src/m/solve/createMCC.m
===================================================================
--- /issm/trunk-jpl/src/m/solve/createMCC.m	(revision 28012)
+++ /issm/trunk-jpl/src/m/solve/createMCC.m	(revision 28012)
@@ -0,0 +1,51 @@
+function createMCC(filename)
+%CREATEMCC takes an existing matlab script and compiles it to an executable file.
+% A number of files are produced, including 'run_MCCexecutable.sh' and 'MCCexecutable,'
+% and are saved into a directory './mccfiles' which is cleared if it already exists and is
+% created if it does not.
+%
+%USEAGE
+%   $ matlab 
+%   >> createMCC(filename);
+%   >> exit
+%   $ ./mccfiles/run_MCCexecutable.sh /nasa/matlab/2022b/
+%
+%INPUT
+%   filename   .m file to be turned into an executable
+%
+%OUTPUT
+%   no direct output is produced, however CREATEMCC creates a number of files in ./mccfiles
+%
+%10.25.2023
+
+% check if mccfiles directory exists in current directory
+if exist('./mccfiles','dir')
+	!rm ./mccfiles/* 
+else
+	mkdir ./mccfiles
+end
+
+%Get dependencies
+files = matlab.codetools.requiredFilesAndProducts(filename);
+
+%Creaste long string for command, ignore Matlab's statistical toolbox license
+deps = [];
+for i=1:numel(files)
+   if contains(files{i},'normfit_issm.m')
+      continue
+   elseif contains(files{i},'dakota_moments.m')
+      continue
+   elseif contains(files{i},'dakota_out_parse.m')
+      continue
+   else
+      deps = [deps ' ' files{i}];
+   end
+end
+
+%Create command
+command = ['mcc -m ' filename deps ' -o MCCexecutable'];
+
+%Create executable
+cd ./mccfiles
+system(command);
+cd ..
