{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Saving and Restoring Marvin objects\n",
    "With all Marvin Tools, you can save the object you are working with locally to your filesystem, and restore it later on.  This works using the Python pickle package.  The objects are pickled (i.e. formatted and compressed) into a pickle file object. All Marvin Tools, Queries, and Results can be saved and restored.\n",
    "\n",
    "We can save a map... "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<Marvin Map (plateifu='8485-1901', property='emline_gflux', channel='ha_6564')>\n"
     ]
    }
   ],
   "source": [
    "# let's grab the H-alpha emission line flux map\n",
    "from marvin.tools.maps import Maps\n",
    "mapfile = '/Users/Brian/Work/Manga/analysis/v2_0_1/2.0.2/SPX-GAU-MILESHC/8485/1901/manga-8485-1901-MAPS-SPX-GAU-MILESHC.fits.gz'\n",
    "maps = Maps(filename=mapfile)\n",
    "haflux = maps.getMap('emline_gflux', channel='ha_6564')\n",
    "print(haflux)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can save any Marvin object with the **save** method.  This methods accepts a string filename+path as the name of the pickled file.  If a full file path is not specified, it defaults to the current directory. **save** also accepts an overwrite boolean keyword in case you want to overwrite an existing file."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'/Users/Brian/Work/github_projects/Marvin/docs/sphinx/jupyter/my_haflux_map'"
      ]
     },
     "execution_count": 15,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "haflux.save('my_haflux_map')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we have a saved map.  We can restore it anytime we want using the **restore** class method.  A class method means you call it from the imported class itself, and not on the instance.  **restore** accepts a string filename as input and returns the instantianted object."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<Marvin Map (plateifu='8485-1901', property='emline_gflux', channel='ha_6564')>\n"
     ]
    }
   ],
   "source": [
    "# import the individual Map class\n",
    "from marvin.tools.quantities import Map\n",
    "\n",
    "# restore the Halpha flux map into a new variable\n",
    "filename = '/Users/Brian/Work/github_projects/Marvin/docs/sphinx/jupyter/my_haflux_map'\n",
    "newflux = Map.restore(filename)\n",
    "print(newflux)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can also save and restore **Marvin Queries and Results**.  First let's create and run a simple query..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Your parsed filter is: \n",
      "nsa.z<0.1\n",
      "Marvin Query(mode='remote', limit=100, sort=None, order='asc')\n",
      "Results contain of a total of 4, only returning the first 4 results\n",
      "[u'mangaid', u'plate', u'plateifu', u'name', u'z']\n",
      "Marvin Results(results=NamedTuple(mangaid=u'1-209232', plate=8485, plateifu=u'8485-1901', name=u'1901', z=0.0407446920871735), \n",
      "query=u'SELECT mangadatadb.cube.mangaid AS \"cube.mangaid\", mangadatadb.cube.plate AS \"cube.plate\", concat(mangadatadb.cube.plate, \\'-\\', mangadatadb.ifudesign.name) AS \"cube.plateifu\", mangadatadb.ifudesign.name AS \"ifu.name\", mangasampledb.nsa.z AS \"nsa.z\" \\nFROM mangadatadb.cube JOIN mangadatadb.ifudesign ON mangadatadb.ifudesign.pk = mangadatadb.cube.ifudesign_pk JOIN mangasampledb.manga_target ON mangasampledb.manga_target.pk = mangadatadb.cube.manga_target_pk JOIN mangasampledb.manga_target_to_nsa ON mangasampledb.manga_target.pk = mangasampledb.manga_target_to_nsa.manga_target_pk JOIN mangasampledb.nsa ON mangasampledb.nsa.pk = mangasampledb.manga_target_to_nsa.nsa_pk JOIN mangadatadb.pipeline_info AS drpalias ON drpalias.pk = mangadatadb.cube.pipeline_info_pk \\nWHERE mangasampledb.nsa.z < 0.1 AND drpalias.pk = 25', \n",
      "count=4, \n",
      "mode=remote\n"
     ]
    }
   ],
   "source": [
    "from marvin.tools.query import Query, Results\n",
    "\n",
    "# let's make a query\n",
    "f = 'nsa.z < 0.1'\n",
    "q = Query(search_filter=f)\n",
    "print(q)\n",
    "\n",
    "# and run it\n",
    "r = q.run()\n",
    "print(r)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Let's save both the query and results for later use.  Without specifiying a filename, by default Marvin will name the query or results using your provided search filter. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "WARNING: file already exists. Not overwriting.\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "'/Users/Brian/marvin_results_nsa.z<0.1.mpf'"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "q.save()\n",
    "r.save()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By default, if you don't specify a filename for the pickled file, Marvin will auto assign one for you with extension `.mpf` (MaNGA Pickle File).\n",
    "\n",
    "Now let's restore..."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "('query', Marvin Query(mode='remote', limit=100, sort=None, order='asc'))\n",
      "('filter', 'nsa.z < 0.1')\n"
     ]
    }
   ],
   "source": [
    "newquery = Query.restore('/Users/Brian/marvin_query_nsa.z<0.1.mpf')\n",
    "print('query', newquery)\n",
    "print('filter', newquery.search_filter)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {
    "collapsed": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[NamedTuple(mangaid=u'1-209232', plate=8485, plateifu=u'8485-1901', name=u'1901', z=0.0407446920871735), NamedTuple(mangaid=u'1-209113', plate=8485, plateifu=u'8485-1902', name=u'1902', z=0.0378877110779285), NamedTuple(mangaid=u'1-209191', plate=8485, plateifu=u'8485-12701', name=u'12701', z=0.0234252735972404), NamedTuple(mangaid=u'1-209151', plate=8485, plateifu=u'8485-12702', name=u'12702', z=0.0185245610773563)]\n"
     ]
    }
   ],
   "source": [
    "myresults = Results.restore('/Users/Brian/marvin_results_nsa.z<0.1.mpf')\n",
    "print(myresults.results)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "collapsed": true
   },
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python [default]",
   "language": "python",
   "name": "python2"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.12"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
