{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Browse Granta MI\n",
    "Use various methods to get records from Granta MI."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook shows three methods of browsing for records in Granta MI:\n",
    "\n",
    "* Get records by internal Granta MI identifier\n",
    "* Get records by an exact match on a short text attribute value\n",
    "* Get records by navigating the tree structure"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Connect to MI"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "from GRANTA_MIScriptingToolkit import granta as mpy\n",
    "mi = mpy.connect('http://localhost/mi_servicelayer', autologon=True)\n",
    "db = mi.get_db(db_key='MI_Training')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Access a record by specifying an internal ID\n",
    "Get a record with a specific identifier, for example history GUID or history identity."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Record long name:Soda barium glass>"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "record_by_guid = db.get_record_by_id(hguid='bf5e6054-6cad-4c9d-ad7a-adfa124c504b')\n",
    "record_by_guid"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Record long name:Alumino silicate - 1720>"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "record_by_identity = db.get_record_by_id(identity=8925)\n",
    "record_by_identity"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Access a record by specifying a unique short text value\n",
    "Get a record with a unique short-text attribute value using the `Table.get_record_by_lookup_value()` method."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Record long name:MTS-615722>"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "tensile_test_data = db.get_table('Tensile Test Data')\n",
    "record_by_value = tensile_test_data.get_record_by_lookup_value('Specimen ID', 'MTS-615722')\n",
    "record_by_value"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**Note:** This method can only return a single record; if multiple records have the same value an exception is raised. Uncomment the line below to see the error."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "# tensile_test_data.get_record_by_lookup_value('Testing Standards', 'ASTM E8')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Browse for records by navigating the tree structure\n",
    "The following examples show two methods of browsing the Granta MI tree structure in Python. These examples use the\n",
    "*MaterialUniverse* table."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [],
   "source": [
    "material_universe = db.get_table('MaterialUniverse')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Iterative browsing\n",
    "Browse iteratively by getting the immediate children of each record in turn. First, get the top-level folders of the table with the `Table.children` property:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Name: Ceramics and glasses, Type: Folder',\n",
       " 'Name: Hybrids: composites, foams, honeycombs, natural materials, Type: Folder',\n",
       " 'Name: Metals and alloys, Type: Folder',\n",
       " 'Name: Polymers: plastics, elastomers, Type: Folder',\n",
       " 'Name: NEW RECORDS, Type: Folder']"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "material_universe_folders = material_universe.children\n",
    "[\"Name: {}, Type: {}\".format(child.name, child.type) for child in material_universe_folders]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Then filter for a specific folder and access the `Record.children` property to find its children:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Name: Glasses, Type: Folder']"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ceramics_and_glasses = [child for child in material_universe_folders if child.short_name == 'Ceramics and glasses'][0]\n",
    "[\"Name: {}, Type: {}\".format(child.name, child.type) for child in ceramics_and_glasses.children]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Repeat the process to navigate the tree structure until you reach your records of interest."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "['Name: Alumino silicate - 1720, Type: Record',\n",
       " 'Name: Alumino silicate - 1723, Type: Record',\n",
       " 'Name: Lithium aluminosilicate, Type: Record',\n",
       " 'Name: Soda barium glass, Type: Record']"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "glasses = [child for child in ceramics_and_glasses.children if child.short_name == 'Glasses'][0]\n",
    "alumino_silicate = [child for child in glasses.children if child.short_name == 'Alumino silicate'][0]\n",
    "[\"Name: {}, Type: {}\".format(child.name, child.type) for child in alumino_silicate.children]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Access a tree location directly\n",
    "\n",
    "The `table.get_records_from_path()` method returns all the records at the end of a specified path.\n",
    "It accepts wildcards at any level."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Get all records that are great-grandchildren of folders with the short name *Ceramics and glasses* and also have a\n",
    "parent with the short name *Baryta*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<Record long name:Barium silicate>]"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recs = material_universe.get_records_from_path(material_universe,\n",
    "                                               ['Ceramics and glasses', None, 'Baryta'],\n",
    "                                               use_short_names=True)\n",
    "recs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {
    "pycharm": {
     "name": "#%% md\n"
    }
   },
   "source": [
    "Get all records that are great-grandchildren of the folder *Ceramics and glasses*."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<Record long name:Alumino silicate - 1720>,\n",
       " <Record long name:Alumino silicate - 1723>,\n",
       " <Record long name:Lithium aluminosilicate>,\n",
       " <Record long name:Soda barium glass>,\n",
       " <Record long name:Barium silicate>]"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "recs = material_universe.get_records_from_path(ceramics_and_glasses, [None, None])\n",
    "recs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Access all descendant records within a folder\n",
    "Use the `Record.all_children()` method to retrieve all records that are a descendant of the specified record\n",
    "in a single step."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[<Record long name:Alumino silicate - 1720>,\n",
       " <Record long name:Alumino silicate - 1723>,\n",
       " <Record long name:Lithium aluminosilicate>,\n",
       " <Record long name:Soda barium glass>,\n",
       " <Record long name:Barium silicate>]"
      ]
     },
     "execution_count": 12,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "all_ceramics_and_glasses = ceramics_and_glasses.all_children()\n",
    "all_ceramics_and_glasses"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Print the results and whether the object is a record or folder."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {
    "pycharm": {
     "name": "#%%\n"
    }
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "         Record Name           |           Short Name           |        Record / Folder?       \n",
      "------------------------------------------------------------------------------------------------\n",
      "   Alumino silicate - 1720     |    Alumino silicate - 1720     |             Record            \n",
      "   Alumino silicate - 1723     |    Alumino silicate - 1723     |             Record            \n",
      "   Lithium aluminosilicate     |    Lithium aluminosilicate     |             Record            \n",
      "      Soda barium glass        |       Soda barium glass        |             Record            \n",
      "       Barium silicate         |        Barium silicate         |             Record            \n"
     ]
    }
   ],
   "source": [
    "print('{:^30.30} | {:^30.30} | {:^30.30}'.format('Record Name', 'Short Name', 'Record / Folder?'))\n",
    "print('-'*96)\n",
    "for r in all_ceramics_and_glasses:\n",
    "    print('{:^30.30} | {:^30.30} | {:^30.30}'.format(str(r.name), r.short_name, r.type))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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.6.8"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
