Skip to content

Instantly share code, notes, and snippets.

@mhoffman
Created June 8, 2018 13:03
Show Gist options
  • Save mhoffman/2f680eb90a5531fe6e3e588f2c835775 to your computer and use it in GitHub Desktop.
Save mhoffman/2f680eb90a5531fe6e3e588f2c835775 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Preparations"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Import `requests` library for http request and define API endpoints"
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [],
"source": [
"import requests\n",
"import pprint\n",
"import sys\n",
"import ase.io\n",
"try:# catch module change from Python2->3\n",
" import io\n",
"except:\n",
" import StringIO as io\n",
"\n",
"\n",
"API = 'http://api.catalysis-hub.org'\n",
"\n",
"SEARCH_ENDPOINT = API + '/apps/prototypeSearch/facet_search/'\n",
"PROTOTYPE_ENDPOINT = API + '/apps/prototypeSearch/prototype/'\n",
"STRUCTURE_ENDPOINT = API + '/apps/prototypeSearch/get_structure/'"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The prototype App uses 3 API endpoints for searching and retrieving structures. Below we go through a practical example of how to use them together. The `request` is a very user friendly module to make HTTP requests from python. If you don't have it installed, you can change that with `pip install requests --user`"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Search"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's make use of the facet_search API to find all materials with a given composition"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"r = requests.post(SEARCH_ENDPOINT, json={\n",
" \"search_terms\": \"stoichiometry:AB2\",\n",
" \"limit\": 1000,\n",
"})"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"462"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(r.json()['prototypes'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can learn about other possible arguments by inspecting the 'input' field of the result"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'facet_filters': [],\n",
" 'limit': 1000,\n",
" 'offset': 0,\n",
" 'search_terms': ['stoichiometry:AB2']}"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r.json()['input']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To see how many structures of this composition are in each repository, we look at the repositories facet."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[['AFLOW', 50442],\n",
" ['COD', 2888],\n",
" ['OQMD', 533],\n",
" ['MaterialsProject', 477],\n",
" ['AMCSD', 66]]"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r.json()['repositories']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The facet lists are ordered by frequency by default. There are of course all the other facets, that are also in the GUI. "
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"dict_keys(['input', 'n_atoms', 'n_compounds', 'n_prototypes', 'n_species', 'n_wyckoffs', 'prototypes', 'repositories', 'spacegroups', 'stoichiometries', 'time'])"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r.json().keys()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Filter"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"To narrow down the result, we look, e.g. only at the AB2 structures in OQMD"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [],
"source": [
"r = requests.post(SEARCH_ENDPOINT, json={\n",
" \"search_terms\": \"stoichiometry:AB2 repository:OQMD\",\n",
" \"limit\": 1000,\n",
"})"
]
},
{
"cell_type": "code",
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'input': {'facet_filters': [],\n",
" 'limit': 1000,\n",
" 'offset': 0,\n",
" 'search_terms': ['stoichiometry:AB2', 'repository:OQMD']},\n",
" 'n_atoms': [[3, 533]],\n",
" 'n_compounds': 533,\n",
" 'n_prototypes': 533,\n",
" 'n_species': [[2, 533]],\n",
" 'n_wyckoffs': [[2, 519], [3, 14]],\n",
" 'prototypes': [['AB2_a_e_139', 111],\n",
" ['AB2_a_d_191', 105],\n",
" ['AB2_a_c_225', 97],\n",
" ['AB2_a_d_164', 68],\n",
" ['AB2_a_i_12', 44],\n",
" ['AB2_a_c_166', 32],\n",
" ['AB2_a_i_69', 9],\n",
" ['AB2_a_j_65', 8],\n",
" ['AB2_a_a2_160', 8],\n",
" ['AB2_a_i_71', 8],\n",
" ['AB2_a_k_21', 6],\n",
" ['AB2_a_c_42', 5],\n",
" ['AB2_a_d_139', 5],\n",
" ['AB2_a_e_123', 4],\n",
" ['AB2_a_h_187', 3],\n",
" ['AB2_a_h_123', 3],\n",
" ['AB2_a_bc_216', 2],\n",
" ['AB2_a_c_5', 2],\n",
" ['AB2_a_g_115', 2],\n",
" ['AB2_a_c_38', 1],\n",
" ['AB2_a_a2_8', 1],\n",
" ['AB2_a_e_191', 1],\n",
" ['AB2_a_ab_38', 1],\n",
" ['AB2_a_i_65', 1],\n",
" ['AB2_a_e_38', 1],\n",
" ['AB2_a_m_10', 1],\n",
" ['AB2_a_bc_156', 1],\n",
" ['AB2_a_j_71', 1],\n",
" ['AB2_a_a2_1', 1],\n",
" ['AB2_a_n_10', 1]],\n",
" 'repositories': [['OQMD', 533]],\n",
" 'spacegroups': [[139, 116],\n",
" [191, 106],\n",
" [225, 97],\n",
" [164, 68],\n",
" [12, 44],\n",
" [166, 32],\n",
" [71, 9],\n",
" [65, 9],\n",
" [69, 9],\n",
" [160, 8],\n",
" [123, 7],\n",
" [21, 6],\n",
" [42, 5],\n",
" [38, 3],\n",
" [187, 3],\n",
" [216, 2],\n",
" [115, 2],\n",
" [5, 2],\n",
" [10, 2],\n",
" [156, 1],\n",
" [1, 1],\n",
" [8, 1]],\n",
" 'stoichiometries': [['AB2', 533]],\n",
" 'time': 1.216792106628418}"
]
},
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"r.json()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Prototypes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Some prototypes are apparently more frequent than others. So let's have a look at the structures in the `AB2_a_d_191` prototype. To this end we use the prototype API."
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [],
"source": [
"r = requests.post(PROTOTYPE_ENDPOINT, json={\n",
" \"prototype\": \"AB2_a_d_191\",\n",
" \"search_terms\": \"repository:OQMD\"\n",
"})"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"105"
]
},
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"len(r.json()['prototypes'])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Structures"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"So, let's say we want to do some specific manipulation on structures. To this end it will be handy to turn it into ASE atoms objects. "
]
},
{
"cell_type": "code",
"execution_count": 11,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
".........."
]
}
],
"source": [
"structures = []\n",
"for prototype in r.json()['prototypes'][:10]:\n",
" sys.stdout.write('.')\n",
" r_structure = requests.post(STRUCTURE_ENDPOINT, json=prototype)\n",
" cif = r_structure.json()['structure']\n",
" with io.StringIO() as cif_file:\n",
" cif_file.write(cif)\n",
" cif_file.seek(0)\n",
" structures.append(\n",
" ase.io.read(cif_file, format='cif')\n",
" )\n",
" "
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[Atoms(symbols='B2Mg', pbc=True, cell=[[3.8347, 0.0, 0.0], [-1.9173499999999992, 3.320947615892188, 0.0], [0.0, 0.0, 3.50909]]),\n",
" Atoms(symbols='Bi2Tl', pbc=True, cell=[[7.10897, 0.0, 0.0], [-3.5544849999999983, 6.156548614741462, 0.0], [0.0, 0.0, 3.38233]]),\n",
" Atoms(symbols='B2W', pbc=True, cell=[[3.78488, 0.0, 0.0], [-1.892439999999999, 3.2778022302756464, 0.0], [0.0, 0.0, 3.35748]]),\n",
" Atoms(symbols='EuHg2', pbc=True, cell=[[6.26501, 0.0, 0.0], [-3.1325049999999988, 5.4256578149635475, 0.0], [0.0, 0.0, 3.58463]]),\n",
" Atoms(symbols='CaHg2', pbc=True, cell=[[6.19862, 0.0, 0.0], [-3.0993149999999985, 5.368171048660336, 0.0], [0.0, 0.0, 3.54152]]),\n",
" Atoms(symbols='B2V', pbc=True, cell=[[3.73867, 0.0, 0.0], [-1.869329999999999, 3.23777453611273, 0.0], [0.0, 0.0, 3.03155]]),\n",
" Atoms(symbols='B2V', pbc=True, cell=[[3.74283, 0.0, 0.0], [-1.8714099999999991, 3.2413772017924734, 0.0], [0.0, 0.0, 3.01813]]),\n",
" Atoms(symbols='TiU2', pbc=True, cell=[[5.95252, 0.0, 0.0], [-2.9762599999999986, 5.155033536534948, 0.0], [0.0, 0.0, 2.80189]]),\n",
" Atoms(symbols='Au2Ba', pbc=True, cell=[[6.05807, 0.0, 0.0], [-3.0290349999999986, 5.246442517904395, 0.0], [0.0, 0.0, 4.18078]]),\n",
" Atoms(symbols='Hg2Y', pbc=True, cell=[[6.10075, 0.0, 0.0], [-3.0503799999999988, 5.283413142391953, 0.0], [0.0, 0.0, 3.47105]])]"
]
},
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"structures"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Voila!\n",
"\n",
"Ok, should be admitted, that doing `n` HTTP round trips for `n` structures is not ideal. We are working on that."
]
}
],
"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.5"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment