{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Inspecting record link groups \n",
    "Find which record link groups are in a specified database, and find which records are contained in a specified record link group.\n",
    "\n",
    "This example demonstrates:\n",
    "\n",
    "- Retrieving a list of record link groups from a database\n",
    "\n",
    "- Retrieve a list of records within a specified record link group"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Create a Granta MI session\n",
    "Import the GRANTA_MIScriptingToolkit package, and create a connection to a Granta MI server."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Session created\n"
     ]
    }
   ],
   "source": [
    "import GRANTA_MIScriptingToolkit as gdl\n",
    "\n",
    "session = gdl.GRANTA_MISession('http://localhost/mi_servicelayer', autoLogon=True)\n",
    "\n",
    "print(\"Session created\")                                                               "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Retrieve record link groups from a given database\n",
    "You can use GetRecordLinkGroups to retrieve information about all the link groups in a given database.\n",
    "Find the record link groups and the group IDs for groups in the MI_Training database."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Training Exercise: id=116\n",
      "Tensile Statistical Data: id=106\n",
      "Design Data: id=105\n",
      "Tensile Test Data: id=104\n",
      "Metals Pedigree: id=102\n",
      "Tensile Statistical Data: id=103\n",
      "AM builds using this batch: id=123\n",
      "Tensile Test Data: id=101\n",
      "Tensile test data: id=8\n",
      "Material batch: id=124\n",
      "Tensile tests from this build: id=10\n",
      "MaterialUniverse: id=115\n",
      "Smart Link to MaterialUniverse: id=3\n"
     ]
    }
   ],
   "source": [
    "dbKey = \"MI_Training\"\n",
    "tableName = \"Metals Pedigree\"\n",
    "\n",
    "req = gdl.GetRecordLinkGroups(DBKey=dbKey)\n",
    "grlg_resp = session.browseService.GetRecordLinkGroups(req)\n",
    "\n",
    "groups = {} # Will be populated as RLG name -> RLG object\n",
    "for i, r in enumerate(grlg_resp.recordLinkGroups):\n",
    "    if i < 20: # Print first 20 group names\n",
    "        print(\"{0}: id={1}\".format(r.name, r.reference.recordLinkGroupIdentity))\n",
    "    if r.fromTable.name == tableName:\n",
    "        groups[r.name] = r"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## List the records within a record link group\n",
    "Search for records containing \"ICS-46634\". Subsequent steps will use only these search results."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "def TextSearch(session, text, dbKey):\n",
    "    \"\"\"\n",
    "    Simple wrapper around textsearch\n",
    "    \"\"\"\n",
    "    search = session.searchService\n",
    "    s = gdl.SimpleTextSearch()\n",
    "    s.DBKey = dbKey\n",
    "    s.searchValue = text\n",
    "    s.populateGUIDs = True\n",
    "    resp = search.SimpleTextSearch(s)\n",
    "    return resp\n",
    "\n",
    "results = TextSearch(session, \"ICS-46634\", dbKey)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Collate the record references from the search results. Use GetLinkedRecords to specify the record link group \"Tensile Test Data\"."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "recs = [r.recordReference for r in results.searchResults]\n",
    "\n",
    "name = \"Tensile Test Data\"\n",
    "g = groups[name]\n",
    "\n",
    "req = gdl.GetLinkedRecordsRequest(recordLinkGroups=[g.reference],\n",
    "                                  recordReferences=recs)\n",
    "\n",
    "glr_resp = session.browseService.GetLinkedRecords(req)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Collate and list the number of results from the record link group."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "9 links found from 1 source records\n"
     ]
    }
   ],
   "source": [
    "links = [] # list of ordered pairs of refs\n",
    "for sr in glr_resp.sourceRecords:\n",
    "    for rlg in sr.recordLinkGroups.recordLinkGroups:\n",
    "        for tr in rlg.linkedRecords:\n",
    "            links.append((sr.record, tr.recordReference))\n",
    "print(\"{0} links found from {1} source records\".format(len(links), len(recs)))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Use other functions in the MI Scripting Toolkit to retrieve the names of the test data records within the record link group."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Records linked by 'Tensile Test Data':\n",
      "Batch 921                     -> MTS-615722\n",
      "Batch 921                     -> MTS-615721\n",
      "Batch 921                     -> MTS-615723\n",
      "Batch 921                     -> MTS-615724\n",
      "Batch 921                     -> MTS-615725\n",
      "Batch 921                     -> MTS-615726\n",
      "Batch 921                     -> MTS-615734\n",
      "Batch 921                     -> MTS-615735\n",
      "Batch 921                     -> MTS-615736\n"
     ]
    }
   ],
   "source": [
    "# Prepare to use GetTreeRecords to find record names corresponding to record references\n",
    "idsToFetch = set([pair[0].identity for pair in links])      # source records\n",
    "idsToFetch.update([pair[1].identity for pair in links])     # also add target records\n",
    "\n",
    "# create ref objects for all source/target records\n",
    "recordRefs = [gdl.RecordReference(DBKey=dbKey, identity=recId) for recId in idsToFetch]\n",
    "\n",
    "# use GetTreeRecords to find record names\n",
    "req = gdl.GetTreeRecordsRequest(records=recordRefs)\n",
    "resp = session.browseService.GetTreeRecords(req)\n",
    "nameLookup = {tr.recordReference.identity:tr.shortName for tr in resp.treeRecords}\n",
    "\n",
    "# Get and print record names\n",
    "linkPairs = []\n",
    "for r in links:\n",
    "    linkPairs.append((nameLookup[r[0].identity], nameLookup[r[1].identity]))\n",
    "    \n",
    "print(\"Records linked by '{0}':\".format(name))\n",
    "for pair in linkPairs:\n",
    "    print(\"{0:<30}-> {1}\".format(pair[0], pair[1]))\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "anaconda-cloud": {},
  "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": 2
}
