From 548fd831b8f9e39d5917024e742ff2a520473a70 Mon Sep 17 00:00:00 2001 From: Logan Ward Date: Mon, 4 Dec 2017 17:00:28 -0600 Subject: [PATCH 01/10] Minor fixes to OQMD ML example --- .../Example Machine Learning - OQMD.ipynb | 55 ++++++++----------- 1 file changed, 22 insertions(+), 33 deletions(-) diff --git a/examples/Example Machine Learning - OQMD.ipynb b/examples/Example Machine Learning - OQMD.ipynb index d9cae48..4539248 100644 --- a/examples/Example Machine Learning - OQMD.ipynb +++ b/examples/Example Machine Learning - OQMD.ipynb @@ -5,7 +5,7 @@ "metadata": {}, "source": [ "# Train a Model to Predict Formation Energy using the MDF\n", - "This notebook demonstrates how to create an model to predict the formation energy of crystalline materials using data from the MDF. Specifically, we will use data from the OQMD and train a model using the technique describe in a recent paper by [Ward *et al.*](https://www.nature.com/articles/npjcompumats201628)" + "This notebook demonstrates how to create an model to predict the formation energy of crystalline materials using data from the [OQMD](oqmd.org). Specifically, we will train a model based on the technique described in a 2016 paper by [Ward *et al.*](https://www.nature.com/articles/npjcompumats201628)" ] }, { @@ -95,7 +95,7 @@ "name": "stderr", "output_type": "stream", "text": [ - "100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 6847/6847 [00:13<00:00, 509.65it/s]\n" + "100%|███████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████████| 6847/6847 [00:12<00:00, 550.30it/s]\n" ] }, { @@ -118,7 +118,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Each of these results contain the key metadata of these OQMD compositions." + "Each of these results contain the key metadata of these OQMD calculations." ] }, { @@ -333,7 +333,7 @@ "output_type": "stream", "text": [ "Removed 1014/6846 entires\n", - "Wall time: 783 ms\n" + "Wall time: 1.12 s\n" ] } ], @@ -350,7 +350,7 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "Remove crazy high $\\Delta H_f$ values" + "Remove exceptionally high $\\Delta H_f$ values" ] }, { @@ -363,7 +363,7 @@ "output_type": "stream", "text": [ "Removed 1014/6846 entires\n", - "Wall time: 13 ms\n" + "Wall time: 29 ms\n" ] } ], @@ -436,7 +436,7 @@ "name": "stdout", "output_type": "stream", "text": [ - "Wall time: 48.5 s\n" + "Wall time: 42.3 s\n" ] } ], @@ -530,7 +530,7 @@ " oob_score=False, random_state=None, verbose=0, warm_start=False),\n", " fit_params=None, iid=True, n_jobs=1,\n", " param_grid={'max_features': range(8, 15)}, pre_dispatch='2*n_jobs',\n", - " refit=True, return_train_score='warn',\n", + " refit=True, return_train_score=True,\n", " scoring='neg_mean_squared_error', verbose=0)" ] }, @@ -558,7 +558,7 @@ { "data": { "text/plain": [ - "-0.047349072432448604" + "-0.050444414130504732" ] }, "execution_count": 22, @@ -578,7 +578,7 @@ { "data": { "text/plain": [ - "Text(0,0.5,'RMSE (eV/atom)')" + "" ] }, "execution_count": 23, @@ -587,9 +587,9 @@ }, { "data": { - "image/png": "iVBORw0KGgoAAAANSUhEUgAAAYsAAAEKCAYAAADjDHn2AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAADl0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uIDIuMS4wLCBo\ndHRwOi8vbWF0cGxvdGxpYi5vcmcvpW3flQAAGQpJREFUeJzt3Xu0XnV95/H3xwQxmpEgxEvCVYpU\nCkjwFGupeAElXiZcHBSUFiwV0aEdhzVaWLTOiKuCROvUiqtQi3gFRRCzFIgtorWOcUgMt3BRQIUk\ntsQLA0hEAt/549mBh8PJ2U9OznOek3Per7XOOs/+7d9+9ncvQj7Zt98vVYUkSaN5yqALkCRNfoaF\nJKmVYSFJamVYSJJaGRaSpFaGhSSplWEhSWplWEiSWhkWkqRWMwddwHjZcccda7fddht0GZK0VVmx\nYsXPq2puW78pExa77bYby5cvH3QZkrRVSfLTXvp5GUqS1MqwkCS1MiwkSa0MC0lSK8NCktTKsJAk\ntTIsJEmtDAtJUivDQpLUyrCQJLUyLCRJrQwLSVIrw0KS1MqwkCS1MiwkSa0MC0lSK8NCktTKsJAk\ntTIsJEmtDAtJUqu+hkWShUluS3J7ktNGWH9qkpuT3JDk6iS7dq17JMl1zc+SftYpSRrdzH59cZIZ\nwLnAq4HVwLVJllTVzV3dVgJDVfVgkncC5wBvbtatr6r9+1WfJKl3/TyzOBC4varurKrfAhcDh3d3\nqKprqurBZnEZsFMf65EkjVE/w2I+cHfX8uqmbVNOBK7sWn5akuVJliU5oh8FSpJ607fLUEBGaKsR\nOybHAUPAy7uad6mqtUmeD3wzyY1Vdcew7U4CTgLYZZddxqdqSdKT9PPMYjWwc9fyTsDa4Z2SHAqc\nASyqqoc2tlfV2ub3ncC3gAXDt62q86tqqKqG5s6dO77VS5Ie08+wuBbYM8nuSZ4KHAM84ammJAuA\n8+gExT1d7dsn2bb5vCNwENB9Y1ySNIH6dhmqqjYkOQVYCswALqiqVUnOBJZX1RJgMTAbuCQJwF1V\ntQh4IXBekkfpBNrZw56ikiRNoFSNeBthqzM0NFTLly8fdBmStFVJsqKqhtr6+Qa3JKmVYSFJamVY\nSJJaGRaSpFaGhSSplWEhSWplWEiSWhkWkqRWhoUkqZVhIUlqZVhIkloZFpKkVoaFJKmVYSFJamVY\nSJJaGRaSpFaGhSSplWEhSWplWEiSWhkWkqRWhoUkqZVhIUlqZVhIkloZFpKkVoaFJKmVYSFJamVY\nSJJaGRaSpFaGhSSplWEhSWplWEiSWvU1LJIsTHJbktuTnDbC+lOT3JzkhiRXJ9l12PpnJlmT5OP9\nrFPqp8tXruGgs7/J7qd9nYPO/iaXr1wz6JKkzda3sEgyAzgXeC2wN3Bskr2HdVsJDFXVfsCXgXOG\nrf8A8O1+1Sj12+Ur13D6ZTey5t71FLDm3vWcftmNBoa2Ov08szgQuL2q7qyq3wIXA4d3d6iqa6rq\nwWZxGbDTxnVJXgw8B/hGH2uU+mrx0ttY//AjT2hb//AjLF5624Aqksamn2ExH7i7a3l107YpJwJX\nAiR5CvAR4D2j7SDJSUmWJ1m+bt26LSxXGn9r712/We3SZNXPsMgIbTVix+Q4YAhY3DS9C7iiqu4e\nqf9jX1Z1flUNVdXQ3Llzt6hYqR/mzZm1We3SZNXPsFgN7Ny1vBOwdninJIcCZwCLquqhpvmlwClJ\nfgJ8GPiTJGf3sVapL95z2F7M2mbGE9pmbTOD9xy214AqksZmZh+/+1pgzyS7A2uAY4C3dHdIsgA4\nD1hYVfdsbK+qt3b1OYHOTfAnPU0lTXZHLOhceV289DbW3rueeXNm8Z7D9nqsXdpa9C0sqmpDklOA\npcAM4IKqWpXkTGB5VS2hc9lpNnBJEoC7qmpRv2qSBuGIBfMNB231UjXibYSROyfPAH5TVY+0dp5g\nQ0NDtXz58kGXIUlblSQrqmqord+oZxbNU0nHAG8Ffh94CNg2yTrgCuD8qvrRONQrSRPi8pVrvCw4\nBm2Xoa4B/gU4Hbipqh4FSPIs4JXA2Um+UlWf62+ZkrTlNr4kufHdl40vSQJbZWBMZPC1hcWhVfXw\n8Maq+iVwKXBpkm36UpkkjbPRXpLc2sJiooNv1Ednu4MiyfZJ9ktywMaf4X0kaTKbSi9JTvToAD09\nDZXkA8AJwB08/mJdAa/qS1WS1Afz5sxizQjBsDW+JDnRwdfrS3lvAvaoqldU1SubH4NC0lZlKr0k\nOdGjA/QaFjcBc/pSgSRNkCMWzOeso/Zl/pxZBJg/ZxZnHbXvVne/AiY++Hp9Ke8sYGWSm+g8PguA\nL9BJ2tpMlZckJ3p0gF7D4tPAh4AbgUf7UokkabNMZPD1GhY/r6qP9bUSSdKk1WtYrEhyFrCEJ16G\n+kFfqpIkTSq9hsWC5vcfdLX56KwkTRM9hUVVvbLfhUiSJq+eHp1Nsl2Sv904hWmSjyTZrt/FSZIm\nh17fs7gAuJ/Oy3lvAu4DPtWvoiRJk0uv9yz2qKo3di2/P8l1/ShIkjT59HpmsT7JH21cSHIQsPWN\nvCVJGpNezyxOBj7TdZ/iV8Dx/SlJkjTZ9BoW91XVi5I8E6Cq7kuyex/rkiRNIr1ehroUOiFRVfc1\nbV/uT0mSpMmmbQ7u3wV+D9guyVFdq54JPK2fhUmSJo+2y1B7AW+gMzz5f+5qvx94e7+KkmBi5xeW\nNLpRw6Kqvgp8NclLq+p7E1STNOHzC0saXa83uFcm+a90Lkk9dvmpqv60L1Vp2httfmHDQpp4vd7g\n/izwXOAw4NvATnQuRUl9MdHzC0saXa9h8TtV9dfAr6vq08DrgX37V5amu4meX1jS6HoNi4eb3/cm\n2QfYDtitLxVJTPz8wpJG1+s9i/OTbA/8NZ0JkGY3n6W+mOj5hSWNLlW16ZXJS4FlNVqnSWJoaKiW\nL18+6DIkaauSZEVVDbX1azuzOB44N8kPgauAq6rq38ejQElbF997md5GvWdRVSdX1QHA/wK2By5M\n8r0kH0xycJIZo22fZGGS25LcnuS0EdafmuTmJDckuTrJrk37rklWJLkuyaokJ4/9ECVtqY3vvay5\ndz3F4++9XL5yzaBL0wTp6QZ3Vd1aVR+tqoV05t3+N+Bo4Pub2qYJknOB1wJ7A8cm2XtYt5XAUFXt\nR2esqXOa9p8Bf1hV+wMvAU5LMq/3w5I0nkZ770XTQ9vYUF8HvgBcXlW/Bqiq9cAVzc9oDgRur6o7\nm++6GDgcuHljh6q6pqv/MuC4pv23Xe3b0vtTW8LLBRp/vveitr+Ez6czNtSPk3wxyRFJntrjd88H\n7u5aXt20bcqJwJUbF5LsnOSG5js+VFVre9zvtOblAvWD772o7Z7FV6vqWGBX4DI6N7zvSnJBkle3\nfHdG+soROybHAUPA4q59391cnvod4Pgkzxlhu5OSLE+yfN26dS3lTA9eLlA/+N6Ler1nsb6qvlhV\nRwKvARbQeTpqNKuBnbuWdwKedHaQ5FDgDGBRVT00wr7XAquAl42w7vyqGqqqoblz5/ZyKFOelwvU\nD0csmM9ZR+3L/DmzCDB/zizOOmpfL29OIz29lNf8q/5NwDHA84BLgLe1bHYtsGczo96aZtu3DPve\nBcB5wMKquqerfSfgF1W1vnkZ8CDgb3s6omlu3pxZrBkhGLxcoC11xIL5hsM0NuqZRZK3J/km8APg\nBcB7q+r5VfWXVXXdaNtW1QbgFGApcAvwpapaleTMJIuabovpvA1+SfOY7JKm/YXA95NcT2fgwg9X\n1Y1jPcjpxMsFkvqh7Q3uTwEXAf9SVY9OWFVj4Bvcj/NpKEm9Gpc3uKvqbc2XpbkJ/fyqOjPJLsBz\nq+r/jk+5Gk9eLpA03np9f+ETwEuBY5vl++m8cCdJmgZ6HXX2JVV1QJKVAFX1q81430KStJXreT6L\nZviOAkgyF5jU9zAkSeOn17D4GPAV4NlJ/obO2FAf7FtVkqRJpafLUFX1+SQrgEPovJl9RFXd0tfK\nJEmTRttAgrOr6gHojDwL3DpaH0nS1NR2GeqrST7SzF3xjI2NSZ6f5MQkS4GF/S1RkjRobe9ZHJLk\ndcA7gIOSPAt4GLgN+DpwvDPnSdLU13rPoqp6mbtCkjSFOamQJKmVYSFJamVYSJJatQ1R/qquz7sP\nW3dUv4qSJE0ubWcWH+76fOmwdX81zrVIkiaptrDIJj6PtCxJmqLawqI28XmkZUnSFNX2nsXzm6lO\n0/WZZnn3TW8mSZpK2sLi8K7PHx62bviyJGmKahvu49vdy0m2AfYB1lTVPf0sTJI0ebQ9OvsPSX6v\n+bwdcD3wGWBlkmNH21aSNHW03eB+WVWtaj6/DfhhVe0LvBh4b18rkyRNGm1h8duuz68GLgdwpFlJ\nml7awuLeJG9IsgA4CLgKIMlMYFa/i5MkTQ5tT0O9g878288F3t11RnEInfksJEnTQNvTUD9khJnw\nqmopsLRfRUmSJpe2Obg/Ntr6qvqL8S1HkjQZtV2GOhm4CfgSsBbHg5KkaaktLJ4HHA28GdgAfBG4\ntKp+1e/CJEmTx6hPQ1XVL6rqH6rqlcAJwBxgVZI/nojiJEmTQ08z5SU5AHg3cBxwJbCix+0WJrkt\nye1JThth/alJbk5yQ5Krk+zatO+f5HtJVjXr3tz7IUmSxlvbDe73A28AbgEuBk6vqg29fHGSGcC5\ndF7mWw1cm2RJVd3c1W0lMFRVDyZ5J3AOnUteDwJ/UlU/SjIPWJFkaVXdu5nHJ0kaB233LP4auBN4\nUfPzwSTQudFdVbXfKNseCNxeVXcCJLmYzii2j4VFVV3T1X8ZnTOXjY/sbuyzNsk9wFzAsJCkAWgL\niy2Zs2I+cHfX8mrgJaP0P5HOJa4nSHIg8FTgji2oRZK0BdpeyvvpSO3NJaZjgBHXb+w20ldu4vuO\nA4aAlw9rfx7wWeD4qnp0hO1OAk4C2GWXXUYpRZK0JdqGKH9mktOTfDzJa9Lx53QuTb2p5btXAzt3\nLe9E512N4fs4FDgDWFRVD3Xvm86QIn9VVctG2kFVnV9VQ1U1NHfu3JZyJElj1XYZ6rPAr4DvAX8G\nvIfOJaHDq+q6lm2vBfZMsjuwhs6ZyFu6OzQDFJ4HLOyeTCnJU4GvAJ+pqkt6PxxJUj+0zsHdzF9B\nkk8CPwd2qar72764qjYkOYXOGFIzgAuqalWSM4HlVbUEWAzMBi5pbpzfVVWL6Jy1HAzskOSE5itP\n6CGgJEl90BYWD2/8UFWPJPlxL0HRtc0VwBXD2t7X9fnQTWz3OeBzve5HktRfbWHxoiT3NZ8DzGqW\nNz46+8y+VidJmhTanoaaMVGFTBoPPABr18K8eTB79qCrkaRJoafhPqaFDRu445i38Zvtd+CBffbn\nN9vvwB3HvA029PTCuiRNaW2XoaaNO457O/MuvYinbXh82vF5l17EHcAeF39qcIVJ0iTgmQXAAw8w\n/9IvMGvDQ09onrXhIeZfdlHn0pQkTWOGBcDatWzIyLdnNuQpnXsYkjSNGRYA8+Yxsx4ZcdXMerRz\ns1uSpjHDAmD2bNa88S2sn7ntE5rXz9yWNUcd61NRkqY9b3A39vjcP3IHMP+yi9iQpzCzHmXtUcey\nx+f+cdClSdLAGRYbzZzZeerpgb9/7D2LPTyjkCTAsHiy2bPhBS8YdBWSNKl4z0KS1MqwkCS1Miwk\nSa0MC0lSK8NCktTKsJAktTIsJEmtDAtJUivDQpLUyrCQJLUyLCRJrQwLSVIrw0KS1MqwkCS1Miwk\nSa0MC0lSK8NCktTKsJAktTIsJEmtDAtJUqu+hkWShUluS3J7ktNGWH9qkpuT3JDk6iS7dq27Ksm9\nSb7WzxolSe36FhZJZgDnAq8F9gaOTbL3sG4rgaGq2g/4MnBO17rFwB/3qz5JUu/6eWZxIHB7Vd1Z\nVb8FLgYO7+5QVddU1YPN4jJgp651VwP397E+SVKP+hkW84G7u5ZXN22bciJw5ebsIMlJSZYnWb5u\n3boxlChJ6kU/wyIjtNWIHZPjgCE6l556VlXnV9VQVQ3NnTt3DCVKknoxs4/fvRrYuWt5J2Dt8E5J\nDgXOAF5eVQ/1sR5J0hj188ziWmDPJLsneSpwDLCku0OSBcB5wKKquqePtUiStkDfwqKqNgCnAEuB\nW4AvVdWqJGcmWdR0WwzMBi5Jcl2Sx8IkyXeAS4BDkqxOcli/apUkja6fl6GoqiuAK4a1va/r86Gj\nbPuyPpYmSdoMvsEtSWplWEiSWhkWkqRWhoUkqZVhIUlqZVhIkloZFpKkVoaFJKmVYSFJamVYSJJa\nGRaSpFaGhSSplWEhSWplWEiSWhkWkqRWhoUkqZVhIUlqZVhIkloZFpKkVoaFJKmVYSFJamVYSJJa\nGRaSpFaGhSSplWEhSWplWEiSWhkWkqRWhoUkqZVhIUlqlaoadA3jIsk64Kfj9HU7Aj8fp+8aJI9j\ncvE4JpepchywZceya1XNbes0ZcJiPCVZXlVDg65jS3kck4vHMblMleOAiTkWL0NJkloZFpKkVobF\nyM4fdAHjxOOYXDyOyWWqHAdMwLF4z0KS1MozC0lSK8OiS5L/nmRVkpuSXJTkaYOuaSyS/LfmGFYl\nefeg69kcSS5Ick+Sm7ranpXkn5P8qPm9/SBr7MUmjuPo5r/Jo0m2iqdwNnEci5PcmuSGJF9JMmeQ\nNfZiE8fxgeYYrkvyjSTzBlljL0Y6jq51/yNJJdmxH/s2LBpJ5gN/AQxV1T7ADOCYwVa1+ZLsA7wd\nOBB4EfCGJHsOtqrNciGwcFjbacDVVbUncHWzPNldyJOP4ybgKOBfJ7yasbuQJx/HPwP7VNV+wA+B\n0ye6qDG4kCcfx+Kq2q+q9ge+BrxvwqvafBfy5OMgyc7Aq4G7+rVjw+KJZgKzkswEng6sHXA9Y/FC\nYFlVPVhVG4BvA0cOuKaeVdW/Ar8c1nw48Onm86eBIya0qDEY6Tiq6paqum1AJY3JJo7jG82fLYBl\nwE4TXthm2sRx3Ne1+Axg0t/A3cT/HwAfBd5LH4/BsGhU1Rrgw3SS+WfA/6uqbwy2qjG5CTg4yQ5J\nng68Dth5wDVtqedU1c8Amt/PHnA9etyfAlcOuoixSvI3Se4G3srWcWbxJEkWAWuq6vp+7sewaDTX\nwQ8HdgfmAc9Ictxgq9p8VXUL8CE6lwquAq4HNoy6kTQGSc6g82fr84OuZayq6oyq2pnOMZwy6Ho2\nV/MPwjOYgKAzLB53KPDjqlpXVQ8DlwF/OOCaxqSq/qmqDqiqg+mcsv5o0DVtof9I8jyA5vc9A65n\n2ktyPPAG4K01NZ6//wLwxkEXMQZ70PkH7vVJfkLnkuAPkjx3vHdkWDzuLuAPkjw9SYBDgFsGXNOY\nJHl283sXOjdULxpsRVtsCXB88/l44KsDrGXaS7IQ+EtgUVU9OOh6xmrYgx+LgFsHVctYVdWNVfXs\nqtqtqnYDVgMHVNW/j/e+fCmvS5L3A2+mc2q9EvizqnposFVtviTfAXYAHgZOraqrB1xSz5JcBLyC\nziia/wH8T+By4EvALnRC/eiqGukm36SxieP4JfD3wFzgXuC6qjpsUDX2YhPHcTqwLfCLptuyqjp5\nIAX2aBPH8TpgL+BROiNWn9zcu5y0RjqOqvqnrvU/ofNE57iPpmtYSJJaeRlKktTKsJAktTIsJEmt\nDAtJUivDQpLUyrDQlNWMwPnZruWZSdYl+Vof9vVIM3rpxp/dxvAdc5K8a7xrk8bDzEEXIPXRr4F9\nksyqqvV0RuXs13P065vRS7fEHOBdwCc2Z6MkM6rqkS3ctzQqzyw01V0JvL75fCxdb7MnOTDJ/0my\nsvm9V9N+apILms/7NnODPH1zd5xkRjP3w7XNvAnvaNpnJ7k6yQ+S3Jjk8GaTs4E9mjOTxUle0X0W\nlOTjSU5oPv8kyfuS/BtwdJI9klyVZEWS7yT53abf0U391yfZmoZG1yTjmYWmuouB9zV/6e4HXAC8\nrFl3K3BwVW1IcijwQTrjA/1v4FtJjqQzSNs7ehjWYlaS65rPP66qI4ET6Yxe/PtJtgW+m+QbwN3A\nkVV1XzNRzbIkS+jM07HPxjOUJK9o2edvquqPmr5X03kD+UdJXkLn7ORVdAaYO6yq1mwNkxRp8jIs\nNKVV1Q3N/YNjgSuGrd4O+HQzRlAB2zTbPNr8C/4G4Lyq+m4PuxrpMtRrgP2S/Jeu/e1JZ/yeDyY5\nmM5QE/OB52zmoQF8ETpnKnQGvbykM6wZ0BmOA+C7wIVJvkRncExpTAwLTQdL6MxV8go6Y2Zt9AHg\nmqo6sgmUb3Wt2xN4gM5w9WMV4M+raukTGjtBNBd4cVU93IznM9IUvht44qXi4X1+3fx+CnDvSPdM\nqurk5kzj9cB1Sfavql8M7ye18Z6FpoMLgDOr6sZh7dvx+A3vEzY2JtkO+DvgYGCHrjODzbUUeGeS\nbZrvfUGSZzT7vacJilcCuzb97wf+U9f2PwX2TrJtU9MhI+2kmfHtx0mObvaTJC9qPu9RVd+vqvcB\nP2frnwhLA2JYaMqrqtVV9XcjrDoHOCvJd+nMub7RR4FPVNUP6dx3ODvJs5MMJfnkZuz6k8DNdOYX\nuAk4j87Z/OeBoSTL6czQdmtT5y/o3Ne4Kcniqrqbzmi7NzTbrBxlX28FTkxyPbCKzkReAIubm+g3\n0Zn7u6+zqWnqctRZSVIrzywkSa0MC0lSK8NCktTKsJAktTIsJEmtDAtJUivDQpLUyrCQJLX6/9ig\nB14aBsULAAAAAElFTkSuQmCC\n", + "image/png": "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\n4QWhvagAAAAASUVORK5CYII=\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -636,9 +636,7 @@ { "cell_type": "code", "execution_count": 25, - "metadata": { - "collapsed": true - }, + "metadata": {}, "outputs": [], "source": [ "cv_prediction = cross_val_predict(model, data[feature_labels], data['delta_e'], cv=10)" @@ -660,9 +658,9 @@ "name": "stdout", "output_type": "stream", "text": [ - "r2_score 0.876058126274\n", - "mean_absolute_error 0.178085812522\n", - "mean_squared_error 0.0828029123798\n" + "r2_score 0.873449467512\n", + "mean_absolute_error 0.178289556346\n", + "mean_squared_error 0.08454570145\n" ] } ], @@ -688,9 +686,9 @@ "outputs": [ { "data": { - "image/png": "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\nGww+5v8ANx9D309rWwEAAAAASUVORK5CYII=\n", + "image/png": "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\nykKpJSUlAAAAAElFTkSuQmCC\n", "text/plain": [ - "" + "" ] }, "metadata": {}, @@ -707,8 +705,8 @@ "\n", "ax.plot(ax.get_xlim(), ax.get_xlim(), 'k--')\n", "\n", - "ax.set_xlabel('DFT $\\Delta H_f$ (eV)', fontsize=20)\n", - "ax.set_ylabel('ML $\\Delta H_f$ (eV)', fontsize=20)\n", + "ax.set_xlabel('DFT $\\Delta H_f$ (eV/atom)')\n", + "ax.set_ylabel('ML $\\Delta H_f$ (eV/atom)')\n", "\n", "fig.set_size_inches(3, 3)\n", "fig.tight_layout()\n", @@ -717,16 +715,7 @@ }, { "cell_type": "code", - "execution_count": 28, - "metadata": { - "collapsed": true - }, - "outputs": [], - "source": [] - }, - { - "cell_type": "code", - "execution_count": 28, + "execution_count": null, "metadata": { "collapsed": true }, @@ -750,7 +739,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.0" } }, "nbformat": 4, From 42ca2a8c1f14a8eba65c1a63c0e1427a75a47d54 Mon Sep 17 00:00:00 2001 From: jgaff Date: Thu, 15 Mar 2018 14:25:13 -0500 Subject: [PATCH 02/10] Update Forge to new schema (fails testing) Update Forge helpers to work with the new, MDF Connect-approved schema. As the data currently in Search does not yet adhere to this schema, this commit will fail testing initially. Also update the tutorials and examples (which will be re-run for corrected outputs later). --- docs/examples/Example Aggregations.ipynb | 175 +---- ...xample Analysis - Fe-Cr-Al Oxidation.ipynb | 99 +-- .../Example Machine Learning - OQMD.ipynb | 2 +- .../Example Statistics - MDF Datasets.ipynb | 212 +----- docs/tutorials/1 - Introduction.ipynb | 118 +--- .../2 - Core Query Builder Functions.ipynb | 143 +--- ...3 - Expanded Query Builder Functions.ipynb | 494 +------------- .../4 - General Helper Functions.ipynb | 545 ++------------- .../5 - Field-Specific Helper Functions.ipynb | 637 ++---------------- .../6 - Data Retrieval Functions.ipynb | 86 +-- mdf_forge/forge.py | 111 +-- setup.py | 4 +- tests/test_forge.py | 228 +++---- 13 files changed, 289 insertions(+), 2565 deletions(-) diff --git a/docs/examples/Example Aggregations.ipynb b/docs/examples/Example Aggregations.ipynb index 30c8c70..8d0145e 100644 --- a/docs/examples/Example Aggregations.ipynb +++ b/docs/examples/Example Aggregations.ipynb @@ -16,7 +16,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -26,7 +26,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -43,50 +43,20 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 29189/29189 [00:27<00:00, 1067.83it/s]" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "29189\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], + "outputs": [], "source": [ "# First, let's aggregate all the nist_xps_db data.\n", - "all_entries = mdf.aggregate_source(\"nist_xps_db\")\n", + "all_entries = mdf.aggregate_source_names(\"nist_xps_db\")\n", "print(len(all_entries))" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{'': 15940, 'good': 4, 'Good': 1615, 'Adequate': 11630}\n" - ] - } - ], + "outputs": [], "source": [ "# Now, let's parse out the \"Quality of Data\" and print te results for analysis.\n", "qualities = {}\n", @@ -110,143 +80,26 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 29168/29168 [01:07<00:00, 298.34it/s]" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "29168\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], + "outputs": [], "source": [ "# First, let's aggregate everything that has \"Ga\" in the list of elements.\n", - "all_results = mdf.aggregate(\"mdf.elements:Ga\")\n", + "all_results = mdf.aggregate(\"material.elements:Ga\")\n", "print(len(all_results))" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "{\n", - " \"Ac\": 651,\n", - " \"Ag\": 588,\n", - " \"Al\": 576,\n", - " \"Ar\": 2,\n", - " \"As\": 1330,\n", - " \"Au\": 649,\n", - " \"B\": 681,\n", - " \"Ba\": 802,\n", - " \"Be\": 496,\n", - " \"Bi\": 583,\n", - " \"Br\": 127,\n", - " \"C\": 1843,\n", - " \"Ca\": 682,\n", - " \"Cd\": 581,\n", - " \"Ce\": 639,\n", - " \"Cl\": 672,\n", - " \"Co\": 954,\n", - " \"Cr\": 712,\n", - " \"Cs\": 552,\n", - " \"Cu\": 817,\n", - " \"Dy\": 600,\n", - " \"Er\": 670,\n", - " \"Eu\": 614,\n", - " \"F\": 344,\n", - " \"Fe\": 793,\n", - " \"Ga\": 29168,\n", - " \"Gd\": 612,\n", - " \"Ge\": 776,\n", - " \"H\": 1933,\n", - " \"Hf\": 659,\n", - " \"Hg\": 534,\n", - " \"Ho\": 598,\n", - " \"I\": 187,\n", - " \"In\": 603,\n", - " \"Ir\": 557,\n", - " \"K\": 698,\n", - " \"La\": 960,\n", - " \"Li\": 990,\n", - " \"Lu\": 527,\n", - " \"Mg\": 955,\n", - " \"Mn\": 715,\n", - " \"Mo\": 606,\n", - " \"N\": 1402,\n", - " \"Na\": 840,\n", - " \"Nb\": 564,\n", - " \"Nd\": 616,\n", - " \"Ni\": 836,\n", - " \"Np\": 506,\n", - " \"O\": 4031,\n", - " \"Os\": 668,\n", - " \"P\": 676,\n", - " \"Pa\": 607,\n", - " \"Pb\": 544,\n", - " \"Pd\": 653,\n", - " \"Pm\": 624,\n", - " \"Pr\": 714,\n", - " \"Pt\": 743,\n", - " \"Pu\": 535,\n", - " \"Rb\": 588,\n", - " \"Re\": 498,\n", - " \"Rh\": 584,\n", - " \"Ru\": 562,\n", - " \"S\": 512,\n", - " \"Sb\": 632,\n", - " \"Sc\": 715,\n", - " \"Se\": 374,\n", - " \"Si\": 1075,\n", - " \"Sm\": 773,\n", - " \"Sn\": 606,\n", - " \"Sr\": 711,\n", - " \"Ta\": 558,\n", - " \"Tb\": 591,\n", - " \"Tc\": 508,\n", - " \"Te\": 758,\n", - " \"Th\": 519,\n", - " \"Ti\": 693,\n", - " \"Tl\": 687,\n", - " \"Tm\": 590,\n", - " \"U\": 507,\n", - " \"V\": 714,\n", - " \"W\": 563,\n", - " \"Xe\": 1,\n", - " \"Y\": 724,\n", - " \"Yb\": 741,\n", - " \"Zn\": 672,\n", - " \"Zr\": 648\n", - "}\n" - ] - } - ], + "outputs": [], "source": [ "# Now, let's parse out the other elements in each record and keep a running tally to print out.\n", "elements = {}\n", "for record in all_results:\n", " if record[\"mdf\"][\"resource_type\"] == \"record\":\n", - " elems = record[\"mdf\"][\"elements\"]\n", + " elems = record[\"material\"][\"elements\"]\n", " for elem in elems:\n", " if elem in elements.keys():\n", " elements[elem] += 1\n", @@ -279,7 +132,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.4" } }, "nbformat": 4, diff --git a/docs/examples/Example Analysis - Fe-Cr-Al Oxidation.ipynb b/docs/examples/Example Analysis - Fe-Cr-Al Oxidation.ipynb index 755f9b8..d10503e 100644 --- a/docs/examples/Example Analysis - Fe-Cr-Al Oxidation.ipynb +++ b/docs/examples/Example Analysis - Fe-Cr-Al Oxidation.ipynb @@ -18,7 +18,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -46,17 +46,9 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Found 1401 matches\n" - ] - } - ], + "outputs": [], "source": [ "mdf = Forge()\n", "res = mdf.match_field(\"mdf.source_name\",\"fe_cr_al_oxidation\").match_field(\"mdf.resource_type\", \"record\").search()\n", @@ -65,39 +57,9 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'fe_cr_al_oxidation': {'atomic_composition_percent': {'Al': 3.1,\n", - " 'Cr': 26.5,\n", - " 'Fe': 70.5},\n", - " 'temperature_k': 420.0},\n", - " 'mdf': {'collection': 'Fe-Cr-Al Oxidation Studies',\n", - " 'composition': 'FeCrAl',\n", - " 'elements': ['Cr', 'Fe', 'Al'],\n", - " 'ingest_date': '2017-08-04T21:26:53.296946Z',\n", - " 'links': {'csv': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/Fe_Cr_Al_data/420 K/420 K Point 104.txt'},\n", - " 'landing_page': 'https://materialsdata.nist.gov/dspace/xmlui/handle/11256/836#104',\n", - " 'parent_id': '5984e69cf2c00439c790bf54'},\n", - " 'mdf_id': '5984e69df2c00439c790bfbc',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 104,\n", - " 'source_name': 'fe_cr_al_oxidation',\n", - " 'tags': ['csv'],\n", - " 'title': 'Fe-Cr-Al Oxidation - 420 K Point 104'}}" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "res[0]" ] @@ -111,7 +73,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -148,7 +110,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -183,20 +145,9 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\nyuQAAAAASUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "x = [r[\"data\"][\"Al\"] for r in results]\n", "y = [r[\"data\"][\"Cr\"] for r in results]\n", @@ -219,20 +170,9 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\n/vx5bN68GWq1Wu5IQqusrMSdO3ewePFi+Pv7a7+A+5fY+fv7o7i4WOaUYnnc/29emqjf+LcrKI1G\ngzNnzqCyslI7VlVVhVOnTkGj0ciYTFxtbW1ISEjAsWPHsHHjRnh5eckdSXhubm7IyMjo9AUAkydP\nRkZGBlxcXGROKZbg4GAAQFFRUYfxw4cPQ6FQwN7eXo5Y1Ed4TltQ06dPx65duxATE4P4+HgYGRlh\n3bp1UCgUmDFjhtzxhPT5558jPz8f0dHRsLCwwK+//qrdplAoeJj8KVhbW2P06NFdbnN0dHzoNnq4\nV199FaNHj0ZiYiJu3rypfSNaUVER339hAIwkSZLkDkFPp6amBklJSThy5AgkSUJAQACWLl0KJycn\nuaMJSaPRoLq6usttsbGxWLBgQR8n0l9qtRrR0dFYuHCh3FGE1NjYiNTUVOzfvx8NDQ0YOnQo5s6d\ni7CwMLmjUS9jaRMREQmC57SJiIgEwdImIiISBEubiIhIECxtIiIiQbC0iYiIBMHSJiIiEgRLm+gB\nmZmZUKvVOH78uNxRepVGo8Hbb78tdwwi6gaWNhmU8vJyqNVqqNVqnDt3rkfnTkhIgFqtxrx58x66\nz/bt25GZmdmjj6srLl26hIiICHh7eyM0NBTZ2dmd9mltbcXUqVOxdu1aGRISiY+lTQYlKysLlpaW\nsLOzQ1ZWVo/N29jYiAMHDsDZ2RlFRUW4du1al/tlZGT06OM+i/z8fGzZsqVH5mptbUVsbCzq6uqw\nePFiuLu7Y8mSJR0+Cha4//ybmpoQExPTI49LZGhY2mQw2trakJ2djdDQUEyaNAl5eXloaWnpkbnz\n8vJw584dpKamAgBycnJ6ZN7eZG5uDnNz8x6Zq7y8HGVlZVi+fDlmzZqF1atXY9CgQSgoKNDuc+XK\nFaxfvx6JiYno169fjzwukaFhaZPBOHr0KGprazFlyhRMnToVt27dQmFhYY/MnZWVBV9fX3h6euLf\n//53l6tptVqN6upqnDhxQnuI/sFbf3799deYPHkyPDw84O/vj+joaFy8eLHDPlVVVVCr1UhLS8P3\n33+PsLAweHh44LXXXsPBgwcBABcvXkRUVBS8vb0REBCAdevW4cFPLH7YOe2ffvoJkZGR8PPzg6en\nJyZMmPDYG1HcuXMHADBgwAAAgJGREaytrdHc3KzdZ8WKFQgMDMS4ceMeORcRPRxLmwxGZmYmHBwc\n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\nRU5ErkJggg==\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "ax = sns.jointplot(np.asarray(x), np.asarray(y), kind=\"kde\", \n", " shade=True, stat_func=None, size=7).set_axis_labels(\"Al Atomic %\", \"Cr Atomic %\")" @@ -240,20 +180,9 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "image/png": "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\nh/r6eug6P6MhIiIqlCGF9s6dO3HppZdi48aN3ZdNmTIF99xzD6ZPn5634YiIiGifIdXjN998M6ZM\nmYKXXnoJH330EZ566ikEg0HcdNNN+Z6PiIiIsvoN7SeffLLXy9evX49ly5Zh8uTJCAQCmDNnDs49\n91xs2LChIEMSERHRAKF911134fzzz8emTZsOuHzatGl44oknkMlkAABtbW14/vnnMWXKlMJNSkRE\nNML1G9rPP/88jjjiCPzDP/wD7rzzzu6Q/tGPfoQXX3wRxx13HBYuXIiFCxfi008/xfXXX1+UoYmI\niEaifg9EKysrww033IC/+7u/w0033YTnnnsON910ExYuXIiXXnoJa9asQXNzM8aNG4eTTz4ZlZWV\nxZqbiIhoxHF09PhRRx2FJ598Eo888gi+973v4Utf+hKuv/56nHHGGYWej4iIiLIcHz2uaRq+/e1v\n4/nnn4dlWTjttNPw6KOPQilvnUGJiIjIqwYM7cbGRjzxxBN4+OGH8dFHH2HChAm46667cNttt2HF\nihU466yz8MknnxRjViIiohGt33r81VdfxRVXXAEACAaDiMVi+O53v4urrroKJ598MhYsWIC7774b\n5557Ls4991xceeWViEQiRRmciIhopOl3pX3bbbdh/vz5WLt2LdauXYurr74a9913H/bu3QsACIVC\nuOaaa/A///M/+Oijj3DaaacVZWgiIqKRqN/Q3rFjBxYtWoRgMAgA+NrXvgYpJXbu3HnA7WbNmoXH\nHnsMl19+eeEmJSIiGuH6De2ZM2di1apVaG5uRjwexyOPPAK/34+pU6f2evuzzjqrEDMSERERBvhM\n+4YbbsBll12Gk08+GQCg6zquu+46jBo1qhizERER0X76De25c+fif//3f/H+++8jnU5jzpw5qKmp\nKdZsREREtJ8BT65SVlaGhQsXFmMWIiIi6seQfjUnERERFR9Dm4iIyCMY2kRERB7B0CYiIvIIhjYR\nEZFHOPrVnIXy6quv4r777sOmTZvQ0dGBqqoqzJs3D1dccQVmzpzZfbtdu3bhlltuwV/+8hcopXDi\niSfiRz/6EWpra12cnoiIqLgcr7Tvu+8+nHPOOX1ef+655+KBBx4Y1IN3dHRgzpw5uPHGG7FixQr8\nv//3/7Bx40acffbZ3adKTSaT+Pa3v43NmzfjP/7jP3Drrbdi27ZtuOCCC5BIJAb1eERERF7meKX9\n7LPP4vjjj+/z+rlz5+KZZ57BRRdd5PjBlyxZgiVLlhxw2dFHH43TTjsNL774Ii6++GI88cQT2LFj\nB1544QVMmTIFADB79mx89atfxeOPPz6oxyMiIvIyxyvt7du3Y8aMGX1eP336dGzfvn3YA1VWVgKw\nT5kKAGvWrMHcuXO7AxsAJk/V3cBaAAAgAElEQVSejGOOOQarV68e9uONBEopiOyfXqKUgibcnmLw\nrOzz7LnnG8pzMwOALgQ8+DJB2lKQHnu+lVKwpMKW1gxM6a3ZDxWOQ1sIgVgs1uf1HR0dkFIOaQjL\nspDJZLB161bcdNNNGDduXPcKfOPGjZg1a1aPn5k5cyY2btw4pMcbSaRSSJsKLQkTScPeKJf6hlkp\ne2MWSyugtEftQSmFREZiU6uBlOmNjbJSClIqtKck2lMSliz910iOAFAV1lAV1iCyf/cCDcCOjgz2\nxE1ID7wnAcDKvkY+ak5jT8LCB7tS2N1leGL2Q4njenzWrFl48cUXcckll0DTDsx6y7Lw4osv4rDD\nDhvSEGeddRbWr18PAJgyZQoeeughjBkzBoC9M1BRUdHjZ0aNGtXvTsRIZwcfsDcb1gDQlZFIGkBF\nSINPs3fESo1UChlLoaHDRNL0zsYg93ynTGXvZ0iFja0GKkMaast9EALQSuz5VsqeNZ6RaE1K5BZO\ne5MSEb9Amb80XyM5Pg3w6wJCCFToQDSgoTVpIZ5RJb2vF9DQ/f7bE7fQnrRQW+FHNKCV3GsEsMPa\nlAqb2wzE0vsWZpYCtnWYaOqyMKMqgGiAX0YqBsfP8nnnnYf169fjiiuuwKZNm7pXbBs3bsSVV16J\nDRs24B//8R+HNMRtt92GJ554AnfccQfKyspw0UUXoaGhYUj3NdLlVqkdKQsNHUZ3YOdYCmhLSsTS\nsqT28HO1W2Onib+2GJ4KbKkUUqZC0uwZFu0piU/3ZtCWtErq+ZZKwZAKuzpN7E3sC+ychKGwNymR\nNmXJzJyjCSDkFwj4tAN2KnRNYFzUh5pyHwJ66a26fQKI+PbtaOQYEtjWbmB7uwGjhCrz3HtyZ8zE\nh03pAwI7RyogaSqs35PGJlbmReF4pX3GGWdgw4YNePDBB7FmzRr4fPaPmqYJpRQuuOACfOMb3xjS\nELnPyufOnYsvfelLWLRoEe69917cfPPNqKio6HVF3dcKfCTbvwo3B/ikIm0qZEwL0YCGsN++zI1V\nVW6115GU2NVlwvLQe14pBcNSyAzwXEsFNHZaaElITBrlQ8jn3qrb3tkGWpIWujL9P9lSAe1phYCm\nUBHUoAl3V94CQMAnoA9woEPQJ1Bb7kNXtkFQLn/KogEIOvg378pIfL43jbERHePKfHbd79LzbUmF\nWFpiS1sGhoNPPZUCWhIWWpMW6kb5MD7qK+mWxssG9T3ta6+9Fn/7t3+LZ599Ftu2bQMATJ06FV//\n+tdRX1+fl4EqKipQV1fXfVDbzJkz8de//rXH7TZt2nTAd7lHMpndEO+ND65SVnC3Ms9V4Ts6TKQ8\ntLLuUYU7lLYUNrUaGBXUUFvhg1bEyryvKtyJjMxW5j6BsoA7QbJ/Fe6EEALlQd2uzBP2Doobr7D9\nq3AnFIA9CQvtKQu15dnKvIhHY0ppNzAHV+FOKNjhvX2/yryMlXneDfrkKvX19XkL6N7s3bsXW7Zs\nwemnnw4AWLRoEW699Vbs2LEDkydPBgA0NDTgvffew9VXX12wObwgtyGOpSx0pOSQN0q5yjyoC5SH\ntILv4ed2MnZ1mmhLDe3gRbfk2ozhNAIdaYnOvRlMiOqoiuhFeb4NS2FvwkLGGvr9JEyFlKVQERAI\nDCJAh0MT9up6qDs3mhAYG/WhIqSwJ27CsIqz6vYJ2BX9EOc2JLCtw0A0oGFihR8+rbA7eLkd0Z0x\nE01d5rCeo9wO7Se70xgd1jGl0g+/zlV3vrh6RrRly5bhyCOPxOzZs1FWVoatW7fiwQcfhK7r3d+/\nPvvss/Hoo4/iX/7lX3DllVdCCIH//u//RnV1db8neznUDaYKdyptKaTjFsoKVJnndjLas1W4lz7+\nclqFOyUVsKvLQmtSYlKFDyF//jfKuQ1xq4Mq3KlcZe7XFEYVsDJ3WoU7FdDtyjxuKLQkrIJV5poA\ngnr+/i3jGYm/7k1jTETPVs75f74tqdCRtrC1zXBUhTslYb/22lKszPOpz9C+7rrrIITAv/3bv0HX\ndVx33XUD3pkQAj/72c8cP/jcuXPxwgsv4IEHHoBhGKiursb8+fPx3e9+F5MmTQIARCIRPPTQQ7jl\nllvwgx/8AEopnHDCCfjRj36EaDTq+LEOFTK7IW4ZZBU+GLnKvDyowZenDZCUCmlLoSHmvSrcUvYx\nAIWYOm0pbGozUBHUMDFPlXlu56grnf1MNz+jHsDYrzKPBvK7wzHYKtwpIQTKAgIRv0Bb0kJnOr//\npkEd0AsQqgrA3v0q87Jgfo4yt3JVeKuBznztjR7k4Mp8+ugAyoOszIdDqD4ODT388MMhhMCHH36I\nQCCAww8/fOA7EwKffPJJ3ofMp4aGBixevBirV6/u3jHwgu4DtrJVeLEEdIGKoDbkPfxcFd7YaaJ9\nBFbhg6EJDLsyz1Xhe+JWXldN/dEEUB4QCA4zaIdbhQ9WJvc8WcML7+FW4YMV9WuYOMoHnza05yrX\nwOyIGWjuGsbnJUOgCWB0SMfMMQHHP5PbZl95xyOoHFc96Mc8b37doH+mlPW50v7000/7/TsVT+4r\nRS3x4h9dncl+FhoNaIgMojLP7WS0JS00dVmeq8Izlipa6OXkKvOWbGUeHkRlntsQtyQsxI3iPtlS\nAR3DqMzzXYU7ZVfm+pAr83xX4U7FDYnP92YwJqJjwiArc/sEKRa2tee3Cncq93FNMf12bf9n6vRa\nqLv6mTb1TyoFKe0TpLhdKcczEqlsZe4fYFWRW6GyCh+ajGUfveukMs/tHHWmJdoKVIU7lavMw9mj\nzJ2EmV8DfEU6qK03Q63MC1WFD0ZLwkKHw8o8V4VvajXQVaAq3CnvbBFKE0O7BO07YMsa9NcuCslS\n9slC+qrMWYXnVywt0bnHPsp8TLRnZe5GFe5E0rSfy/Jg35W5JuzvU5fKgUmaEBgT8aE8qLA3biHT\nR2Ve7Cp8IKYEtncYiPgFJlX47cp8v8aiuwrvMNAcL+4KlwpjUKH9zjvv4LHHHsPWrVvR0dHR40xJ\nQgi8/PLLeR1wJMmFdcqQaElYJRUg++utMvdeFa4ACNeqcKcUgKa4hdbUvsoc2Hcyi2JX4U5J7KvM\nK4Ja96rUrSrcqYAuUFOu22eE268yd6sKdyphKHzesq8yh7BfI+0pC1vbjbx9w4Tc5zi0H330Ufz0\npz9FIBDAtGnTUFNTU8i5RqTOtETCkJ6plOPZo8ztwJZIl+peRi+kAkyphn0QUrHkKvPKoIayoDas\n7+UXkyGBlqREVVhDWC/MUeH5JoRANCAQ9gs0d9rfWXa7CncqV5lXBHW0paTrVTjln+PQvu+++zBn\nzhzcf//93b8+k/KrM11aNacTUsGztVvGQzsZOZ0ZCY/s0x1AKm8E9v40IRDyCc+9J00JNMSGd4IU\nKl2OvzDX3t6Ob37zmwxsIiIilzgO7cMPPxwtLS2FnIWIiIj64Ti0v/e97+Gxxx7D559/Xsh5iIiI\nqA+OP9NesGABfvKTn+Cb3/wm5s2bh9raWmjagZk/2NOYEhERkXOOQ/vdd9/FtddeC9M08fbbb/d6\nG4Y2ERFR4TgO7X//939HKBTCf/7nf+KYY45BeXl5IeciIiKigzgO7U2bNuHKK6/El7/85ULOQ0RE\nRH1wfCBadfXgf7sKERER5Y/j0P7Wt76Fp556CqlUqpDzEBERUR8c1+NlZWUIhUL42te+hm984xuo\nra2Frus9bvf3f//3eR2QiIiIbI5D+9prr+3+37/85S97vY0QgqFNRERUII5D++GHHy7kHERERDQA\nx6F9/PHHF3IOIiIiGoDjA9EO1traitbW1nzOQkRERP1wvNIGgKamJtxxxx145ZVXEI/HAQDRaBSL\nFi3CVVddxd+xTUREVECOQ7uhoQHnnHMOWlpaUF9fj5kzZwIANm7ciGeeeQavv/46fve732HSpEkF\nG5aIiGgkcxzad955J+LxOB544AGccMIJB1y3du1aLF26FP/1X/+F22+/Pe9DEhER0SA+037jjTdw\n/vnn9whsAJg/fz7OO+88/OUvf8nrcERERLSP49Du7OzExIkT+7y+trYWXV1deRmKiIiIenIc2pMm\nTcJrr73W5/WvvfZav6FOREREw+M4tM844wysWbMG119/PbZv3959+fbt23HjjTfiT3/6E77xjW8U\nZEgiIiIaxIFo//zP/4xPPvkETz31FJ5++mn4/X4AgGEYUErh1FNPxSWXXFKwQYmIiEY6x6Ht8/lw\n11134dVXX8Xq1avR0NAAAJg8eTIWL16Mk046qWBDEhER0SBPrgIACxcuxMKFCwsxCxEREfXD8Wfa\nixcvxurVq/u8/pVXXsHixYvzMhQRERH15Di0d+7ciUQi0ef1yWQSjY2NeRlqpFFKobHTwMe709gR\nM2BK5fZIjuTm3taeQWvShFTemFsqhZaEib0JE0nDgvLI3AJAQBdujzFoQV1gfFRHxK9B89D4llQI\n6AIhXcArYyul0Jo0sbU9g70J77wnyblB1+N92bVrFyKRSL7ubsToykh8sCuJWFrCUkBHSiKWzqA6\nqqMqrEOI0txcxNIWNrYaMKSCzM7dmZYYF/Uh4h/y76EpKKUU4obE3oQFpQAFoCujkDQtlAd0+Es4\nEP2aHdil+nrojSaA6jIdo8N6d+iFfQKGBDJW6YaJVAoZ035dCyHg0wFds2c2pNvT9S1pSDTETGSy\n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\ntxTtSDscDlNaWioj8wbdrmkLIYQQVmWRecpCCCGEkKYthBBCWIQ0bSGEEMIipGkLIYQQFiFNWwgh\nhLAIadpCCCGERUjTFkIIISxCmrYQQghhEdK0hRBCCIuQa8LFQGlpKU899RSFhYUUFRXh9/vlurvt\nWLt2LWvWrKGwsJCDBw+SmZnJhRdeyM0330xiYqLZ5cWdjz76iKeeeort27dTWVmJz+dj9OjRzJo1\niyFDhphdniXccMMNbNy4kZkzZ/LrX//a7HLizqZNm7juuuuOWZ6UlMRnn31mQkXdlzTtGCguLuad\nd94hNzeXMWPGsHHjRrNLimvLly8nMzOTX//612RkZPD111/z+OOPs2nTJl599VVUVQKi5iorK8nN\nzeWaa67B5/NRUlLCU089xU9+8hP++te/0qdPH7NLjGurV69m69atZpdhCf/93//NyJEjm36X72+I\nPWnaMTB27Fg+/vhjAF577TVp2sexdOlSfD5f0+8FBQWkpqZy5513smnTJs4880wTq4s/l156KZde\nemmLZXl5eVx88cW8++67XH/99SZVFv8qKytZtGgRCxYsYO7cuWaXE/cGDx7MqFGjzC6jW5MhSwzI\nyLBjmjfsRo1H9/v37491OZaUmpoKyEjoeJYsWcIpp5xyzEGPEPFKRtrCEj799FMgcqQvWqdpGpqm\nUVJSwgMPPEBaWpo0o3Z89tlnrFq1ijfftOq32sfevHnzOHz4MMnJyYwfP565c+eSlZVldlndijRt\nEff279/Po48+yllnndXifJpo6aqrruI///kPAP379+f555+nZ8+eJlcVn4LBIHfffTfXX389gwYN\nMrucuJeUlMT111/P2LFjSUxM5Ouvv2bZsmV8+umnrFq1Sl5nMSRNW8S12tpabrnlFmw2G4sWLTK7\nnLi2ePFiampq2L17N8uXL2fGjBm8/PLL8imFVjz99NP4/X5uueUWs0uxhBEjRjBixIim3wsKChg7\ndixXXXUVK1askBn3MSQnW0Xc8vv9zJw5kz179vDMM8+QkZFhdklxbfDgweTn53PppZfy3HPPUVdX\nx5NPPml2WXGnpKSEpUuXMmfOHILBIFVVVVRVVQE0/a5pmslVxr/c3FwGDBhAYWGh2aV0KzLSFnEp\nFAoxe/ZsCgsLefbZZ8nJyTG7JEtJTk6mX79+fPfdd2aXEnd2795NIBDg9ttvP+a25cuXs3z5clat\n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\n/fcf8xEnwzC48847WblyZYebdmVlJevXr+f8889vtels2LCB1atXc+DAAdLT09vdVt++fQHYtm1b\ni8gbIgcdzdfpKgMHDgQio+PMzMyT3t6rr75KaWkps2fPBmD//v0ATY/P7XaTmppKaWnpSd+XEN2F\nNG3xvaZpGm+99RajRo1i6tSpra7z1ltvsWbNGu66664OfW559erVBINBfv7zn3PWWWcdc3u/fv14\n8803WbVqFTfddBMAXq+XysrKY9adOHEiDzzwAMuXL+eMM85oGi3v3LmTd999l9GjR+Pz+aKu7URc\neOGFLFmyhD/96U+cccYZuN3uptsMw4jqvHaj8vJyHnzwQRYtWoTX6wUgLS0NgG+//Zbc3FwOHjzI\noUOHmpYLIY5PzmmL77WPPvqIsrKyNmNxiDSrqqqqqM8/N1q5ciWpqakUFBS0evuIESPIzs5u8VGr\nvLw8vvnmGx577DFWr17NmjVrgMiEs+nTp7Nx40amTZvGihUrePTRR/nZz36G3W7nt7/9bYdqOxFZ\nWVnMmzePzZs3c/nll/P444/zl7/8hQcffJALLrigQ9tatGgRY8aM4fzzz29alp+fT3Z2NvPnz+el\nl15izpw5eL1efvjDH3byIxHi+0tG2uJ7rfFz2O01nYkTJ2K321m5cmXU55+/+eYbCgsLueKKK1rM\n9j7aBRdcwLPPPsuXX35Jfn4+t912G4cPH+b555+nuroagEsuuQSA+fPn069fP1555RUWL16My+Vi\nzJgxzJkzh+HDh0f7kE/K9OnT6devH88++yzPPPMMhmGQmZnZoab9j3/8gw0bNjQdkDRyOp0sXbqU\ne+65hyVLljBgwACWLl1KampqZz8MIb63FMM46jJJQgghhIhLEo8LIYQQFiFNWwghhLAIadpCCCGE\nRUjTFkIIISxCmrYQQghhEdK0hRBCCIuQpi2EEEJYhDRtIYQQwiKkaQshhBAW8f8B+UgbjvwC5BsA\nAAAASUVORK5CYII=\n", - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], + "outputs": [], "source": [ "ax = sns.jointplot(np.asarray(x), np.asarray(y), kind=\"hex\", \n", " gridsize=7, size=7, stat_func=None).set_axis_labels(\"Al Atomic %\", \"Cr Atomic %\")" @@ -283,7 +212,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.4" } }, "nbformat": 4, diff --git a/docs/examples/Example Machine Learning - OQMD.ipynb b/docs/examples/Example Machine Learning - OQMD.ipynb index d9cae48..8d8b636 100644 --- a/docs/examples/Example Machine Learning - OQMD.ipynb +++ b/docs/examples/Example Machine Learning - OQMD.ipynb @@ -750,7 +750,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.4" } }, "nbformat": 4, diff --git a/docs/examples/Example Statistics - MDF Datasets.ipynb b/docs/examples/Example Statistics - MDF Datasets.ipynb index da0310d..e4ac592 100644 --- a/docs/examples/Example Statistics - MDF Datasets.ipynb +++ b/docs/examples/Example Statistics - MDF Datasets.ipynb @@ -10,7 +10,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -21,7 +21,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -30,203 +30,26 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 1280/1280 [06:45<00:00, 3.16it/s]\n" - ] - } - ], + "outputs": [], "source": [ "# First, let's search for all the datasets. There are less than 10,000 currently, so `search()` will work fine.\n", "res = mdf.search(\"mdf.resource_type:dataset\", advanced=True)\n", "# Now, let's pull out the source_name, title, and number of records for each dataset.\n", "mdf_resources = []\n", "for r in tqdm(res):\n", - " q = \"mdf.links.parent_id:\" + r[\"mdf\"][\"mdf_id\"]\n", + " q = \"mdf.parent_id:\" + r[\"mdf\"][\"mdf_id\"]\n", " x, info = mdf.search(q, advanced=True, info=True, limit=0)\n", - " mdf_resources.append((r['mdf']['source_name'], r['mdf']['title'], info[\"total_query_matches\"]))\n", - "df = pd.DataFrame(mdf_resources, columns=['source_name','title', 'num_records'])" + " mdf_resources.append((r['mdf']['source_name'], r['dc'][\"titles\"][0]['title'], info[\"total_query_matches\"]))\n", + "df = pd.DataFrame(mdf_resources, columns=['source_name', 'title', 'num_records'])" ] }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of data resources: 1280\n" - ] - }, - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - " \n", - "
source_nametitlenum_records
430chembl_dbChEMBL Database1727112
411oqmdThe Open Quantum Materials Database686999
8codCrystallography Open Database373631
1015dss_toxDistributed Structure-Searchable Toxicity (DSS...162371
1012gdb9_14Quantum Chemistry Structures and Properties of...139980
831h2o_13Machine-learning approach for one- and two-bod...45482
180nist_xps_dbNIST X-ray Photoelectron Spectroscopy Database29189
830gdb8_15Electronic spectra from TDDFT and machine lear...21786
426amcsThe American Mineralogist Crystal Structure Da...19540
31ecp_sar_environmentsPrediction of Compounds in Different Local SAR...10914
827ft_icr_msAssigned formula of complex mixture FT-ICR MS ...10656
2w_14Accuracy and transferability of Gaussian appro...9693
7activity_cliffsKnowledge base of two- and three-dimensional a...7606
1011gdb7_13Machine learning of molecular electronic prope...7210
413gdb7_12Fast and Accurate Modeling of Molecular Atomiz...7163
\n", - "
" - ], - "text/plain": [ - " source_name title \\\n", - "430 chembl_db ChEMBL Database \n", - "411 oqmd The Open Quantum Materials Database \n", - "8 cod Crystallography Open Database \n", - "1015 dss_tox Distributed Structure-Searchable Toxicity (DSS... \n", - "1012 gdb9_14 Quantum Chemistry Structures and Properties of... \n", - "831 h2o_13 Machine-learning approach for one- and two-bod... \n", - "180 nist_xps_db NIST X-ray Photoelectron Spectroscopy Database \n", - "830 gdb8_15 Electronic spectra from TDDFT and machine lear... \n", - "426 amcs The American Mineralogist Crystal Structure Da... \n", - "31 ecp_sar_environments Prediction of Compounds in Different Local SAR... \n", - "827 ft_icr_ms Assigned formula of complex mixture FT-ICR MS ... \n", - "2 w_14 Accuracy and transferability of Gaussian appro... \n", - "7 activity_cliffs Knowledge base of two- and three-dimensional a... \n", - "1011 gdb7_13 Machine learning of molecular electronic prope... \n", - "413 gdb7_12 Fast and Accurate Modeling of Molecular Atomiz... \n", - "\n", - " num_records \n", - "430 1727112 \n", - "411 686999 \n", - "8 373631 \n", - "1015 162371 \n", - "1012 139980 \n", - "831 45482 \n", - "180 29189 \n", - "830 21786 \n", - "426 19540 \n", - "31 10914 \n", - "827 10656 \n", - "2 9693 \n", - "7 7606 \n", - "1011 7210 \n", - "413 7163 " - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# Finally, we can print the data we gathered.\n", "print(\"Number of data resources: {n_datasets}\".format(n_datasets=len(df)))\n", @@ -235,20 +58,9 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "3325791" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# Bonus: How many records are in MDF in total?\n", "df[\"num_records\"].sum()" @@ -278,7 +90,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.4" } }, "nbformat": 4, diff --git a/docs/tutorials/1 - Introduction.ipynb b/docs/tutorials/1 - Introduction.ipynb index 021ae52..6f6146a 100644 --- a/docs/tutorials/1 - Introduction.ipynb +++ b/docs/tutorials/1 - Introduction.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -19,7 +19,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -47,34 +47,11 @@ }, { "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'collection': 'NIST Interatomic Potentials',\n", - " 'composition': 'Al',\n", - " 'elements': ['Al'],\n", - " 'ingest_date': '2017-08-23T14:13:49.597984Z',\n", - " 'links': {'landing_page': 'https://www.ctcms.nist.gov/potentials/#49',\n", - " 'parent_id': '599d8d9cf2c0040951639aee',\n", - " 'publication': ['www.ctcms.nist.gov/potentials/Download/Al-LEA/NEWAl.txt',\n", - " 'www.ctcms.nist.gov/potentials/Download/Al-LEA/Al-LEA.eam.alloy']},\n", - " 'mdf_id': '599d8d9df2c0040951639b1f',\n", - " 'metadata_version': '0.3.2',\n", - " 'raw': '{\"key\": \"8f71b887-b4c5-42c0-b06c-9456153725d9\", \"id\": \"2004--Liu-X-Y--Al\", \"record-version\": \"slurp-error\", \"description\": {\"local\": [], \"citation\": [{\"DOI\": \"10.1088/0965-0393/12/4/007\", \"text-bibliography\": \"X.-Y. Liu, F. Ercolessi, and J.B. Adams, \\\\\"Aluminium interatomic potential from density functional theory calculations with improved stacking fault energy,\\\\\" Modelling Simul. Mater. Sci. Eng. 12, 665-670 (2004).\"}], \"notes\": [{\"text\": \"NEWAl.txt was obtained from http://enpub.fulton.asu.edu/cms/potentials/main/main.htm and posted with the permission of J.B. Adams. Al-LEA.eam.alloy is a version of the same potential which has been formatted for use in LAMMPS (\\\\\"D\\\\\" was replaced by \\\\\"e\\\\\", \\\\\"FCC\\\\\" by \\\\\"fcc\\\\\", and \\\\\"Al\\\\\" was added on line 3).\"}]}, \"keyword\": [], \"implementation\": [{\"type\": \"EAM\", \"notes\": [{}], \"artifact\": [{\"web-link\": {\"URL\": \"www.ctcms.nist.gov/potentials/Download/Al-LEA/NEWAl.txt\", \"link-text\": \"NEWAl.txt\"}}]}, {\"type\": \"EAM setfl\", \"notes\": [{}], \"artifact\": [{\"web-link\": {\"URL\": \"www.ctcms.nist.gov/potentials/Download/Al-LEA/Al-LEA.eam.alloy\", \"link-text\": \"Al-LEA.eam.alloy\"}}]}], \"element\": [\"Al\"], \"fictional-element\": [], \"other-element\": []}',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 49,\n", - " 'source_name': 'nist_ip',\n", - " 'title': 'NIST Interatomic Potential - NEWAl.txt, Al-LEA.eam.alloy'}}" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], "source": [ "res = mdf.search(\"Al\")\n", "res[0]" @@ -94,37 +71,13 @@ }, { "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'collection': 'SLUSCHI',\n", - " 'composition': 'Al104',\n", - " 'elements': ['Al'],\n", - " 'ingest_date': '2017-08-04T19:56:23.221883Z',\n", - " 'links': {'landing_page': 'http://blogs.brown.edu/qhong/?page_id=102#330',\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/sluschi/sluschi/Dir_CoexRun/1200/1200/1000/anal/OUTCAR'},\n", - " 'parent_id': '5984ce6bf2c004385fd54cd4'},\n", - " 'mdf_id': '5984d167f2c004385fd54e1e',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 330,\n", - " 'source_name': 'sluschi',\n", - " 'tags': ['outcar'],\n", - " 'title': 'SLUSCHI - Al104'}}" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "execution_count": null, + "metadata": { + "scrolled": true + }, + "outputs": [], "source": [ - "res = mdf.search(\"mdf.elements:Al\", advanced=True, limit=10)\n", + "res = mdf.search(\"material.elements:Al\", advanced=True, limit=10)\n", "res[0]" ] }, @@ -137,50 +90,13 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'citation': [\"A.P. Bento, A. Gaulton, A. Hersey, L.J. Bellis, J. Chambers, M. Davies, F.A. Krüger, Y. Light, L. Mak, S. McGlinchey, M. Nowotka, G. Papadatos, R. Santos and J.P. Overington (2014) 'The ChEMBL bioactivity database: an update.' Nucleic Acids Res., 42 1083-1090. DOI: 10.1093/nar/gkt1031 PMID: 24214965\",\n", - " \"M. Davies, M. Nowotka, G. Papadatos, F. Atkinson, G.J.P. van Westen, N Dedman, R. Ochoa and J.P. Overington (2014) 'myChEMBL: A Virtual Platform for Distributing Cheminformatics Tools and Open Data' Challenges 5 (334-337) DOI: 10.3390/challe5020334\",\n", - " 'S. Jupp, J. Malone, J. Bolleman, M. Brandizi, M. Davies, L. Garcia, A. Gaulton, S. Gehant, C. Laibe, N. Redaschi, S.M Wimalaratne, M. Martin, N. Le Novère, H. Parkinson, E. Birney and A.M Jenkinson (2014) The EBI RDF Platform: Linked Open Data for the Life Sciences Bioinformatics 30 1338-1339 DOI: 10.1093/bioinformatics/btt765 PMID: 24413672'],\n", - " 'collection': 'ChEMBL db',\n", - " 'data_contact': {'email': 'jpo@ebi.ac.uk',\n", - " 'family_name': 'Overington',\n", - " 'full_name': 'John P. Overington',\n", - " 'given_name': 'John P.',\n", - " 'institution': 'European Molecular Biology Laboratory European Bioinformatics Institute'},\n", - " 'data_contributor': [{'email': 'dep78@uchicago.edu',\n", - " 'family_name': 'Pike',\n", - " 'full_name': 'Evan Pike',\n", - " 'github': 'dep78',\n", - " 'given_name': 'Evan',\n", - " 'institution': 'The University of Chicago'}],\n", - " 'description': 'ChEMBL is a database of bioactive drug-like small molecules, it contains 2-D structures, calculated properties (e.g. logP, Molecular Weight, Lipinski Parameters, etc.) and abstracted bioactivities (e.g. binding constants, pharmacology and ADMET data).vThe data is abstracted and curated from the primary scientific literature, and cover a significant fraction of the SAR and discovery of modern drugs We attempt to normalise the bioactivities into a uniform set of end-points and units where possible, and also to tag the links between a molecular target and a published assay with a set of varying confidence levels. Additional data on clinical progress of compounds is being integrated into ChEMBL at the current time.',\n", - " 'ingest_date': '2017-08-09T17:26:54.157428Z',\n", - " 'license': 'https://creativecommons.org/licenses/by-sa/3.0/',\n", - " 'links': {'data_doi': 'ftp://ftp.ebi.ac.uk/pub/databases/chembl/ChEMBLdb/',\n", - " 'landing_page': 'https://www.ebi.ac.uk/chembl/downloads'},\n", - " 'mdf_id': '598b45debf9d988c07667735',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'dataset',\n", - " 'source_name': 'chembl_db',\n", - " 'tags': ['SAR'],\n", - " 'title': 'ChEMBL Database',\n", - " 'year': 2017}}" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "res = mdf.search('mdf.title:\"ChEMBL Database\"', advanced=True)\n", + "res = mdf.search('dc.titles.title:\"ChEMBL Database\"', advanced=True)\n", "res[0]" ] }, @@ -208,7 +124,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.4" } }, "nbformat": 4, diff --git a/docs/tutorials/2 - Core Query Builder Functions.ipynb b/docs/tutorials/2 - Core Query Builder Functions.ipynb index 9d916ce..f23d0b8 100644 --- a/docs/tutorials/2 - Core Query Builder Functions.ipynb +++ b/docs/tutorials/2 - Core Query Builder Functions.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -11,7 +11,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -37,22 +37,11 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "mdf.match_field(\"mdf.elements\", \"Al\")" + "mdf.match_field(\"material.elements\", \"Al\")" ] }, { @@ -64,20 +53,9 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.match_field(\"mdf.source_name\", \"oqmd\")" ] @@ -93,45 +71,9 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'collection': 'OQMD',\n", - " 'composition': 'Al1',\n", - " 'elements': ['Al'],\n", - " 'ingest_date': '2017-08-04T14:19:36.159697Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/40083',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/43492/standard/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/43492/standard/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848278a5ea60172af4bbd3',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 9343,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - Al1'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 0.0},\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 43492},\n", - " 'magnetic_moment': {'units': 'bohr/atom'},\n", - " 'spacegroup': 225,\n", - " 'total_energy': {'units': 'eV/atom', 'value': -3.74439255},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 16.5356}}}" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "res = mdf.search(limit=10)\n", "res[0]" @@ -147,22 +89,11 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "mdf.exclude_field(\"mdf.elements\", \"Cu\")" + "mdf.exclude_field(\"material.elements\", \"Cu\")" ] }, { @@ -174,56 +105,18 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "mdf.exclude_field(\"mdf.source_name\", \"sluschi\").match_field(\"mdf.elements\", \"Al\").exclude_field(\"mdf.source_name\", \"oqmd\")" + "mdf.exclude_field(\"mdf.source_name\", \"sluschi\").match_field(\"material.elements\", \"Al\").exclude_field(\"mdf.source_name\", \"oqmd\")" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'collection': 'AMCS',\n", - " 'composition': 'Al4',\n", - " 'elements': ['Al'],\n", - " 'ingest_date': '2017-08-04T19:07:56.890584Z',\n", - " 'links': {'cif': {'http_host': 'http://rruff.geo.arizona.edu',\n", - " 'path': '/AMS/xtal_data/CIFfiles/19141.cif'},\n", - " 'dif': {'http_host': 'http://rruff.geo.arizona.edu',\n", - " 'path': '/AMS/xtal_data/DIFfiles/19141.txt'},\n", - " 'landing_page': 'http://rruff.geo.arizona.edu/AMS/minerals/Aluminum#18135',\n", - " 'parent_id': '5984c125f2c0043771d1507c'},\n", - " 'mdf_id': '5984c60cf2c0043771d19753',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 18135,\n", - " 'source_name': 'amcs',\n", - " 'tags': ['Aluminum', 'cif', 'dif'],\n", - " 'title': 'AMCS - Aluminum'}}" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "res = mdf.search(limit=10)\n", "res[0]" @@ -253,7 +146,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.4" } }, "nbformat": 4, diff --git a/docs/tutorials/3 - Expanded Query Builder Functions.ipynb b/docs/tutorials/3 - Expanded Query Builder Functions.ipynb index c153001..76b596c 100644 --- a/docs/tutorials/3 - Expanded Query Builder Functions.ipynb +++ b/docs/tutorials/3 - Expanded Query Builder Functions.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -11,7 +11,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -35,20 +35,9 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.match_range(\"oqmd.band_gap.value\", 0, 10)" ] @@ -63,327 +52,18 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.exclude_range(\"oqmd.spacegroup\", 100, 199)" ] }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'mdf': {'collection': 'OQMD',\n", - " 'composition': 'As1B1',\n", - " 'elements': ['As', 'B'],\n", - " 'ingest_date': '2017-08-04T14:18:57.869255Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/5869',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/43871/static/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/43871/static/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848251a5ea60172af49b41',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 1005,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - As1B1'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 1.416},\n", - " 'configuration': 'static',\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 43871},\n", - " 'delta_e': {'units': 'eV/atom', 'value': -0.0223691475000001},\n", - " 'magnetic_moment': {'units': 'bohr/atom'},\n", - " 'spacegroup': 216,\n", - " 'stability': {'units': 'eV/atom', 'value': 0.0775163231849894},\n", - " 'total_energy': {'units': 'eV/atom', 'value': -5.687312155},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 13.9302}}},\n", - " {'mdf': {'collection': 'OQMD',\n", - " 'composition': 'Au1Sm1',\n", - " 'elements': ['Au', 'Sm'],\n", - " 'ingest_date': '2017-08-04T14:18:57.873459Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/5875',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/58584/static/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/58584/static/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848251a5ea60172af49b42',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 1006,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - Au1Sm1'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 0.0},\n", - " 'configuration': 'static',\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 58584},\n", - " 'delta_e': {'units': 'eV/atom', 'value': -0.80073676375},\n", - " 'magnetic_moment': {'units': 'bohr/atom', 'value': 0.01266875},\n", - " 'spacegroup': 221,\n", - " 'stability': {'units': 'eV/atom', 'value': 0.03705677},\n", - " 'total_energy': {'units': 'eV/atom', 'value': -4.791521425},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 24.3595}}},\n", - " {'mdf': {'collection': 'OQMD',\n", - " 'composition': 'Ag1Er1',\n", - " 'elements': ['Er', 'Ag'],\n", - " 'ingest_date': '2017-08-04T14:18:57.907419Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/6522',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/58234/static/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/58234/static/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848251a5ea60172af49b4a',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 1014,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - Ag1Er1'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 0.0},\n", - " 'configuration': 'static',\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 58234},\n", - " 'delta_e': {'units': 'eV/atom', 'value': -0.34775013375},\n", - " 'magnetic_moment': {'units': 'bohr/atom', 'value': 0.0005443},\n", - " 'spacegroup': 221,\n", - " 'stability': {'units': 'eV/atom', 'value': 0.000802095000000003},\n", - " 'total_energy': {'units': 'eV/atom', 'value': -4.040306885},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 23.1094}}},\n", - " {'mdf': {'collection': 'OQMD',\n", - " 'composition': 'Fe1N1',\n", - " 'elements': ['Fe', 'N'],\n", - " 'ingest_date': '2017-08-04T14:18:57.932967Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/6051',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/41258/static/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/41258/static/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848251a5ea60172af49b50',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 1020,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - Fe1N1'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 0.0},\n", - " 'configuration': 'static',\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 41258},\n", - " 'delta_e': {'units': 'eV/atom', 'value': -0.228883157671754},\n", - " 'magnetic_moment': {'units': 'bohr/atom', 'value': 0.0058439},\n", - " 'spacegroup': 216,\n", - " 'stability': {'units': 'eV/atom', 'value': -0.14338019663029},\n", - " 'total_energy': {'units': 'eV/atom', 'value': -8.442702575},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 9.35959}}},\n", - " {'mdf': {'collection': 'OQMD',\n", - " 'composition': 'Au1Lu1',\n", - " 'elements': ['Lu', 'Au'],\n", - " 'ingest_date': '2017-08-04T14:18:57.949847Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/5920',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/58535/static/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/58535/static/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848251a5ea60172af49b54',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 1024,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - Au1Lu1'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 0.0},\n", - " 'configuration': 'static',\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 58535},\n", - " 'delta_e': {'units': 'eV/atom', 'value': -0.901567857499999},\n", - " 'magnetic_moment': {'units': 'bohr/atom', 'value': 1.635e-05},\n", - " 'spacegroup': 221,\n", - " 'stability': {'units': 'eV/atom', 'value': 0.000442014999999962},\n", - " 'total_energy': {'units': 'eV/atom', 'value': -4.79705949},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 21.6392}}},\n", - " {'mdf': {'collection': 'OQMD',\n", - " 'composition': 'Au1Tb1',\n", - " 'elements': ['Au', 'Tb'],\n", - " 'ingest_date': '2017-08-04T14:18:57.971204Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/5932',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/58600/static/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/58600/static/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848251a5ea60172af49b59',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 1029,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - Au1Tb1'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 0.0},\n", - " 'configuration': 'static',\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 58600},\n", - " 'delta_e': {'units': 'eV/atom', 'value': -0.524167797333335},\n", - " 'magnetic_moment': {'units': 'bohr/atom', 'value': -0.00017925},\n", - " 'spacegroup': 221,\n", - " 'stability': {'units': 'eV/atom', 'value': 0.0257228025},\n", - " 'total_energy': {'units': 'eV/atom', 'value': -4.801447045},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 23.2841}}},\n", - " {'mdf': {'collection': 'OQMD',\n", - " 'composition': 'Ge1Sb1',\n", - " 'elements': ['Sb', 'Ge'],\n", - " 'ingest_date': '2017-08-04T14:18:57.975432Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/5949',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/42472/relaxation/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/42472/relaxation/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848251a5ea60172af49b5a',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 1030,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - Ge1Sb1'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 0.0},\n", - " 'configuration': 'relaxation',\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 42472},\n", - " 'magnetic_moment': {'units': 'bohr/atom'},\n", - " 'spacegroup': 225,\n", - " 'total_energy': {'units': 'eV/atom', 'value': -4.22786394},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 24.8356}}},\n", - " {'mdf': {'collection': 'OQMD',\n", - " 'composition': 'Mn1Te1',\n", - " 'elements': ['Te', 'Mn'],\n", - " 'ingest_date': '2017-08-04T14:18:58.000782Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/6160',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/181324/static/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/181324/static/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848252a5ea60172af49b60',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 1036,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - Mn1Te1'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 0.0},\n", - " 'configuration': 'static',\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 181324},\n", - " 'delta_e': {'units': 'eV/atom', 'value': -0.0519698435632154},\n", - " 'magnetic_moment': {'units': 'bohr/atom', 'value': 2.4778259},\n", - " 'spacegroup': 216,\n", - " 'stability': {'units': 'eV/atom', 'value': 0.0416428459944419},\n", - " 'total_energy': {'units': 'eV/atom', 'value': -6.136342655},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 31.5199}}},\n", - " {'mdf': {'collection': 'OQMD',\n", - " 'composition': 'N1Os1',\n", - " 'elements': ['Os', 'N'],\n", - " 'ingest_date': '2017-08-04T14:18:58.030559Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/6329',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/167863/static/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/167863/static/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848252a5ea60172af49b67',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 1043,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - N1Os1'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 0.0},\n", - " 'configuration': 'static',\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 167863},\n", - " 'delta_e': {'units': 'eV/atom', 'value': 1.45457860732825},\n", - " 'magnetic_moment': {'units': 'bohr/atom', 'value': 0.02228575},\n", - " 'spacegroup': 225,\n", - " 'stability': {'units': 'eV/atom', 'value': 1.45457860732825},\n", - " 'total_energy': {'units': 'eV/atom', 'value': -8.218279915},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 10.2902}}},\n", - " {'mdf': {'collection': 'OQMD',\n", - " 'composition': 'C1Sc1',\n", - " 'elements': ['C', 'Sc'],\n", - " 'ingest_date': '2017-08-04T14:18:58.034756Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/6351',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/43524/static/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/43524/static/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848252a5ea60172af49b68',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 1044,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - C1Sc1'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 0.0},\n", - " 'configuration': 'static',\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 43524},\n", - " 'delta_e': {'units': 'eV/atom', 'value': -0.144528211249999},\n", - " 'magnetic_moment': {'units': 'bohr/atom', 'value': -0.00021075},\n", - " 'spacegroup': 225,\n", - " 'stability': {'units': 'eV/atom', 'value': 0.307225142393983},\n", - " 'total_energy': {'units': 'eV/atom', 'value': -7.9172498},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 12.7909}}}]" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.search(limit=10)" ] @@ -398,161 +78,11 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'mdf': {'collection': 'ChEMBL db',\n", - " 'composition': 'O',\n", - " 'elements': ['O'],\n", - " 'ingest_date': '2017-08-09T17:32:46.951874Z',\n", - " 'links': {'landing_page': 'https://www.ebi.ac.uk/chembl/downloads#32430',\n", - " 'parent_id': '598b45debf9d988c07667735',\n", - " 'sdf': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/chembl_db/chembl_sdf_data_1/CHEMBL1098659.sdf'}},\n", - " 'mdf_id': '598b473ebf9d988c1966f5e3',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 32430,\n", - " 'source_name': 'chembl_db',\n", - " 'tags': ['sdf'],\n", - " 'title': 'ChEMBL db - O'}},\n", - " {'mdf': {'collection': 'ChEMBL db',\n", - " 'composition': 'O',\n", - " 'elements': ['O'],\n", - " 'ingest_date': '2017-08-09T18:32:17.732085Z',\n", - " 'links': {'landing_page': 'https://www.ebi.ac.uk/chembl/downloads#479490',\n", - " 'parent_id': '598b45debf9d988c07667735',\n", - " 'sdf': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/chembl_db/chembl_sdf_data_3/CHEMBL1689064.sdf'}},\n", - " 'mdf_id': '598b5531bf9d988c196dc837',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 479490,\n", - " 'source_name': 'chembl_db',\n", - " 'tags': ['sdf'],\n", - " 'title': 'ChEMBL db - O'}},\n", - " {'mdf': {'collection': 'AMCS',\n", - " 'composition': 'O6',\n", - " 'elements': ['O'],\n", - " 'ingest_date': '2017-08-04T19:05:00.649235Z',\n", - " 'links': {'cif': {'http_host': 'http://rruff.geo.arizona.edu',\n", - " 'path': '/AMS/xtal_data/CIFfiles/16233.cif'},\n", - " 'dif': {'http_host': 'http://rruff.geo.arizona.edu',\n", - " 'path': '/AMS/xtal_data/DIFfiles/16233.txt'},\n", - " 'landing_page': 'http://rruff.geo.arizona.edu/AMS/minerals/Oxygen#15365',\n", - " 'parent_id': '5984c125f2c0043771d1507c'},\n", - " 'mdf_id': '5984c55cf2c0043771d18c81',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 15365,\n", - " 'source_name': 'amcs',\n", - " 'tags': ['Oxygen', 'cif', 'dif'],\n", - " 'title': 'AMCS - Oxygen'}},\n", - " {'mdf': {'collection': 'NIST',\n", - " 'composition': 'O',\n", - " 'elements': ['O'],\n", - " 'ingest_date': '2017-08-30T14:27:51.847389Z',\n", - " 'links': {'landing_page': 'http://trc.nist.gov/applications/metals_data/metals_data.php#861#5',\n", - " 'parent_id': '59a6cb67f2c0041b3d1d6376'},\n", - " 'mdf_id': '59a6cb67f2c0041b3d1d637b',\n", - " 'metadata_version': '0.4.0',\n", - " 'raw': '{\"refid\": \"861\", \"cmpid\": \"21658\"}',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 5,\n", - " 'source_name': 'nist_trc_861',\n", - " 'title': 'TRC Specimen 6658'}},\n", - " {'mdf': {'collection': 'NIST',\n", - " 'composition': 'O',\n", - " 'elements': ['O'],\n", - " 'ingest_date': '2017-08-30T14:27:51.772149Z',\n", - " 'links': {'landing_page': 'http://trc.nist.gov/applications/metals_data/metals_data.php#860#2',\n", - " 'parent_id': '59a6cb67f2c0041b3d1d6370'},\n", - " 'mdf_id': '59a6cb67f2c0041b3d1d6372',\n", - " 'metadata_version': '0.4.0',\n", - " 'raw': '{\"refid\": \"860\", \"cmpid\": \"21658\"}',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 2,\n", - " 'source_name': 'nist_trc_860',\n", - " 'title': 'TRC Specimen 6646'}},\n", - " {'mdf': {'collection': 'NIST',\n", - " 'composition': 'O',\n", - " 'elements': ['O'],\n", - " 'ingest_date': '2017-08-30T14:27:22.689552Z',\n", - " 'links': {'landing_page': 'http://trc.nist.gov/applications/metals_data/metals_data.php#111#4',\n", - " 'parent_id': '59a6cb4af2c0041b3d1d56c7'},\n", - " 'mdf_id': '59a6cb4af2c0041b3d1d56cb',\n", - " 'metadata_version': '0.4.0',\n", - " 'raw': '{\"refid\": \"111\", \"cmpid\": \"21658\"}',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 4,\n", - " 'source_name': 'nist_trc_111',\n", - " 'title': 'TRC Specimen 1513'}},\n", - " {'mdf': {'collection': 'NIST',\n", - " 'composition': 'O',\n", - " 'elements': ['O'],\n", - " 'ingest_date': '2017-08-30T14:27:58.656152Z',\n", - " 'links': {'landing_page': 'http://trc.nist.gov/applications/metals_data/metals_data.php#1184#3',\n", - " 'parent_id': '59a6cb6ef2c0041b3d1d6661'},\n", - " 'mdf_id': '59a6cb6ef2c0041b3d1d6664',\n", - " 'metadata_version': '0.4.0',\n", - " 'raw': '{\"refid\": \"1184\", \"cmpid\": \"21658\"}',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 3,\n", - " 'source_name': 'nist_trc_1184',\n", - " 'title': 'TRC Specimen 8177'}},\n", - " {'mdf': {'collection': 'NIST',\n", - " 'composition': 'O',\n", - " 'elements': ['O'],\n", - " 'ingest_date': '2017-08-30T14:27:30.033610Z',\n", - " 'links': {'landing_page': 'http://trc.nist.gov/applications/metals_data/metals_data.php#294#4',\n", - " 'parent_id': '59a6cb51f2c0041b3d1d59e1'},\n", - " 'mdf_id': '59a6cb52f2c0041b3d1d59e5',\n", - " 'metadata_version': '0.4.0',\n", - " 'raw': '{\"refid\": \"294\", \"cmpid\": \"21658\"}',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 4,\n", - " 'source_name': 'nist_trc_294',\n", - " 'title': 'TRC Specimen 2774'}},\n", - " {'mdf': {'collection': 'NIST',\n", - " 'composition': 'O',\n", - " 'elements': ['O'],\n", - " 'ingest_date': '2017-08-30T14:27:34.080206Z',\n", - " 'links': {'landing_page': 'http://trc.nist.gov/applications/metals_data/metals_data.php#385#2',\n", - " 'parent_id': '59a6cb56f2c0041b3d1d5b7a'},\n", - " 'mdf_id': '59a6cb56f2c0041b3d1d5b7c',\n", - " 'metadata_version': '0.4.0',\n", - " 'raw': '{\"refid\": \"385\", \"cmpid\": \"21658\"}',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 2,\n", - " 'source_name': 'nist_trc_385',\n", - " 'title': 'TRC Specimen 3444'}},\n", - " {'mdf': {'collection': 'NIST',\n", - " 'composition': 'O',\n", - " 'elements': ['O'],\n", - " 'ingest_date': '2017-08-30T14:27:34.224400Z',\n", - " 'links': {'landing_page': 'http://trc.nist.gov/applications/metals_data/metals_data.php#388#6',\n", - " 'parent_id': '59a6cb56f2c0041b3d1d5b87'},\n", - " 'mdf_id': '59a6cb56f2c0041b3d1d5b8d',\n", - " 'metadata_version': '0.4.0',\n", - " 'raw': '{\"refid\": \"388\", \"cmpid\": \"21658\"}',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 6,\n", - " 'source_name': 'nist_trc_388',\n", - " 'title': 'TRC Specimen 3467'}}]" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "mdf.exclusive_match(\"mdf.elements\", \"O\").search(limit=10)" + "mdf.exclusive_match(\"material.elements\", \"O\").search(limit=10)" ] }, { @@ -579,7 +109,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.4" } }, "nbformat": 4, diff --git a/docs/tutorials/4 - General Helper Functions.ipynb b/docs/tutorials/4 - General Helper Functions.ipynb index 0df3291..8b49137 100644 --- a/docs/tutorials/4 - General Helper Functions.ipynb +++ b/docs/tutorials/4 - General Helper Functions.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -11,7 +11,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -35,20 +35,9 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'(mdf.source_name:oqmd)'" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.match_field(\"mdf.source_name\", \"oqmd\")\n", "mdf.current_query()" @@ -64,7 +53,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -73,20 +62,9 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "''" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.current_query()" ] @@ -101,11 +79,11 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ - "mdf.exclude_field(\"mdf.source_name\", \"sluschi\").match_field(\"mdf.elements\", \"Al\").exclude_field(\"mdf.source_name\", \"oqmd\")\n", + "mdf.exclude_field(\"mdf.source_name\", \"sluschi\").match_field(\"material.elements\", \"Al\").exclude_field(\"mdf.source_name\", \"oqmd\")\n", "res, info = mdf.search(limit=10, info=True)" ] }, @@ -118,60 +96,18 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'collection': 'AMCS',\n", - " 'composition': 'Al4',\n", - " 'elements': ['Al'],\n", - " 'ingest_date': '2017-08-04T19:07:56.890584Z',\n", - " 'links': {'cif': {'http_host': 'http://rruff.geo.arizona.edu',\n", - " 'path': '/AMS/xtal_data/CIFfiles/19141.cif'},\n", - " 'dif': {'http_host': 'http://rruff.geo.arizona.edu',\n", - " 'path': '/AMS/xtal_data/DIFfiles/19141.txt'},\n", - " 'landing_page': 'http://rruff.geo.arizona.edu/AMS/minerals/Aluminum#18135',\n", - " 'parent_id': '5984c125f2c0043771d1507c'},\n", - " 'mdf_id': '5984c60cf2c0043771d19753',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 18135,\n", - " 'source_name': 'amcs',\n", - " 'tags': ['Aluminum', 'cif', 'dif'],\n", - " 'title': 'AMCS - Aluminum'}}" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "res[0]" ] }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'query': {'advanced': True,\n", - " 'limit': 10,\n", - " 'offset': 0,\n", - " 'q': '( NOT mdf.source_name:sluschi AND mdf.elements:Al AND NOT mdf.source_name:oqmd)'},\n", - " 'total_query_matches': 18170}" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "info" ] @@ -186,40 +122,18 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.match_field(\"mdf.source_name\", \"nist_xps_db\")" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'(mdf.source_name:nist_xps_db)'" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "res, info = mdf.search(limit=10, info=True, reset_query=False)\n", "info[\"query\"][\"q\"]" @@ -227,20 +141,9 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'(mdf.source_name:nist_xps_db)'" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "res, info = mdf.search(limit=10, info=True)\n", "info[\"query\"][\"q\"]" @@ -256,36 +159,9 @@ }, { "cell_type": "code", - "execution_count": 12, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "{'dss_tox': 'object',\n", - " 'fe_cr_al_oxidation': 'object',\n", - " 'gdb9_14': 'object',\n", - " 'header': 'object',\n", - " 'hopv': 'object',\n", - " 'jcap_xps_spectral_db': 'object',\n", - " 'md_17': 'object',\n", - " 'mdf': 'object',\n", - " 'metadata': 'object',\n", - " 'mpi_mainz': 'object',\n", - " 'natural_fiber_composite_tensile': 'object',\n", - " 'nist_janaf': 'object',\n", - " 'oqmd': 'object',\n", - " 'pppdb': 'object',\n", - " 'qm_mdt_c': 'object',\n", - " 'quinary_alloys': 'object',\n", - " 'xafs_sl': 'object'}" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.show_fields()" ] @@ -299,234 +175,11 @@ }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf.author.email': 'text',\n", - " 'mdf.author.family_name': 'text',\n", - " 'mdf.author.full_name': 'text',\n", - " 'mdf.author.given_name': 'text',\n", - " 'mdf.author.instituition': 'text',\n", - " 'mdf.author.institution': 'text',\n", - " 'mdf.author.orcid': 'text',\n", - " 'mdf.citation': 'text',\n", - " 'mdf.collection': 'text',\n", - " 'mdf.composition': 'text',\n", - " 'mdf.data_contact.email': 'text',\n", - " 'mdf.data_contact.family_name': 'text',\n", - " 'mdf.data_contact.full_name': 'text',\n", - " 'mdf.data_contact.given_name': 'text',\n", - " 'mdf.data_contact.instituition': 'text',\n", - " 'mdf.data_contact.institution': 'text',\n", - " 'mdf.data_contact.orcid': 'text',\n", - " 'mdf.data_contributor.email': 'text',\n", - " 'mdf.data_contributor.family_name': 'text',\n", - " 'mdf.data_contributor.full_name': 'text',\n", - " 'mdf.data_contributor.github': 'text',\n", - " 'mdf.data_contributor.given_name': 'text',\n", - " 'mdf.data_contributor.institution': 'text',\n", - " 'mdf.description': 'text',\n", - " 'mdf.elements': 'text',\n", - " 'mdf.ingest_date': 'date',\n", - " 'mdf.license': 'text',\n", - " 'mdf.links.DSC_data.globus_endpoint': 'text',\n", - " 'mdf.links.DSC_data.http_host': 'text',\n", - " 'mdf.links.DSC_data.path': 'text',\n", - " 'mdf.links.Neutron_data.globus_endpoint': 'text',\n", - " 'mdf.links.Neutron_data.http_host': 'text',\n", - " 'mdf.links.Neutron_data.path': 'text',\n", - " 'mdf.links.OUTCAR.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR.http_host': 'text',\n", - " 'mdf.links.OUTCAR.path': 'text',\n", - " 'mdf.links.OUTCAR_Ti3Au2C2_sg166-42atom_cut500.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_Ti3Au2C2_sg166-42atom_cut500.http_host': 'text',\n", - " 'mdf.links.OUTCAR_Ti3Au2C2_sg166-42atom_cut500.path': 'text',\n", - " 'mdf.links.OUTCAR_Ti3Au2C2_sg194_cut500.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_Ti3Au2C2_sg194_cut500.http_host': 'text',\n", - " 'mdf.links.OUTCAR_Ti3Au2C2_sg194_cut500.path': 'text',\n", - " 'mdf.links.OUTCAR_Ti3AuC2_cut500.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_Ti3AuC2_cut500.http_host': 'text',\n", - " 'mdf.links.OUTCAR_Ti3AuC2_cut500.path': 'text',\n", - " 'mdf.links.OUTCAR_bandstructure.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_bandstructure.http_host': 'text',\n", - " 'mdf.links.OUTCAR_bandstructure.path': 'text',\n", - " 'mdf.links.OUTCAR_cutoff-400eV.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_cutoff-400eV.http_host': 'text',\n", - " 'mdf.links.OUTCAR_cutoff-400eV.path': 'text',\n", - " 'mdf.links.OUTCAR_cutoff-500eV.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_cutoff-500eV.http_host': 'text',\n", - " 'mdf.links.OUTCAR_cutoff-500eV.path': 'text',\n", - " 'mdf.links.OUTCAR_normal.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_normal.http_host': 'text',\n", - " 'mdf.links.OUTCAR_normal.path': 'text',\n", - " 'mdf.links.OUTCAR_scf.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_scf.http_host': 'text',\n", - " 'mdf.links.OUTCAR_scf.path': 'text',\n", - " 'mdf.links.OUTCAR_spin-irbit-coupling.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_spin-irbit-coupling.http_host': 'text',\n", - " 'mdf.links.OUTCAR_spin-irbit-coupling.path': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling-001.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling-001.http_host': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling-001.path': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling-100.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling-100.http_host': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling-100.path': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling.http_host': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling.path': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling_001.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling_001.http_host': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling_001.path': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling_100.globus_endpoint': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling_100.http_host': 'text',\n", - " 'mdf.links.OUTCAR_spin-orbit-coupling_100.path': 'text',\n", - " 'mdf.links.SEM_images.globus_endpoint': 'text',\n", - " 'mdf.links.SEM_images.http_host': 'text',\n", - " 'mdf.links.SEM_images.path': 'text',\n", - " 'mdf.links.TEM_images_101a.globus_endpoint': 'text',\n", - " 'mdf.links.TEM_images_101a.http_host': 'text',\n", - " 'mdf.links.TEM_images_101a.path': 'text',\n", - " 'mdf.links.TEM_images_151a.globus_endpoint': 'text',\n", - " 'mdf.links.TEM_images_151a.http_host': 'text',\n", - " 'mdf.links.TEM_images_151a.path': 'text',\n", - " 'mdf.links.TEM_images_201a.globus_endpoint': 'text',\n", - " 'mdf.links.TEM_images_201a.http_host': 'text',\n", - " 'mdf.links.TEM_images_201a.path': 'text',\n", - " 'mdf.links.ThermoCalc_TCNI5.globus_endpoint': 'text',\n", - " 'mdf.links.ThermoCalc_TCNI5.http_host': 'text',\n", - " 'mdf.links.ThermoCalc_TCNI5.path': 'text',\n", - " 'mdf.links.ThermoCalc_TTNI8.globus_endpoint': 'text',\n", - " 'mdf.links.ThermoCalc_TTNI8.http_host': 'text',\n", - " 'mdf.links.ThermoCalc_TTNI8.path': 'text',\n", - " 'mdf.links.XY.globus_endpoint': 'text',\n", - " 'mdf.links.XY.http_host': 'text',\n", - " 'mdf.links.XY.path': 'text',\n", - " 'mdf.links.castep-castep.globus_endpoint': 'text',\n", - " 'mdf.links.castep-castep.http_host': 'text',\n", - " 'mdf.links.castep-castep.path': 'text',\n", - " 'mdf.links.castep-cell.globus_endpoint': 'text',\n", - " 'mdf.links.castep-cell.http_host': 'text',\n", - " 'mdf.links.castep-cell.path': 'text',\n", - " 'mdf.links.cif.globus_endpoint': 'text',\n", - " 'mdf.links.cif.http_host': 'text',\n", - " 'mdf.links.cif.path': 'text',\n", - " 'mdf.links.csv.globus_endpoint': 'text',\n", - " 'mdf.links.csv.http_host': 'text',\n", - " 'mdf.links.csv.path': 'text',\n", - " 'mdf.links.data_doi': 'text',\n", - " 'mdf.links.data_link.globus_endpoint': 'text',\n", - " 'mdf.links.data_link.path': 'text',\n", - " 'mdf.links.dataset.globus_endpoint': 'text',\n", - " 'mdf.links.dataset.path': 'text',\n", - " 'mdf.links.dif.http_host': 'text',\n", - " 'mdf.links.dif.path': 'text',\n", - " 'mdf.links.energy.globus_endpoint': 'text',\n", - " 'mdf.links.energy.http_host': 'text',\n", - " 'mdf.links.energy.path': 'text',\n", - " 'mdf.links.file.globus_endpoint': 'text',\n", - " 'mdf.links.file.path': 'text',\n", - " 'mdf.links.gro.globus_endpoint': 'text',\n", - " 'mdf.links.gro.http_host': 'text',\n", - " 'mdf.links.gro.path': 'text',\n", - " 'mdf.links.jpg.globus_endpoint': 'text',\n", - " 'mdf.links.jpg.http_host': 'text',\n", - " 'mdf.links.jpg.path': 'text',\n", - " 'mdf.links.jpg2.globus_endpoint': 'text',\n", - " 'mdf.links.jpg2.http_host': 'text',\n", - " 'mdf.links.jpg2.path': 'text',\n", - " 'mdf.links.klh.globus_endpoint': 'text',\n", - " 'mdf.links.klh.http_host': 'text',\n", - " 'mdf.links.klh.path': 'text',\n", - " 'mdf.links.landing_page': 'text',\n", - " 'mdf.links.log.globus_endpoint': 'text',\n", - " 'mdf.links.log.http_host': 'text',\n", - " 'mdf.links.log.path': 'text',\n", - " 'mdf.links.metadata.globus_endpoint': 'text',\n", - " 'mdf.links.metadata.http_host': 'text',\n", - " 'mdf.links.metadata.path': 'text',\n", - " 'mdf.links.mol2.globus_endpoint': 'text',\n", - " 'mdf.links.mol2.http_host': 'text',\n", - " 'mdf.links.mol2.path': 'text',\n", - " 'mdf.links.molecule.globus_endpoint': 'text',\n", - " 'mdf.links.molecule.http_host': 'text',\n", - " 'mdf.links.molecule.path': 'text',\n", - " 'mdf.links.mrc.globus_endpoint': 'text',\n", - " 'mdf.links.mrc.http_host': 'text',\n", - " 'mdf.links.mrc.path': 'text',\n", - " 'mdf.links.mrc2.globus_endpoint': 'text',\n", - " 'mdf.links.mrc2.http_host': 'text',\n", - " 'mdf.links.mrc2.path': 'text',\n", - " 'mdf.links.original.globus_endpoint': 'text',\n", - " 'mdf.links.original.http_host': 'text',\n", - " 'mdf.links.original.path': 'text',\n", - " 'mdf.links.outcar.globus_endpoint': 'text',\n", - " 'mdf.links.outcar.http_host': 'text',\n", - " 'mdf.links.outcar.path': 'text',\n", - " 'mdf.links.output.globus_endpoint': 'text',\n", - " 'mdf.links.output.http_host': 'text',\n", - " 'mdf.links.output.path': 'text',\n", - " 'mdf.links.parent_id': 'text',\n", - " 'mdf.links.pdb.globus_endpoint': 'text',\n", - " 'mdf.links.pdb.http_host': 'text',\n", - " 'mdf.links.pdb.path': 'text',\n", - " 'mdf.links.pdf.http_host': 'text',\n", - " 'mdf.links.pdf.path': 'text',\n", - " 'mdf.links.publication': 'text',\n", - " 'mdf.links.qe.globus_endpoint': 'text',\n", - " 'mdf.links.qe.http_host': 'text',\n", - " 'mdf.links.qe.path': 'text',\n", - " 'mdf.links.sdf.globus_endpoint': 'text',\n", - " 'mdf.links.sdf.http_host': 'text',\n", - " 'mdf.links.sdf.path': 'text',\n", - " 'mdf.links.tar.http_host': 'text',\n", - " 'mdf.links.tar.path': 'text',\n", - " 'mdf.links.tar_bz2.http_host': 'text',\n", - " 'mdf.links.tar_bz2.path': 'text',\n", - " 'mdf.links.tar_gz.http_host': 'text',\n", - " 'mdf.links.tar_gz.path': 'text',\n", - " 'mdf.links.txt.globus_endpoint': 'text',\n", - " 'mdf.links.txt.http_host': 'text',\n", - " 'mdf.links.txt.path': 'text',\n", - " 'mdf.links.vasp.globus_endpoint': 'text',\n", - " 'mdf.links.vasp.http_host': 'text',\n", - " 'mdf.links.vasp.path': 'text',\n", - " 'mdf.links.xdi.http_host': 'text',\n", - " 'mdf.links.xdi.path': 'text',\n", - " 'mdf.links.xlsx.globus_endpoint': 'text',\n", - " 'mdf.links.xlsx.http_host': 'text',\n", - " 'mdf.links.xlsx.path': 'text',\n", - " 'mdf.links.xslx.http_host': 'text',\n", - " 'mdf.links.xslx.path': 'text',\n", - " 'mdf.links.xye.globus_endpoint': 'text',\n", - " 'mdf.links.xye.http_host': 'text',\n", - " 'mdf.links.xye.path': 'text',\n", - " 'mdf.links.xyz.globus_endpoint': 'text',\n", - " 'mdf.links.xyz.http_host': 'text',\n", - " 'mdf.links.xyz.path': 'text',\n", - " 'mdf.links.zip.http_host': 'text',\n", - " 'mdf.links.zip.path': 'text',\n", - " 'mdf.mdf_id': 'text',\n", - " 'mdf.metadata_version': 'text',\n", - " 'mdf.raw': 'text',\n", - " 'mdf.repository': 'text',\n", - " 'mdf.resource_type': 'text',\n", - " 'mdf.scroll_id': 'long',\n", - " 'mdf.source_name': 'text',\n", - " 'mdf.tags': 'text',\n", - " 'mdf.title': 'text',\n", - " 'mdf.year': 'long'}" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.show_fields(\"mdf\")" ] @@ -548,62 +201,22 @@ }, { "cell_type": "code", - "execution_count": 14, - "metadata": {}, + "execution_count": null, + "metadata": { + "collapsed": true + }, "outputs": [], "source": [ - "records = mdf.search(\"mdf.tags:outcar AND mdf.resource_type:record\")" + "records = mdf.search(\"dft.converged:true AND mdf.resource_type:record\")" ] }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'author': [{'email': 'gibbons.dayna@epa.gov',\n", - " 'family_name': 'Gibbons',\n", - " 'full_name': 'Dayna Gibbons',\n", - " 'given_name': 'Dayna',\n", - " 'institution': 'US EPA Research'}],\n", - " 'citation': ['Richard, A M. AND C. R. Williams. DISTRIBUTED STRUCTURE-SEARCHABLE TOXICITY (DSSTOX) PUBLIC DATABASE NETWORK: A PROPOSAL. MUTATION RESEARCH NEW FRONTIERS ISSUE 499(1):27-52, (2001).'],\n", - " 'collection': 'DSS Tox',\n", - " 'data_contact': {'email': 'gibbons.dayna@epa.gov',\n", - " 'family_name': 'Gibbons',\n", - " 'full_name': 'Dayna Gibbons',\n", - " 'given_name': 'Dayna',\n", - " 'institution': 'US EPA Research'},\n", - " 'data_contributor': [{'email': 'dep78@uchicago.edu',\n", - " 'family_name': 'Pike',\n", - " 'full_name': 'Evan Pike',\n", - " 'github': 'dep78',\n", - " 'given_name': 'Evan',\n", - " 'institution': 'The University of Chicago'}],\n", - " 'description': 'DSSTox provides a high quality public chemistry resource for supporting improved predictive toxicology. A distinguishing feature of this effort is the accurate mapping of bioassay and physicochemical property data associated with chemical substances to their corresponding chemical structures.',\n", - " 'ingest_date': '2017-08-09T17:29:37.655346Z',\n", - " 'links': {'landing_page': 'https://www.epa.gov/chemical-research/distributed-structure-searchable-toxicity-dsstox-database',\n", - " 'publication': ['http://cfpub.epa.gov/si/si_lab_search_results.cfm?SIType=PR&TIMSType=Journal&showCriteria=0&view=citation&sortBy=pubDateYear&keyword=DssTox',\n", - " 'https://www.epa.gov/chemical-research/toxicity-forecasting',\n", - " 'https://www.epa.gov/chemical-research/toxicology-testing-21st-century-tox21',\n", - " 'http://actor.epa.gov/dashboard/',\n", - " 'https://www.epa.gov/chemical-research/chemistry-dashboard']},\n", - " 'mdf_id': '598b4681bf9d988c4c3c151c',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'dataset',\n", - " 'source_name': 'dss_tox',\n", - " 'title': 'Distributed Structure-Searchable Toxicity (DSSTox) Database',\n", - " 'year': 2016}}" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "res = mdf.fetch_datasets_from_results(records)\n", "res[0]" @@ -618,59 +231,13 @@ }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'author': [{'email': 'qhong@alumni.caltech.edu',\n", - " 'family_name': 'Hong',\n", - " 'full_name': 'Qi-Jun Hong',\n", - " 'given_name': 'Qi-Jun',\n", - " 'institution': 'Brown University'},\n", - " {'email': 'avdw@alum.mit.edu',\n", - " 'family_name': 'van de Walle',\n", - " 'full_name': 'Axel van de Walle',\n", - " 'given_name': 'Axel',\n", - " 'institution': 'Brown University'}],\n", - " 'citation': ['Qi-Jun Hong, Axel van de Walle, A user guide for SLUSCHI: Solid and Liquid in Ultra Small Coexistence with Hovering Interfaces, Calphad, Volume 52, March 2016, Pages 88-97, ISSN 0364-5916, http://doi.org/10.1016/j.calphad.2015.12.003.'],\n", - " 'collection': 'SLUSCHI',\n", - " 'data_contact': {'email': 'qhong@alumni.caltech.edu',\n", - " 'family_name': 'Hong',\n", - " 'full_name': 'Qi-Jun Hong',\n", - " 'given_name': 'Qi-Jun',\n", - " 'institution': 'Brown University'},\n", - " 'data_contributor': [{'email': 'jgaff@uchicago.edu',\n", - " 'family_name': 'Gaff',\n", - " 'full_name': 'Jonathon Gaff',\n", - " 'github': 'jgaff',\n", - " 'given_name': 'Jonathon',\n", - " 'institution': 'The University of Chicago'}],\n", - " 'description': 'Although various approaches for melting point calculations from first principles have been proposed and employed for years, their practical implementation has hitherto remained a complex and time-consuming process. The SLUSCHI code (Solid and Liquid in Ultra Small Coexistence with Hovering Interfaces) drastically simplifies this procedure into an automated package, by implementing the recently-developed small-size coexistence method and putting together a series of steps that lead to final melting point evaluation. Based on density functional theory, SLUSCHI employs Born–Oppenheimer molecular dynamics techniques under the isobaric–isothermal (NPT) ensemble, with interface to the first-principles code VASP.',\n", - " 'ingest_date': '2017-08-04T19:43:39.345950Z',\n", - " 'links': {'landing_page': 'http://blogs.brown.edu/qhong/?page_id=102',\n", - " 'publication': ['https://doi.org/10.1016/j.calphad.2015.12.003']},\n", - " 'mdf_id': '5984ce6bf2c004385fd54cd4',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'dataset',\n", - " 'source_name': 'sluschi',\n", - " 'tags': ['Melting temperature calculation',\n", - " 'Density functional theory',\n", - " 'Automated code'],\n", - " 'title': 'Solid and Liquid in Ultra Small Coexistence with Hovering Interfaces',\n", - " 'year': 2015}}" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "res = mdf.match_field(\"mdf.elements\", \"Al\").fetch_datasets_from_results()\n", + "outputs": [], + "source": [ + "res = mdf.match_field(\"material.elements\", \"Al\").fetch_datasets_from_results()\n", "res[0]" ] }, @@ -698,19 +265,11 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of results: 23269\n" - ] - } - ], - "source": [ - "mdf.match_field(\"mdf.source_name\", \"oqmd\").match_field(\"mdf.elements\", \"Pb\").exclude_field(\"mdf.elements\", \"Al\")\n", + "outputs": [], + "source": [ + "mdf.match_field(\"mdf.source_name\", \"oqmd\").match_field(\"material.elements\", \"Pb\").exclude_field(\"material.elements\", \"Al\")\n", "res, info = mdf.search(limit=0, info=True, reset_query=False)\n", "print(\"Number of results:\", info[\"total_query_matches\"])" ] @@ -724,31 +283,9 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "100%|██████████| 23269/23269 [01:00<00:00, 388.45it/s]" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of results: 23269\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" - ] - } - ], + "outputs": [], "source": [ "res = mdf.aggregate()\n", "print(\"Number of results:\", len(res))" @@ -778,7 +315,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.4" } }, "nbformat": 4, diff --git a/docs/tutorials/5 - Field-Specific Helper Functions.ipynb b/docs/tutorials/5 - Field-Specific Helper Functions.ipynb index a446c90..48ea6fd 100644 --- a/docs/tutorials/5 - Field-Specific Helper Functions.ipynb +++ b/docs/tutorials/5 - Field-Specific Helper Functions.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -11,7 +11,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -29,28 +29,17 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### match_sources\n", - "`match_sources()` matches values against the `\"mdf.source_name\"` field. It is equivalent to chaining `match_field(\"mdf.source_name\", value)` for each value." + "### match_source_names\n", + "`match_source_names()` matches values against the `\"mdf.source_name\"` field. It is equivalent to chaining `match_field(\"mdf.source_name\", value)` for each value." ] }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "mdf.match_sources(\"oqmd\")" + "mdf.match_source_names(\"oqmd\")" ] }, { @@ -63,20 +52,9 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 4, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.match_elements([\"Al\", \"Cu\"])" ] @@ -91,70 +69,20 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.match_resource_types(\"record\")" ] }, { "cell_type": "code", - "execution_count": 6, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'collection': 'OQMD',\n", - " 'composition': 'Al2Cu1',\n", - " 'elements': ['Al', 'Cu'],\n", - " 'ingest_date': '2017-08-04T14:19:13.058498Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/17664',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/107544/static/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/107544/static/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848261a5ea60172af4a8c2',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 4462,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - Al2Cu1'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 0.0},\n", - " 'configuration': 'static',\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 107544},\n", - " 'delta_e': {'units': 'eV/atom', 'value': -0.15628721},\n", - " 'magnetic_moment': {'units': 'bohr/atom'},\n", - " 'spacegroup': 69,\n", - " 'stability': {'units': 'eV/atom', 'value': 0.018707923333333},\n", - " 'total_energy': {'units': 'eV/atom', 'value': -3.89209998333333},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 14.7911}}}" - ] - }, - "execution_count": 6, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "res = mdf.search(limit=10)\n", "res[0]" @@ -170,20 +98,9 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 7, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "an_id = res[1][\"mdf\"][\"mdf_id\"]\n", "mdf.match_ids(an_id)" @@ -191,50 +108,11 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'mdf': {'collection': 'OQMD',\n", - " 'composition': 'Al1Cu3',\n", - " 'elements': ['Al', 'Cu'],\n", - " 'ingest_date': '2017-08-04T14:19:02.238752Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/8950',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/150823/static/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/150823/static/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848256a5ea60172af49f39',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 2021,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - Al1Cu3'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 0.0},\n", - " 'configuration': 'static',\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 150823},\n", - " 'delta_e': {'units': 'eV/atom', 'value': -0.1675233825},\n", - " 'magnetic_moment': {'units': 'bohr/atom'},\n", - " 'spacegroup': 225,\n", - " 'stability': {'units': 'eV/atom', 'value': 0.02138741875},\n", - " 'total_energy': {'units': 'eV/atom', 'value': -3.8909277975},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 12.3364}}}]" - ] - }, - "execution_count": 8, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.search()" ] @@ -244,259 +122,57 @@ "metadata": {}, "source": [ "### match_titles\n", - "`match_titles()` matches values against the `\"mdf.title\"` field. It is equivalent to chaining `match_field(\"mdf.title\", value)` for each value.\n", + "`match_titles()` matches values against the `\"dc.titles.title\"` field. It is equivalent to chaining `match_field(\"dc.titles.title\", value)` for each value.\n", "\n", "Remember, values with special characters (like spaces) need to be wrapped in double quotes." ] }, { "cell_type": "code", - "execution_count": 9, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 9, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.match_titles('\"The Open Quantum Materials Database\"')" ] }, { "cell_type": "code", - "execution_count": 10, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "[{'mdf': {'author': [{'family_name': 'Wolverton',\n", - " 'full_name': 'Chris Wolverton',\n", - " 'given_name': 'Chris',\n", - " 'institution': 'Northwestern University'},\n", - " {'family_name': 'Kirklin',\n", - " 'full_name': 'Scott Kirklin',\n", - " 'given_name': 'Scott',\n", - " 'institution': 'Northwestern University'},\n", - " {'family_name': 'Hegde',\n", - " 'full_name': 'Vinay Hegde',\n", - " 'given_name': 'Vinay',\n", - " 'institution': 'Northwestern University'},\n", - " {'family_name': 'Ward',\n", - " 'full_name': 'Logan Ward',\n", - " 'given_name': 'Logan',\n", - " 'institution': 'Northwestern University',\n", - " 'orcid': 'https://orcid.org/0000-0002-1323-5939'}],\n", - " 'citation': ['Saal, J. E., Kirklin, S., Aykol, M., Meredig, B., and Wolverton, C. \"Materials Design and Discovery with High-Throughput Density Functional Theory: The Open Quantum Materials Database (OQMD)\", JOM 65, 1501-1509 (2013). doi:10.1007/s11837-013-0755-4',\n", - " 'Kirklin, S., Saal, J.E., Meredig, B., Thompson, A., Doak, J.W., Aykol, M., Rühl, S. and Wolverton, C. \"The Open Quantum Materials Database (OQMD): assessing the accuracy of DFT formation energies\", npj Computational Materials 1, 15010 (2015). doi:10.1038/npjcompumats.2015.10'],\n", - " 'collection': 'OQMD',\n", - " 'data_contact': {'email': 'oqmd.questions@gmail.com',\n", - " 'family_name': 'Wolverton',\n", - " 'full_name': 'Chris Wolverton',\n", - " 'given_name': 'Chris',\n", - " 'institution': 'Northwestern University'},\n", - " 'data_contributor': [{'email': 'jgaff@uchicago.edu',\n", - " 'family_name': 'Gaff',\n", - " 'full_name': 'Jonathon Gaff',\n", - " 'github': 'jgaff',\n", - " 'given_name': 'Jonathon',\n", - " 'institution': 'The University of Chicago'}],\n", - " 'description': 'The OQMD is a database of DFT-calculated thermodynamic and structural properties.',\n", - " 'ingest_date': '2017-08-04T14:18:51.560728Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/',\n", - " 'publication': ['http://dx.doi.org/10.1007/s11837-013-0755-4',\n", - " 'http://dx.doi.org/10.1038/npjcompumats.2015.10']},\n", - " 'mdf_id': '5984824ba5ea60170af49754',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'dataset',\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['dft'],\n", - " 'title': 'The Open Quantum Materials Database',\n", - " 'year': 2013}}]" - ] - }, - "execution_count": 10, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.search()" ] }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### match_tags\n", - "`match_tags()` matches values against the `\"mdf.tags\"` field. It is equivalent to chaining `match_field(\"mdf.tags\", value)` for each value." - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "mdf.match_tags(\"DFT\")" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'author': [{'email': 'mfelling@illinois.edu',\n", - " 'family_name': 'Fellinger',\n", - " 'full_name': 'Michael Fellinger',\n", - " 'given_name': 'Michael',\n", - " 'institution': 'University of Illinois'},\n", - " {'family_name': 'Trinkle',\n", - " 'full_name': 'Dallas Trinkle',\n", - " 'given_name': 'Dallas',\n", - " 'institution': 'University of Illinois'},\n", - " {'family_name': 'Hector Jr.',\n", - " 'full_name': 'Louis Hector Jr.',\n", - " 'given_name': 'Louis',\n", - " 'institution': 'General Motors'}],\n", - " 'citation': ['M. R. Fellinger, L. G. Hector Jr., and D. R. Trinkle, Comp. Mat. Sci. 126, 503 (2017).',\n", - " 'M. R. Fellinger, L. G. Hector Jr., and D. R. Trinkle, Data in Brief 10, 147 (2017).'],\n", - " 'collection': 'Elastic Fe BCC',\n", - " 'data_contact': {'email': 'mfelling@illinois.edu',\n", - " 'family_name': 'Fellinger',\n", - " 'full_name': 'Michael Fellinger',\n", - " 'given_name': 'Michael',\n", - " 'institution': 'University of Illinois'},\n", - " 'data_contributor': [{'email': 'jgaff@uchicago.edu',\n", - " 'family_name': 'Gaff',\n", - " 'full_name': 'Jonathon Gaff',\n", - " 'github': 'jgaff',\n", - " 'given_name': 'Jonathon',\n", - " 'institution': 'The University of Chicago'}],\n", - " 'description': 'We introduce a solute strain misfit tensor that quantifies how solutes change the lattice parameter.',\n", - " 'ingest_date': '2017-08-04T19:51:21.076837Z',\n", - " 'license': 'http://creativecommons.org/publicdomain/zero/1.0/',\n", - " 'links': {'data_doi': 'http://hdl.handle.net/11256/671',\n", - " 'landing_page': 'https://materialsdata.nist.gov/dspace/xmlui/handle/11256/671',\n", - " 'publication': ['http://dx.doi.org/10.1016/j.commatsci.2016.09.040',\n", - " 'http://dx.doi.org/10.1016/j.dib.2016.11.092']},\n", - " 'mdf_id': '5984d039f2c0043894245abb',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'dataset',\n", - " 'source_name': 'trinkle_elastic_fe_bcc',\n", - " 'tags': ['dft'],\n", - " 'title': 'Ab initio calculations of the lattice parameter and elastic stiffness coefficients of bcc Fe with solutes',\n", - " 'year': 2017}}" - ] - }, - "execution_count": 12, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "res = mdf.search(limit=10)\n", - "res[0]" - ] - }, { "cell_type": "markdown", "metadata": {}, "source": [ "### match_years\n", - "`match_years()` matches values against the `\"mdf.year\"` field." + "`match_years()` matches values against the `\"dc.publicationYear\"` field." ] }, { "cell_type": "code", - "execution_count": 13, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 13, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.match_years([\"2015\", 2010])" ] }, { "cell_type": "code", - "execution_count": 14, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'collection': 'PPPDB',\n", - " 'composition': 'C8H8 C7H7N',\n", - " 'description': 'Chi Parameter for poly(styrene) and poly(4-vinylpyridine)',\n", - " 'elements': ['H', 'N', 'C'],\n", - " 'ingest_date': '2017-08-04T20:56:39.045371Z',\n", - " 'links': {'landing_page': 'http://pppdb.uchicago.edu?&id=164',\n", - " 'parent_id': '5984df58f2c004392664b14c',\n", - " 'publication': ['10.1021/ma1006792']},\n", - " 'mdf_id': '5984df87f2c004392664b15e',\n", - " 'metadata_version': '0.3.2',\n", - " 'raw': '{\"doi\": \"10.1021/ma1006792\", \"type\": \"Type 1\", \"temperature\": 160.0, \"tempunit\": \"Celsius\", \"chinumber\": 0.3, \"chierror\": 0.0, \"chia\": 0.0, \"chiaerror\": 0.0, \"chib\": 0.0, \"chiberror\": 0.0, \"chic\": 0.0, \"chicerror\": 0.0, \"notes\": \"\", \"indirect\": 1, \"reference\": \"DOI: 10.1021/ma062516u; DOI: 10.1021/ma702780c\", \"compound1\": \"poly(styrene)\", \"compound2\": \"poly(4-vinylpyridine)\", \"authors\": \"Biplab K. Kuila, E. Bhoje Gowd, and Manfred Stamm\", \"date\": \"August 19, 2010\", \"pppdb_id\": 164}',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 18,\n", - " 'source_name': 'pppdb',\n", - " 'tags': ['poly(styrene)', 'poly(4-vinylpyridine)'],\n", - " 'title': 'PPPDB - Chi Parameter for poly(styrene) and poly(4-vinylpyridine)',\n", - " 'year': 2010},\n", - " 'pppdb': {'authors': 'Biplab K. Kuila, E. Bhoje Gowd, and Manfred Stamm',\n", - " 'chierror': 0.0,\n", - " 'chinumber': 0.3,\n", - " 'date': 'August 19, 2010',\n", - " 'id': 164,\n", - " 'reference': 'DOI: 10.1021/ma062516u; DOI: 10.1021/ma702780c',\n", - " 'temperature': 160.0,\n", - " 'tempunit': 'Celsius',\n", - " 'type': 'Type 1'}}" - ] - }, - "execution_count": 14, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "res = mdf.search(limit=10)\n", "res[0]" @@ -511,67 +187,20 @@ }, { "cell_type": "code", - "execution_count": 15, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "" - ] - }, - "execution_count": 15, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "mdf.match_years(start=2014, stop=2016, inclusive=True)" ] }, { "cell_type": "code", - "execution_count": 16, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'collection': 'PPPDB',\n", - " 'composition': 'C7H7N C7H8',\n", - " 'description': 'could not access cited reference for method',\n", - " 'elements': ['H', 'N', 'C'],\n", - " 'ingest_date': '2017-08-04T21:06:57.080792Z',\n", - " 'links': {'landing_page': 'http://pppdb.uchicago.edu?&id=606',\n", - " 'parent_id': '5984df58f2c004392664b14c',\n", - " 'publication': ['10.1021/acs.macromol.5b01261']},\n", - " 'mdf_id': '5984e1f1f2c004392664b2cc',\n", - " 'metadata_version': '0.3.2',\n", - " 'raw': '{\"doi\": \"10.1021/acs.macromol.5b01261\", \"type\": \"Type 1\", \"temperature\": 0.0, \"tempunit\": \"\", \"chinumber\": 1.01, \"chierror\": 0.0, \"chia\": 0.0, \"chiaerror\": 0.0, \"chib\": 0.0, \"chiberror\": 0.0, \"chic\": 0.0, \"chicerror\": 0.0, \"notes\": \"could not access cited reference for method\", \"indirect\": 1, \"reference\": \"ISBN: 0-471-16628-6\", \"compound1\": \"poly(4-vinylpyridine)\", \"compound2\": \"toluene\", \"authors\": \"Renhua Deng, Hui Li, Fuxin Liang, Jintao Zhu, Baohui Li, Xiaolin Xie, and Zhenzhong Yang \", \"date\": \"August 6, 2015\", \"pppdb_id\": 606}',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 384,\n", - " 'source_name': 'pppdb',\n", - " 'tags': ['poly(4-vinylpyridine)', 'toluene'],\n", - " 'title': 'PPPDB - Chi Parameter for poly(4-vinylpyridine) and toluene',\n", - " 'year': 2015},\n", - " 'pppdb': {'authors': 'Renhua Deng, Hui Li, Fuxin Liang, Jintao Zhu, Baohui Li, Xiaolin Xie, and Zhenzhong Yang ',\n", - " 'chierror': 0.0,\n", - " 'chinumber': 1.01,\n", - " 'date': 'August 6, 2015',\n", - " 'id': 606,\n", - " 'reference': 'ISBN: 0-471-16628-6',\n", - " 'temperature': 0.0,\n", - " 'tempunit': '',\n", - " 'type': 'Type 1'}}" - ] - }, - "execution_count": 16, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "res = mdf.search(limit=10)\n", "res[0]" @@ -594,52 +223,13 @@ }, { "cell_type": "code", - "execution_count": 17, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'collection': 'OQMD',\n", - " 'composition': 'Al2Cu1',\n", - " 'elements': ['Al', 'Cu'],\n", - " 'ingest_date': '2017-08-04T14:19:13.058498Z',\n", - " 'links': {'landing_page': 'http://oqmd.org/analysis/calculation/17664',\n", - " 'metadata': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/107544/static/metadata.json'},\n", - " 'outcar': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/oqmd/data/home/oqmd/libraries/icsd/107544/static/OUTCAR'},\n", - " 'parent_id': '5984824ba5ea60170af49754'},\n", - " 'mdf_id': '59848261a5ea60172af4a8c2',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 4462,\n", - " 'source_name': 'oqmd',\n", - " 'tags': ['metadata', 'outcar'],\n", - " 'title': 'OQMD - Al2Cu1'},\n", - " 'oqmd': {'band_gap': {'units': 'eV', 'value': 0.0},\n", - " 'configuration': 'static',\n", - " 'converged': True,\n", - " 'crossreference': {'icsd': 107544},\n", - " 'delta_e': {'units': 'eV/atom', 'value': -0.15628721},\n", - " 'magnetic_moment': {'units': 'bohr/atom'},\n", - " 'spacegroup': 69,\n", - " 'stability': {'units': 'eV/atom', 'value': 0.018707923333333},\n", - " 'total_energy': {'units': 'eV/atom', 'value': -3.89209998333333},\n", - " 'volume': {'units': 'angstrom^3/atom', 'value': 14.7911}}}" - ] - }, - "execution_count": 17, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "res = mdf.search_by_elements([\"Al\", \"Cu\"], sources=[\"oqmd\"])\n", + "res = mdf.search_by_elements([\"Al\", \"Cu\"], source_names=[\"oqmd\"])\n", "res[0]" ] }, @@ -653,49 +243,11 @@ }, { "cell_type": "code", - "execution_count": 18, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'author': [{'family_name': 'Chase, Jr.',\n", - " 'full_name': 'Malcolm Chase, Jr.',\n", - " 'given_name': 'Malcolm',\n", - " 'institution': 'National Institute of Standards and Technology'}],\n", - " 'citation': ['M. W. Chase, Jr., JANAF Thermochemical Tables Third Edition, J. Phys. Chem. Ref. Data, Vol. 14, Suppl. 1, 1985.'],\n", - " 'collection': 'NIST-JANAF',\n", - " 'data_contact': {'email': 'evelyn.brown@nist.gov',\n", - " 'family_name': 'Brown',\n", - " 'full_name': 'Evelyn Brown',\n", - " 'given_name': 'Evelyn',\n", - " 'institution': 'National Institute of Standards and Technology'},\n", - " 'data_contributor': [{'email': 'jgaff@uchicago.edu',\n", - " 'family_name': 'Gaff',\n", - " 'full_name': 'Jonathon Gaff',\n", - " 'github': 'jgaff',\n", - " 'given_name': 'Jonathon',\n", - " 'institution': 'The University of Chicago'}],\n", - " 'description': 'DISCLAIMER: NIST uses its best efforts to deliver a high quality copy of the Database and to verify that the data contained therein have been selected on the basis of sound scientific judgement. However, NIST makes no warranties to that effect, and NIST shall not be liable for any damage that may result from errors or omissions in the Database.',\n", - " 'ingest_date': '2017-08-04T19:34:26.282241Z',\n", - " 'license': 'Copyright 1986 by the U.S. Department of Commerce on behalf of the United States. All rights reserved.',\n", - " 'links': {'landing_page': 'http://kinetics.nist.gov/janaf/'},\n", - " 'mdf_id': '5984cc42f2c00438337919d7',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'dataset',\n", - " 'source_name': 'nist_janaf',\n", - " 'tags': ['Thermochemical'],\n", - " 'title': 'NIST-JANAF Thermochemical Tables',\n", - " 'year': 1985}}" - ] - }, - "execution_count": 18, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "res = mdf.search_by_titles(['\"JANAF Thermochemical Tables\"'])\n", "res[0]" @@ -705,124 +257,19 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### search_by_tags\n", - "`search_by_tags()` executes a search for the provided tags in the provided sources and returns the results." + "### aggregate_source_names\n", + "`aggregate_source_names()` fetches and returns all the records for a provided `\"mdf.source_name\"` value. Calling `search()` or `aggregate()` is not required, as this helper function does that for you. Please note that it is not possible to use the `limit` argument with this helper function, so you may get back a large number of results." ] }, { "cell_type": "code", - "execution_count": 19, - "metadata": { - "scrolled": true - }, - "outputs": [ - { - "data": { - "text/plain": [ - "{'mdf': {'author': [{'email': 'wjoost@umd.edu',\n", - " 'family_name': 'Joost',\n", - " 'full_name': 'William Joost',\n", - " 'given_name': 'William',\n", - " 'institution': 'University of Maryland'},\n", - " {'family_name': 'Ankem',\n", - " 'full_name': 'Sreeramamurthy Ankem',\n", - " 'given_name': 'Sreeramamurthy',\n", - " 'institution': 'University of Maryland'},\n", - " {'family_name': 'Kuklja',\n", - " 'full_name': 'Maija Kuklja',\n", - " 'given_name': 'Maija',\n", - " 'institution': 'University of Maryland'}],\n", - " 'citation': ['W.J. Joost, S. Ankem, M.M. Kuklja \"A modified embedded atom method potential for the titanium-oxygen system\" Modelling and Simulation in Materials Science and Engineering Vol. 23, pp. 015006 (2015) doi:10.1088/0965-0393/23/1/015006'],\n", - " 'collection': 'Ti-O MEAM Model',\n", - " 'data_contact': {'email': 'wjoost@umd.edu',\n", - " 'family_name': 'Joost',\n", - " 'full_name': 'William Joost',\n", - " 'given_name': 'William',\n", - " 'institution': 'University of Maryland'},\n", - " 'data_contributor': [{'email': 'jgaff@uchicago.edu',\n", - " 'family_name': 'Gaff',\n", - " 'full_name': 'Jonathon Gaff',\n", - " 'github': 'jgaff',\n", - " 'given_name': 'Jonathon',\n", - " 'institution': 'The University of Chicago'}],\n", - " 'description': 'The files included here are:\\n 1) LAMMPS and VASP input files describing the structures specified in the article.\\n 2) LAMMPS and VASP output files describing the calculation results and the output structures.\\n 3) A Python script used in this study to perform a brute force search of the parameter space for the Ti-O MEAM potential. Further details are provided in the article, and in the script.\\n 4) The Ti, O and Ti-O potential files in LAMMPS MEAM format',\n", - " 'ingest_date': '2017-08-04T19:50:45.686503Z',\n", - " 'links': {'data_doi': 'http://hdl.handle.net/11115/244',\n", - " 'landing_page': 'https://materialsdata.nist.gov/dspace/xmlui/handle/11115/244',\n", - " 'publication': ['https:/dx.doi.org/10.1088/0965-0393/23/1/015006']},\n", - " 'mdf_id': '5984d015f2c004388b77e807',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'dataset',\n", - " 'source_name': 'ti_o_meam_model',\n", - " 'tags': ['dft', 'atom-scale simulation'],\n", - " 'title': 'A Modified Embedded Atom Method Potential for the Titanium-Oxygen System',\n", - " 'year': 2014}}" - ] - }, - "execution_count": 19, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "res = mdf.search_by_tags([\"dft\", \"simulation\"])\n", - "res[0]" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "### aggregate_source\n", - "`aggregate_source()` fetches and returns all the records for a provided `\"mdf.source_name\"` value. Calling `search()` or `aggregate()` is not required, as this helper function does that for you. Please note that it is not possible to use the `limit` argument with this helper function, so you may get back a large number of results." - ] - }, - { - "cell_type": "code", - "execution_count": 20, + "execution_count": null, "metadata": { "scrolled": true }, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "1401it [00:01, 787.20it/s] \n" - ] - }, - { - "data": { - "text/plain": [ - "{'fe_cr_al_oxidation': {'atomic_composition_percent': {'Al': 3.1,\n", - " 'Cr': 26.5,\n", - " 'Fe': 70.5},\n", - " 'temperature_k': 420.0},\n", - " 'mdf': {'collection': 'Fe-Cr-Al Oxidation Studies',\n", - " 'composition': 'FeCrAl',\n", - " 'elements': ['Cr', 'Fe', 'Al'],\n", - " 'ingest_date': '2017-08-04T21:26:53.296946Z',\n", - " 'links': {'csv': {'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec',\n", - " 'http_host': 'https://data.materialsdatafacility.org',\n", - " 'path': '/collections/Fe_Cr_Al_data/420 K/420 K Point 104.txt'},\n", - " 'landing_page': 'https://materialsdata.nist.gov/dspace/xmlui/handle/11256/836#104',\n", - " 'parent_id': '5984e69cf2c00439c790bf54'},\n", - " 'mdf_id': '5984e69df2c00439c790bfbc',\n", - " 'metadata_version': '0.3.2',\n", - " 'resource_type': 'record',\n", - " 'scroll_id': 104,\n", - " 'source_name': 'fe_cr_al_oxidation',\n", - " 'tags': ['csv'],\n", - " 'title': 'Fe-Cr-Al Oxidation - 420 K Point 104'}}" - ] - }, - "execution_count": 20, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ - "res = mdf.aggregate_source(\"fe_cr_al_oxidation\")\n", + "res = mdf.aggregate_source_names(\"fe_cr_al_oxidation\")\n", "res[0]" ] }, @@ -850,7 +297,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.4" } }, "nbformat": 4, diff --git a/docs/tutorials/6 - Data Retrieval Functions.ipynb b/docs/tutorials/6 - Data Retrieval Functions.ipynb index 4910ab3..86f9515 100644 --- a/docs/tutorials/6 - Data Retrieval Functions.ipynb +++ b/docs/tutorials/6 - Data Retrieval Functions.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": 1, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -11,7 +11,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": null, "metadata": {}, "outputs": [], "source": [ @@ -39,59 +39,12 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Multiple endpoints found:\n", - "1 : jgaff_laptop \t ce6d512a-b414-11e7-b0a7-22000a92523b\n", - "2 : MDF AWS MRDP \t b6cbf972-aded-11e7-afcb-22000a92523b\n", - "3 : MDF Open Connect \t 1d14558e-aebc-11e7-b018-22000a92523b\n", - "\n", - "Please choose the endpoint on this machine\n", - "Enter the number of the correct endpoint (-1 to cancel): 1\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Processing records: 100%|██████████| 1/1 [00:00<00:00, 3.20it/s]\n", - "Submitting transfers: 100%|██████████| 1/1 [00:10<00:00, 10.86s/it]" - ] - }, - { - "name": "stdout", - "output_type": "stream", - "text": [ - "All transfers submitted\n", - "Task IDs: 62508454-bf12-11e7-9473-22000a8cbd7d\n" - ] - }, - { - "name": "stderr", - "output_type": "stream", - "text": [ - "\n" - ] - }, - { - "data": { - "text/plain": [ - "['62508454-bf12-11e7-9473-22000a8cbd7d']" - ] - }, - "execution_count": 3, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "# Running this example will save a file in the current directory.\n", - "res = mdf.search(\"mdf.tags:DFT AND mdf.resource_type:record\", limit=1)\n", + "res = mdf.search(\"dft.converged:true AND mdf.resource_type:record\", limit=1)\n", "mdf.globus_download(res)" ] }, @@ -105,17 +58,9 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Fetching files: 100%|██████████| 1/1 [00:01<00:00, 1.67s/it]\n" - ] - } - ], + "outputs": [], "source": [ "# Running this example will save a file in the current directory.\n", "res = mdf.search(\"mdf.source_name:janaf AND mdf.resource_type:record\", limit=1)\n", @@ -132,20 +77,9 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": null, "metadata": {}, - "outputs": [ - { - "data": { - "text/plain": [ - "'This file contains the embrittling potenciesthat might not be suitable for quantitative analysis.,,,,,\\rSolvent,Solute,Boundary Studied,Method,\"XC Functional, if DFT\",\"Embrittling Potency (kJ/mol, positive denotes a lowering of boundary cohesion)\"\\rNi,V,Sigma 5 (012)[100],DFT - Slab,Norm-Conserving Pseudopotentials with LDA,72.3\\rFe,Cr,Sigma 5 (210),DFT - PBC\\'S,GGA,-14.9\\rFe,Mo,Sigma 5 (210),DFT - PBC\\'S,GGA,10.1\\rFe,Nb,Sigma 5 (210),DFT - PBC\\'S,GGA,19.5\\rFe,Mn,Sigma 11 [1-10]/(11-3),DFT DMOL,?,197.5\\rFe,Cr,Sigma 11 [1-10]/(11-3),DFT DMOL,?,-106\\rFe,N,N/A,DFT with - bad for Fe,LDA,\\rFe,P,Sigma 3 [1-10](111),DFT DMOL,?,95.4\\rNi,H,Sigma 5 (210),DFT FLAPW - slab,GGA,0.3\\rFe,H,Sigma 5 [001](310),MD - EAM,,144.5\\rNi,He,Sigma 5 (210),DFT-Slab FLAPW,GGA,240.9\\rFe,N,{111},MD - Finnis-Sinclair,,139\\rFe,O,{111},MD - Finnis-Sinclair,,132\\rFe,S,{111},MD - Finnis-Sinclair,,556\\rFe,H,{111},MD - Finnis-Sinclair,,23\\rFe,P,{111},MD - Finnis-Sinclair,,355\\rFe,C,{111},MD - Finnis-Sinclair,,68\\rFe,B,{111},MD - Finnis-Sinclair,,63\\rFe,Si,{111},MD - Finnis-Sinclair,,244\\rFe,O,Sigma 5 (210),DFT - PBC\\'s,GGA (PW91),72.3\\rFe,N,Sigma 5 (210),DFT - PBC\\'s,GGA (PW91),-19.3\\rCu,He,Sigma 5 (310)[001],DFT,,\\rCu,Kr,Sigma 5 (310)[001],DFT,,\\rAl,Co,3 twist and 3 tilt GB\\'s,MD - EAM,N/A,N/A\\rAl,Fe,4 twist and 3 tilt GB\\'s,MD - EAM,N/A,N/A\\rAl,Ti,5 twist and 3 tilt GB\\'s,MD - EAM,N/A,N/A\\rAl,Mg,6 twist and 3 tilt GB\\'s,MD - EAM,N/A,N/A\\rAl,Cu,7 twist and 3 tilt GB\\'s,MD - EAM,N/A,N/A\\rAl,Pb,8 twist and 3 tilt GB\\'s,MD - EAM,N/A,N/A\\rNi,W,Sigma 5 (210),DFT-slab,GGA,-127.2\\rNi,Zr,Sigma 5 (210),DFT-slab,GGA,-16.4\\rNi,Hf,Sigma 5 (210),DFT-slab,GGA,-47.2\\rNi,Bi,Sigma 5 (210),DFT-slab,GGA,194.6\\rNi,S,Sigma 5 (210),DFT-slab,GGA,105\\rNi,B,Sigma 5 (210),DFT-slab,GGA,-67.4\\rNi,Ta,Sigma 5 (210),DFT-slab,GGA,-102.1\\rNi,Re,Sigma 5 (210),DFT-slab,GGA,-128.2\\rW,H,Sigma 3 (111),DFT- not specified,Not specified,25.8\\rW,B,Sigma 3 (111),DFT- not specified,Not specified,-17.6\\rW,C,Sigma 3 (111),DFT- not specified,Not specified,-55.2\\rW,N,Sigma 3 (111),DFT- not specified,Not specified,36.4\\rW,O,Sigma 3 (111),DFT- not specified,Not specified,150.4\\rW,F,Sigma 3 (111),DFT- not specified,Not specified,341.9\\rW,Al,Sigma 3 (111),DFT- not specified,Not specified,285.5\\rW,Si,Sigma 3 (111),DFT- not specified,Not specified,245.6\\rW,P,Sigma 3 (111),DFT- not specified,Not specified,255\\rW,S,Sigma 3 (111),DFT- not specified,Not specified,358.4\\rW,Cl,Sigma 3 (111),DFT- not specified,Not specified,575.8\\rTa,H,Sigma 3 (111),DFT- not specified,Not specified,56.4\\rTa,B,Sigma 3 (111),DFT- not specified,Not specified,-17.6\\rTa,C,Sigma 3 (111),DFT- not specified,Not specified,-84.7\\rTa,N,Sigma 3 (111),DFT- not specified,Not specified,-22.3\\rTa,O,Sigma 3 (111),DFT- not specified,Not specified,47\\rTa,F,Sigma 3 (111),DFT- not specified,Not specified,275\\rTa,Al,Sigma 3 (111),DFT- not specified,Not specified,179.8\\rTa,Si,Sigma 3 (111),DFT- not specified,Not specified,108.1\\rTa,P,Sigma 3 (111),DFT- not specified,Not specified,110.5\\rTa,S,Sigma 3 (111),DFT- not specified,Not specified,162.1\\rTa,Cl,Sigma 3 (111),DFT- not specified,Not specified,372.5\\rFe,B,Sigma 5 (210),DFT - PBC\\'s,GGA (PW91),-55.9'" - ] - }, - "execution_count": 5, - "metadata": {}, - "output_type": "execute_result" - } - ], + "outputs": [], "source": [ "res = mdf.search(\"AlCu\", limit=1)\n", "raw_data = mdf.http_stream(res)\n", @@ -176,7 +110,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.5.2" + "version": "3.6.4" } }, "nbformat": 4, diff --git a/mdf_forge/forge.py b/mdf_forge/forge.py index e7774bb..6e31042 100644 --- a/mdf_forge/forge.py +++ b/mdf_forge/forge.py @@ -354,24 +354,25 @@ def exclusive_match(self, field, value): # Done return self - def match_sources(self, sources): + def match_source_names(self, source_names): """Add sources to match to the query. Arguments: - sources (str or list of str): The sources to match. + source_names (str or list of str): The source_names to match. Returns: self (Forge): For chaining. """ - # If no sources are supplied, nothing to match - if not sources: + # If no source_names are supplied, nothing to match + if not source_names: return self - if isinstance(sources, string_types): - sources = [sources] + if isinstance(source_names, string_types): + source_names = [source_names] # First source should be in new group and required - self.match_field(field="mdf.source_name", value=sources[0], required=True, new_group=True) + self.match_field(field="mdf.source_name", value=source_names[0], + required=True, new_group=True) # Other sources should stay in that group, and not be required - for src in sources[1:]: + for src in source_names[1:]: self.match_field(field="mdf.source_name", value=src, required=False, new_group=False) return self @@ -412,32 +413,11 @@ def match_elements(self, elements, match_all=True): if isinstance(elements, string_types): elements = [elements] # First element should be in new group and required - self.match_field(field="mdf.elements", value=elements[0], required=True, new_group=True) + self.match_field(field="material.elements", value=elements[0], + required=True, new_group=True) # Other elements should stay in that group for element in elements[1:]: - self.match_field(field="mdf.elements", value=element, required=match_all, - new_group=False) - return self - - def match_tags(self, tags, match_all=True): - """Add tags to the query. - - Arguments: - tags (str or list of str): The tags (keywords) to match. - match_all (bool): If True, will add with AND. If False, will use OR. Default True. - - Returns: - self (Forge): For chaining. - """ - - if not tags: - return self - if isinstance(tags, string_types): - tags = [tags] - - self.match_field(field="mdf.tags", value=tags[0], required=True, new_group=True) - for tag in tags[1:]: - self.match_field(field="mdf.tags", value=tag, required=match_all, + self.match_field(field="material.elements", value=element, required=match_all, new_group=False) return self @@ -455,9 +435,9 @@ def match_titles(self, titles): if not isinstance(titles, list): titles = [titles] - self.match_field(field="mdf.title", value=titles[0], required=True, new_group=True) + self.match_field(field="dc.titles.title", value=titles[0], required=True, new_group=True) for title in titles[1:]: - self.match_field(field="mdf.title", value=title, required=False, new_group=False) + self.match_field(field="dc.titles.title", value=title, required=False, new_group=False) return self def match_years(self, years=None, start=None, stop=None, inclusive=True): @@ -491,10 +471,11 @@ def match_years(self, years=None, start=None, stop=None, inclusive=True): # Only match years if valid years were supplied if len(years_int) > 0: - self.match_field(field="mdf.year", value=years_int[0], required=True, + self.match_field(field="dc.publicationYear", value=years_int[0], required=True, new_group=True) for year in years_int[1:]: - self.match_field(field="mdf.year", value=year, required=False, new_group=False) + self.match_field(field="dc.publicationYear", + value=year, required=False, new_group=False) else: if start is not None: try: @@ -509,7 +490,7 @@ def match_years(self, years=None, start=None, stop=None, inclusive=True): print_("Invalid stop year: '", stop, "'", sep="") stop = None - self.match_range(field="mdf.year", start=start, stop=stop, + self.match_range(field="dc.publicationYear", start=start, stop=stop, inclusive=inclusive, required=True, new_group=True) return self @@ -539,16 +520,16 @@ def match_resource_types(self, types): # * Premade searches # *********************************************** - def search_by_elements(self, elements, sources=[], index=None, limit=None, + def search_by_elements(self, elements, source_names=[], index=None, limit=None, match_all=True, info=False): """Execute a search for the given elements in the given sources. search_by_elements([x], [y]) is equivalent to - match_elements([x]).match_sources([y]).search() + match_elements([x]).match_source_names([y]).search() Note that this method does use terms from the current query. Arguments: elements (list of str): The elements to match. Default []. - sources (list of str): The sources to match. Default []. + source_names (list of str): The sources to match. Default []. index (str): The Globus Search index to search on. Defaults to the current index. limit (int): The maximum number of results to return. The max for this argument is the SEARCH_LIMIT imposed by Globus Search. @@ -565,7 +546,7 @@ def search_by_elements(self, elements, sources=[], index=None, limit=None, tuple (if info=True): The results, and a dictionary of query information. """ return (self.match_elements(elements, match_all=match_all) - .match_sources(sources) + .match_source_names(source_names) .search(index=index, limit=limit, info=info)) def search_by_titles(self, titles, index=None, limit=None, info=False): @@ -588,44 +569,19 @@ def search_by_titles(self, titles, index=None, limit=None, info=False): """ return self.match_titles(titles).search(index=index, limit=limit, info=info) - def search_by_tags(self, tags, index=None, limit=None, match_all=True, info=False): - """Execute a search for the given tag. - search_by_tags([x]) is equivalent to match_tags([x]).search() - - Arguments: - tags (list of str): The tags to match. Default []. - index (str): The Globus Search index to search on. Defaults to the current index. - limit (int): The maximum number of results to return. - The max for this argument is the SEARCH_LIMIT imposed by Globus Search. - match_all (bool): If True, will add elements with AND. - If False, will use OR. - Default True. - info (bool): If False, search will return a list of the results. - If True, search will return a tuple containing the results list, - and other information about the query. - Default False. - - Returns: - list (if info=False): The results. - tuple (if info=True): The results, and a dictionary of query information. - """ - return self.match_tags(tags, match_all=match_all).search(index=index, - limit=limit, - info=info) - - def aggregate_source(self, sources, index=None): + def aggregate_sources(self, source_names, index=None): """Aggregate all records from a given source. There is no limit to the number of results returned. Please beware of aggregating very large datasets. Arguments: - sources (str or list of str): The source to aggregate. + source_names (str or list of str): The source to aggregate. index (str): The Globus Search index to search on. Defaults to the current index. Returns: list of dict: All of the records from the source. """ - return self.match_sources(sources).aggregate(index=index) + return self.match_source_names(source_names).aggregate(index=index) def fetch_datasets_from_results(self, entries=None, query=None, reset_query=True): """Retrieve the dataset entries for given records. @@ -1012,19 +968,6 @@ def __init__(self, search_client, q=None, limit=None, advanced=False): # initialized is True if something has been added to the query # __init__(), term(), and field() can change this value to True self.initialized = not self.query == "(" - # Search index UUIDs, which are required instead of names - self.__index_uuids = { - "mdf": "d6cc98c3-ff53-4ee2-b22b-c6f945c0d30c", - "mdf-test": "c082b745-32ac-4ad2-9cde-92393f6e505c", - "dlhub": "847c9105-18a0-4ffb-8a71-03dd76dfcc9d", - "dlhub-test": "5c89e0a9-00e5-4171-b415-814fe4d0b8af" - } - - def __translate_index(self, index): - """Translate a known Globus Search index into the index UUID. - The UUID is now the only way to access indices. - """ - return self.__index_uuids.get(index.strip().lower(), index) def __clean_query_string(self, q): """Clean up a query string. @@ -1194,7 +1137,7 @@ def search(self, q=None, index=None, advanced=None, limit=SEARCH_LIMIT, info=Fal print_("Error: No index specified") return ([], {"error": "No index"}) if info else [] else: - uuid_index = self.__translate_index(index) + uuid_index = mdf_toolbox.translate_index(index) if advanced is None or self.advanced: advanced = self.advanced if limit is None: @@ -1299,5 +1242,5 @@ def mapping(self, index): dict: The full mapping for the index. """ return (self.__search_client.get( - "/unstable/index/{}/mapping".format(self.__translate_index(index))) + "/unstable/index/{}/mapping".format(mdf_toolbox.translate_index(index))) ["mappings"]) diff --git a/setup.py b/setup.py index dabc8a6..bc7683f 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ setup( name='mdf_forge', - version='0.5.2', + version='0.6.0', packages=['mdf_forge'], description='Materials Data Facility python package', long_description=("Forge is the Materials Data Facility Python package" @@ -10,7 +10,7 @@ "Forge allows users to perform simple queries and " "facilitiates moving and synthesizing results."), install_requires=[ - "mdf-toolbox>=0.1.6", + "mdf-toolbox>=0.1.7", "globus-sdk>=1.4.1", "requests>=2.18.4", "tqdm>=4.19.4", diff --git a/tests/test_forge.py b/tests/test_forge.py index ac584cd..8160d38 100644 --- a/tests/test_forge.py +++ b/tests/test_forge.py @@ -181,14 +181,14 @@ def test_query_aggregate(capsys): assert isinstance(res1[0], dict) # Multi-dataset aggregation - res2 = q.aggregate("(mdf.source_name:nist_xps_db OR mdf.source_name:nist_janaf)", + res2 = q.aggregate("(mdf.source_name:nist_xps_db OR mdf.source_name:khazana_vasp)", index="mdf") assert len(res2) > 10000 assert len(res2) > len(res1) # Unnecessary aggregation fallback to .search() # Check success in Coveralls - assert len(q.aggregate("mdf.source_name:hopv")) < 10000 + assert len(q.aggregate("mdf.source_name:khazana_vasp")) < 10000 def test_query_chaining(): @@ -297,47 +297,17 @@ def test_forge_properties(): # 1: Inclusive match, some values other than argument found # 2: Partial match, value is found in some but not all results def check_field(res, field, value): - supported_fields = [ - "mdf.elements", - "mdf.source_name", - "mdf.mdf_id", - "mdf.resource_type", - "mdf.title", - "mdf.tags", - "mdf.year" - ] - if field not in supported_fields: - raise ValueError("Implement or re-spell " - + field - + "because check_field only works on " - + str(supported_fields)) + dict_path = "" + for key in field.split("."): + dict_path += "['{}']".format(key) # If no results, set matches to false all_match = (len(res) > 0) only_match = (len(res) > 0) some_match = False for r in res: - if field == "mdf.elements": - try: - vals = r["mdf"]["elements"] - except KeyError: - vals = [] - elif field == "mdf.source_name": - vals = [r["mdf"]["source_name"]] - elif field == "mdf.mdf_id": - vals = [r["mdf"]["mdf_id"]] - elif field == "mdf.resource_type": - vals = [r["mdf"]["resource_type"]] - elif field == "mdf.title": - vals = [r["mdf"]["title"]] - elif field == "mdf.tags": - # mdf.tags field is already a list - try: - vals = r["mdf"]["tags"] - except KeyError: - vals = [] - elif field == "mdf.year": - vals = [r["mdf"]["year"]] - + vals = eval("r"+dict_path) + if type(vals) is not list: + vals = [vals] # If a result does not contain the value, no match if value not in vals: all_match = False @@ -366,47 +336,47 @@ def check_field(res, field, value): def test_forge_match_field(): f = forge.Forge(index="mdf") # Basic usage - f.match_field("mdf.source_name", "nist_janaf") + f.match_field("mdf.source_name", "khazana_vasp") res1 = f.search() - assert check_field(res1, "mdf.source_name", "nist_janaf") == 0 + assert check_field(res1, "mdf.source_name", "khazana_vasp") == 0 # Check that query clears assert f.search() == [] # Also checking check_field - f.match_field("mdf.elements", "Al") + f.match_field("material.elements", "Al") res2 = f.search() - assert check_field(res2, "mdf.elements", "Al") == 1 + assert check_field(res2, "material.elements", "Al") == 1 def test_forge_exclude_field(): f = forge.Forge(index="mdf") # Basic usage - f.exclude_field("mdf.elements", "Al") - f.match_field("mdf.source_name", "core_mof") + f.exclude_field("material.elements", "Al") + f.match_field("mdf.source_name", "ab_initio_solute_database") res1 = f.search() - assert check_field(res1, "mdf.elements", "Al") == -1 + assert check_field(res1, "material.elements", "Al") == -1 def test_forge_match_range(): # Single-value use f = forge.Forge(index="mdf") - f.match_range("mdf.elements", "Al", "Al") + f.match_range("material.elements", "Al", "Al") res1, info1 = f.search(info=True) - assert check_field(res1, "mdf.elements", "Al") == 1 + assert check_field(res1, "material.elements", "Al") == 1 - res2, info2 = f.search("mdf.elements:Al", advanced=True, info=True) + res2, info2 = f.search("material.elements:Al", advanced=True, info=True) assert info1["total_query_matches"] == info2["total_query_matches"] # Non-matching use, test inclusive - f.match_range("mdf.elements", "Al", "Al", inclusive=False) + f.match_range("material.elements", "Al", "Al", inclusive=False) assert f.search() == [] # Actual range - f.match_range("mdf.elements", "Al", "Cu") + f.match_range("material.elements", "Al", "Cu") res4, info4 = f.search(info=True) assert info1["total_query_matches"] < info4["total_query_matches"] - assert (check_field(res4, "mdf.elements", "Al") >= 0 or - check_field(res4, "mdf.elements", "Cu") >= 0) + assert (check_field(res4, "material.elements", "Al") >= 0 or + check_field(res4, "material.elements", "Cu") >= 0) # Nothing to match assert f.match_range("field", start=None, stop=None) == f @@ -415,19 +385,19 @@ def test_forge_match_range(): def test_forge_exclude_range(): # Single-value use f = forge.Forge(index="mdf") - f.exclude_range("mdf.elements", "Am", "*") - f.exclude_range("mdf.elements", "*", "Ak") + f.exclude_range("material.elements", "Am", "*") + f.exclude_range("material.elements", "*", "Ak") res1, info1 = f.search(info=True) - assert (check_field(res1, "mdf.elements", "Al") == 0 or - check_field(res1, "mdf.elements", "Al") == 2) + assert (check_field(res1, "material.elements", "Al") == 0 or + check_field(res1, "material.elements", "Al") == 2) - res2, info2 = f.search("mdf.elements:Al", advanced=True, info=True) + res2, info2 = f.search("material.elements:Al", advanced=True, info=True) assert info1["total_query_matches"] <= info2["total_query_matches"] # Non-matching use, test inclusive - f.exclude_range("mdf.elements", "Am", "*") - f.exclude_range("mdf.elements", "*", "Ak") - f.exclude_range("mdf.elements", "Al", "Al", inclusive=False) + f.exclude_range("material.elements", "Am", "*") + f.exclude_range("material.elements", "*", "Ak") + f.exclude_range("material.elements", "Al", "Al", inclusive=False) res3, info3 = f.search(info=True) assert info1["total_query_matches"] == info3["total_query_matches"] @@ -437,42 +407,42 @@ def test_forge_exclude_range(): def test_forge_exclusive_match(): f = forge.Forge(index="mdf") - f.exclusive_match("mdf.elements", "Al") + f.exclusive_match("material.elements", "Al") res1 = f.search() - assert check_field(res1, "mdf.elements", "Al") == 0 + assert check_field(res1, "material.elements", "Al") == 0 - f.exclusive_match("mdf.elements", ["Al", "Cu"]) + f.exclusive_match("material.elements", ["Al", "Cu"]) res2 = f.search() - assert check_field(res2, "mdf.elements", "Al") == 1 - assert check_field(res2, "mdf.elements", "Cu") == 1 - assert check_field(res2, "mdf.elements", "Cp") == -1 - assert check_field(res2, "mdf.elements", "Fe") == -1 + assert check_field(res2, "material.elements", "Al") == 1 + assert check_field(res2, "material.elements", "Cu") == 1 + assert check_field(res2, "material.elements", "Cp") == -1 + assert check_field(res2, "material.elements", "Fe") == -1 -def test_forge_match_sources(): +def test_forge_match_source_names(): f = forge.Forge(index="mdf") # One source - f.match_sources("nist_janaf") + f.match_source_names("khazana_vasp") res1 = f.search() assert res1 != [] - assert check_field(res1, "mdf.source_name", "nist_janaf") == 0 + assert check_field(res1, "mdf.source_name", "khazana_vasp") == 0 # Multi-source - f.match_sources(["nist_janaf", "hopv"]) + f.match_source_names(["khazana_vasp", "ta_melting"]) res2 = f.search() # res1 is a subset of res2 assert len(res2) > len(res1) assert all([r1 in res2 for r1 in res1]) - assert check_field(res2, "mdf.source_name", "nist_janaf") == 2 + assert check_field(res2, "mdf.source_name", "ta_melting") == 2 # No source - assert f.match_sources("") == f + assert f.match_source_names("") == f def test_forge_match_ids(): # Get a couple IDs f = forge.Forge(index="mdf") - res0 = f.search("mdf.source_name:nist_janaf", advanced=True, limit=2) + res0 = f.search("mdf.source_name:khazana_vasp", advanced=True, limit=2) id1 = res0[0]["mdf"]["mdf_id"] id2 = res0[1]["mdf"]["mdf_id"] @@ -500,14 +470,14 @@ def test_forge_match_elements(): f.match_elements("Al") res1 = f.search() assert res1 != [] - check_val1 = check_field(res1, "mdf.elements", "Al") + check_val1 = check_field(res1, "material.elements", "Al") assert check_val1 == 0 or check_val1 == 1 # Multi-element f.match_elements(["Al", "Cu"]) res2 = f.search() - assert check_field(res2, "mdf.elements", "Al") == 1 - assert check_field(res2, "mdf.elements", "Cu") == 1 + assert check_field(res2, "material.elements", "Al") == 1 + assert check_field(res2, "material.elements", "Cu") == 1 # No elements assert f.match_elements("") == f @@ -516,61 +486,35 @@ def test_forge_match_elements(): def test_forge_match_titles(): # One title f = forge.Forge(index="mdf") - titles1 = '"OQMD - Na1Y2Zr1"' + titles1 = '"High-throughput Ab-initio Dilute Solute Diffusion Database"' res1 = f.match_titles(titles1).search() assert res1 != [] - assert check_field(res1, "mdf.title", "OQMD - Na1Y2Zr1") == 0 + assert check_field(res1, "dc.titles.title", + "High-throughput Ab-initio Dilute Solute Diffusion Database") == 0 # Multiple titles - titles2 = ['"AMCS - Tungsten"', '"Cytochrome QSAR"'] + titles2 = [ + '"High-throughput Ab-initio Dilute Solute Diffusion Database"', + '"Khazana (VASP)"' + ] res2 = f.match_titles(titles2).search() assert res2 != [] - assert check_field(res2, "mdf.title", "Cytochrome QSAR - C13F2N6O") == 2 + assert check_field(res2, "dc.titles.title", "Khazana (VASP)") == 2 # No titles assert f.match_titles("") == f -def test_forge_match_tags(): - # Get one tag - f = forge.Forge(index="mdf") - res0 = f.search("mdf.source_name:trinkle_elastic_fe_bcc", advanced=True, limit=1) - tags1 = res0[0]["mdf"]["tags"][0] - - # One tag - res1 = f.match_tags(tags1).search() - assert check_field(res1, "mdf.tags", tags1) == 2 - - tags2 = "\"ab initio\"" - f.match_tags(tags2) - res2 = f.search() - # Elasticsearch splits ["ab-initio"] into ["ab", "initio"] - assert check_field(res2, "mdf.tags", "ab-initio") == 2 - - # Multiple tags - tags3 = ["\"density functional theory calculations\"", "\"X-ray\""] - res3 = f.match_tags(tags3, match_all=True).search() - # "source_name": "ge_nanoparticles", - # "tags": [ "amorphization","density functional theory calculations","Ge nanoparticles", - # "high pressure","phase transformation","Raman","X-ray absorption","zip" ] - assert check_field(res3, "mdf.tags", "Raman") == 1 - assert check_field(res3, "mdf.tags", "X-ray absorption") == 1 - assert check_field(res3, "mdf.tags", "density functional theory calculations") == 1 - - # No tag - assert f.match_tags("") == f - - def test_forge_match_years(capsys): # One year of data/results f = forge.Forge(index="mdf") res1 = f.match_years("2015").search() assert res1 != [] - assert check_field(res1, "mdf.year", 2015) == 0 + assert check_field(res1, "dc.publicationYear", 2015) == 0 # Multiple years res2 = f.match_years(years=["2015", 2011]).search() - assert check_field(res2, "mdf.year", 2011) == 2 + assert check_field(res2, "dc.publicationYear", 2011) == 2 # Wrong input f.match_years(["20x5"]).search() @@ -589,14 +533,14 @@ def test_forge_match_years(capsys): # Test range res4 = f.match_years(start=2015, stop=2015, inclusive=True).search() - assert check_field(res4, "mdf.year", 2015) == 0 + assert check_field(res4, "dc.publicationYear", 2015) == 0 res5 = f.match_years(start=2014, stop=2017, inclusive=False).search() - assert check_field(res5, "mdf.year", 2013) == -1 - assert check_field(res5, "mdf.year", 2014) == -1 - assert check_field(res5, "mdf.year", 2015) == 2 - assert check_field(res5, "mdf.year", 2016) == 2 - assert check_field(res5, "mdf.year", 2017) == -1 + assert check_field(res5, "dc.publicationYear", 2013) == -1 + assert check_field(res5, "dc.publicationYear", 2014) == -1 + assert check_field(res5, "dc.publicationYear", 2015) == 2 + assert check_field(res5, "dc.publicationYear", 2016) == 2 + assert check_field(res5, "dc.publicationYear", 2017) == -1 assert f.match_years(start=2015, stop=2015, inclusive=False).search() == [] @@ -656,45 +600,31 @@ def test_forge_search_by_elements(): f = forge.Forge(index="mdf") elements = ["Cu", "Al"] sources = ["oqmd", "nist_xps_db"] - res1, info1 = f.match_sources(sources).match_elements(elements).search(limit=10000, info=True) + res1, info1 = f.match_source_names(sources).match_elements(elements).search(limit=10000, + info=True) res2, info2 = f.search_by_elements(elements, sources, limit=10000, info=True) assert all([r in res2 for r in res1]) and all([r in res1 for r in res2]) - assert check_field(res1, "mdf.elements", "Al") == 1 + assert check_field(res1, "material.elements", "Al") == 1 assert check_field(res1, "mdf.source_name", "oqmd") == 2 def test_forge_search_by_titles(): f = forge.Forge(index="mdf") - titles1 = ["\"AMCS - Tungsten\""] + titles1 = ['"High-throughput Ab-initio Dilute Solute Diffusion Database"'] res1 = f.search_by_titles(titles1) - assert check_field(res1, "mdf.title", "AMCS - Tungsten") == 0 + assert check_field(res1, "dc.titles.title", + "High-throughput Ab-initio Dilute Solute Diffusion Database") == 0 - titles2 = ["Tungsten"] + titles2 = ["Diffusion"] res2 = f.search_by_titles(titles2) - assert check_field(res2, "mdf.title", "AMCS - Tungsten") == 2 - - -def test_forge_search_by_tags(): - f = forge.Forge(index="mdf") - tags1 = "DFT" - res1 = f.search_by_tags(tags1) - assert check_field(res1, "mdf.tags", "DFT") == 2 - - tags2 = ["\"Density Functional Theory\"", "\"X-ray\""] - res2 = f.search_by_tags(tags2, match_all=True) - - tags3 = ["\"Density Functional Theory\"", "\"X-ray\""] - res3 = f.search_by_tags(tags3, match_all=False) - - # res2 is a subset of res3 - assert len(res3) > len(res2) - assert all([r in res3 for r in res2]) + assert check_field(res2, "mdf.title", + "High-throughput Ab-initio Dilute Solute Diffusion Database") == 2 -def test_forge_aggregate_source(): +def test_forge_aggregate_sources(): # Test limit f = forge.Forge(index="mdf") - res1 = f.aggregate_source("amcs") + res1 = f.aggregate_sources("amcs") assert isinstance(res1, list) assert len(res1) > 10000 assert isinstance(res1[0], dict) @@ -739,7 +669,7 @@ def test_forge_fetch_datasets_from_results(): assert res4 == res04 # Fetch entries from current query - f.match_sources("nist_xps_db") + f.match_source_names("nist_xps_db") assert f.fetch_datasets_from_results() == res04 # Fetch nothing @@ -764,7 +694,7 @@ def test_forge_aggregate(): def test_forge_reset_query(): f = forge.Forge(index="mdf") # Term will return results - f.match_field("elements", "Al") + f.match_field("material.elements", "Al") f.reset_query() # Specifying no query will return no results assert f.search() == [] @@ -873,9 +803,9 @@ def test_forge_http_stream(capsys): def test_forge_chaining(): f = forge.Forge(index="mdf") f.match_field("source_name", "cip") - f.match_field("elements", "Al") + f.match_field("material.elements", "Al") res1 = f.search() - res2 = f.match_field("source_name", "cip").match_field("elements", "Al").search() + res2 = f.match_field("source_name", "cip").match_field("material.elements", "Al").search() assert all([r in res2 for r in res1]) and all([r in res1 for r in res2]) @@ -884,7 +814,7 @@ def test_forge_show_fields(): res1 = f.show_fields() assert "mdf" in res1.keys() res2 = f.show_fields(block="mdf", index="mdf") - assert "mdf.mdf_id" in res2.keys() + assert "mdf.source_name" in res2.keys() def test_forge_anonymous(capsys): From bc60ee25b7f0492401c92a9e40a90be7e2a72174 Mon Sep 17 00:00:00 2001 From: jgaff Date: Mon, 19 Mar 2018 14:18:31 -0500 Subject: [PATCH 03/10] Test dataset changes --- tests/test_forge.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test_forge.py b/tests/test_forge.py index 8160d38..6a7cf83 100644 --- a/tests/test_forge.py +++ b/tests/test_forge.py @@ -586,7 +586,7 @@ def test_forge_search(capsys): assert len(res4) == 3 # Check reset_query - f.match_field("mdf.source_name", "hopv") + f.match_field("mdf.source_name", "ta_melting") res5 = f.search(reset_query=False) res6 = f.search() assert all([r in res6 for r in res5]) and all([r in res5 for r in res6]) @@ -624,7 +624,7 @@ def test_forge_search_by_titles(): def test_forge_aggregate_sources(): # Test limit f = forge.Forge(index="mdf") - res1 = f.aggregate_sources("amcs") + res1 = f.aggregate_sources("nist_xps_db") assert isinstance(res1, list) assert len(res1) > 10000 assert isinstance(res1[0], dict) From b5bf0e022cd6379319c4a33bfb0b85da16e65953 Mon Sep 17 00:00:00 2001 From: jgaff Date: Thu, 22 Mar 2018 16:50:27 -0500 Subject: [PATCH 04/10] Fix download helpers in new schema --- mdf_forge/forge.py | 80 ++++++++++++++++++++------------------------- tests/test_forge.py | 2 +- 2 files changed, 36 insertions(+), 46 deletions(-) diff --git a/mdf_forge/forge.py b/mdf_forge/forge.py index 6e31042..d7604d0 100644 --- a/mdf_forge/forge.py +++ b/mdf_forge/forge.py @@ -1,16 +1,16 @@ import os -import requests import globus_sdk -from tqdm import tqdm - +import mdf_toolbox +import requests from six import print_, string_types +from six.moves.urllib.parse import urlparse +from tqdm import tqdm -import mdf_toolbox # Maximum recommended number of HTTP file transfers # Large transfers are much better suited to Globus Transfer use -HTTP_NUM_LIMIT = 2000 +HTTP_NUM_LIMIT = 50 # Maximum number of results per search allowed by Globus Search SEARCH_LIMIT = 10000 @@ -680,16 +680,15 @@ def http_download(self, results, dest=".", preserve_dir=False, verbose=True): + " entries.") } for res in tqdm(results, desc="Fetching files", disable=(not verbose)): - for key in res["mdf"]["links"].keys(): - dl = res["mdf"]["links"][key] - host = dl.get("http_host", None) if type(dl) is dict else None - if host: - remote_path = dl["path"] + for dl in res.get("files", []): + url = dl.get("url", None) + if url: + remote_path = urlparse(url).path # local_path should be either dest + whole path or dest + filename if preserve_dir: - local_path = os.path.normpath(dest + "/" + dl["path"]) + local_path = os.path.normpath(dest + "/" + remote_path) else: - local_path = os.path.normpath(dest + "/" + os.path.basename(dl["path"])) + local_path = os.path.normpath(dest + "/" + os.path.basename(remote_path)) # Make dirs for storing the file if they don't exist # preserve_dir doesn't matter; local_path has accounted for it already try: @@ -721,17 +720,17 @@ def http_download(self, results, dest=".", preserve_dir=False, verbose=True): local_path = local_path + new_add + ext headers = {} self.__mdf_authorizer.set_authorization_header(headers) - response = requests.get(host+remote_path, headers=headers) + response = requests.get(url, headers=headers) # Handle first 401 by regenerating auth headers if response.status_code == 401: self.__mdf_authorizer.handle_missing_authorization() self.__mdf_authorizer.set_authorization_header(headers) - self.response = requests.get(host+remote_path, headers=headers) + self.response = requests.get(url, headers=headers) # Handle other errors by passing the buck to the user if response.status_code != 200: - print_("Error ", response.status_code, - " when attempting to access '", - host+remote_path, "'", sep="") + print_("Error {} when attempting to access '{}'".format( + response.status_code, + url)) else: # Write out the binary response content with open(local_path, 'wb') as output: @@ -784,25 +783,20 @@ def globus_download(self, results, dest=".", dest_ep=None, preserve_dir=False, tasks = {} filenames = set() for res in tqdm(results, desc="Processing records", disable=(not verbose)): - found = False - for key in res["mdf"]["links"].keys(): + for dl in res.get("files", []): # Get the location of the data - dl = res["mdf"]["links"][key] - host = dl.get("globus_endpoint", None) if type(dl) is dict else None - + globus_link = dl.get("globus", None) # If the data is on a Globus Endpoint - # This filters keys that are not data links - if host: - found = True - remote_path = dl["path"] + if globus_link: + ep_id = urlparse(globus_link).netloc + ep_path = urlparse(globus_link).path # local_path should be either dest + whole path or dest + filename if preserve_dir: - # remote_path is absolute, so os.path.join does not work - local_path = os.path.abspath(dest + remote_path) + # ep_path is absolute, so os.path.join does not work + local_path = os.path.abspath(dest + ep_path) else: local_path = os.path.abspath( - os.path.join(dest, - os.path.basename(remote_path))) + os.path.join(dest, os.path.basename(ep_path))) # Make dirs for storing the file if they don't exist # preserve_dir doesn't matter; local_path has accounted for it already @@ -843,14 +837,12 @@ def globus_download(self, results, dest=".", dest_ep=None, preserve_dir=False, # Globus might timeout before it can be completely uploaded # So, we need to be able to check the size of the TD object and, # if need be, send it early - if host not in tasks.keys(): - tasks[host] = globus_sdk.TransferData(self.__transfer_client, - host, dest_ep, - verify_checksum=True) - tasks[host].add_item(remote_path, local_path) + if ep_id not in tasks.keys(): + tasks[ep_id] = globus_sdk.TransferData(self.__transfer_client, + ep_id, dest_ep, + verify_checksum=True) + tasks[ep_id].add_item(ep_path, local_path) filenames.add(local_path) - if not found: - print_("Error on record: No globus_endpoint provided.\nRecord: ", + str(res)) # Submit the jobs submissions = [] @@ -916,23 +908,21 @@ def http_stream(self, results, verbose=True): } return for res in results: - for key in res["mdf"]["links"].keys(): - dl = res["mdf"]["links"][key] - host = dl.get("http_host", None) if type(dl) is dict else None - if host: - remote_path = dl["path"] + for dl in res.get("files", []): + url = dl.get("url", None) + if url: headers = {} self.__mdf_authorizer.set_authorization_header(headers) - response = requests.get(host+remote_path, headers=headers) + response = requests.get(url, headers=headers) # Handle first 401 by regenerating auth headers if response.status_code == 401: self.__mdf_authorizer.handle_missing_authorization() self.__mdf_authorizer.set_authorization_header(headers) - self.response = requests.get(host+remote_path, headers=headers) + self.response = requests.get(url, headers=headers) # Handle other errors by passing the buck to the user if response.status_code != 200: print_("Error ", response.status_code, " when attempting to access '", - host+remote_path, "'", sep="") + url, "'", sep="") yield None else: yield response.text diff --git a/tests/test_forge.py b/tests/test_forge.py index 6a7cf83..c8a1dee 100644 --- a/tests/test_forge.py +++ b/tests/test_forge.py @@ -601,7 +601,7 @@ def test_forge_search_by_elements(): elements = ["Cu", "Al"] sources = ["oqmd", "nist_xps_db"] res1, info1 = f.match_source_names(sources).match_elements(elements).search(limit=10000, - info=True) + info=True) res2, info2 = f.search_by_elements(elements, sources, limit=10000, info=True) assert all([r in res2 for r in res1]) and all([r in res1 for r in res2]) assert check_field(res1, "material.elements", "Al") == 1 From 095781fee9f88e61f44d73b749586122292c82bf Mon Sep 17 00:00:00 2001 From: jgaff Date: Mon, 26 Mar 2018 10:05:25 -0500 Subject: [PATCH 05/10] Update test dataset usage --- tests/test_forge.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/test_forge.py b/tests/test_forge.py index c8a1dee..5837144 100644 --- a/tests/test_forge.py +++ b/tests/test_forge.py @@ -639,14 +639,14 @@ def test_forge_fetch_datasets_from_results(): res02 = f.search("mdf.source_name:oqmd AND mdf.resource_type:record", advanced=True, limit=1, info=True) # Records from JANAF - res03 = f.search("mdf.source_name:nist_janaf AND mdf.resource_type:record", + res03 = f.search("mdf.source_name:khazana_vasp AND mdf.resource_type:record", advanced=True, limit=2) # Dataset for NIST XPS DB res04 = f.search("mdf.source_name:nist_xps_db AND mdf.resource_type:dataset", advanced=True) # Get the correct dataset entries oqmd = f.search("mdf.source_name:oqmd AND mdf.resource_type:dataset", advanced=True)[0] - nist_janaf = f.search("mdf.source_name:nist_janaf AND mdf.resource_type:dataset", + khazana_vasp = f.search("mdf.source_name:khazana_vasp AND mdf.resource_type:dataset", advanced=True)[0] # Fetch single dataset @@ -662,7 +662,7 @@ def test_forge_fetch_datasets_from_results(): res3 = f.fetch_datasets_from_results(rtemp) assert len(res3) == 2 assert oqmd in res3 - assert nist_janaf in res3 + assert khazana_vasp in res3 # Fetch dataset from dataset res4 = f.fetch_datasets_from_results(res04) From d8b4c2436ef2056b241bbc439ae1d115f0b58d32 Mon Sep 17 00:00:00 2001 From: jgaff Date: Thu, 5 Apr 2018 09:07:27 -0500 Subject: [PATCH 06/10] Myriad minor Forge improvements --- .travis.yml | 4 +- mdf_forge/forge.py | 25 +++--- tests/test_forge.py | 184 +++++++++++++++++++++++--------------------- travis.tar.enc | Bin 10256 -> 10256 bytes 4 files changed, 114 insertions(+), 99 deletions(-) diff --git a/.travis.yml b/.travis.yml index fd6bba6..d0339ce 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,8 +16,8 @@ before_install: - openssl aes-256-cbc -K $encrypted_39a50b90a369_key -iv $encrypted_39a50b90a369_iv -in travis.tar.enc -out travis.tar -d - tar xvf travis.tar -- mkdir -p ~/mdf/credentials/ -- mv MDF_Forge_tokens.json ~/mdf/credentials/MDF_Forge_tokens.json +- mkdir -p ~/.mdf/credentials/ +- mv MDF_Forge_tokens.json ~/.mdf/credentials/MDF_Forge_tokens.json after_success: - coveralls notifications: diff --git a/mdf_forge/forge.py b/mdf_forge/forge.py index d7604d0..92dd1b6 100644 --- a/mdf_forge/forge.py +++ b/mdf_forge/forge.py @@ -1,4 +1,5 @@ import os +import re import globus_sdk import mdf_toolbox @@ -26,7 +27,7 @@ class Forge: index is the Globus Search index to be used. """ __default_index = "mdf" - __auth_services = ["mdf", "transfer", "search"] + __auth_services = ["data_mdf", "transfer", "search", "petrel"] __anon_services = ["search"] __app_name = "MDF_Forge" @@ -61,7 +62,8 @@ def __init__(self, index=__default_index, local_ep=None, anonymous=False, **kwar "index": self.index}) self.__search_client = clients.get("search") self.__transfer_client = clients.get("transfer") - self.__mdf_authorizer = clients.get("mdf") + self.__data_mdf_authorizer = clients.get("data_mdf") + self.__petrel_authorizer = clients.get("petrel") self.__query = Query(self.__search_client) @@ -75,7 +77,7 @@ def transfer_client(self): @property def mdf_authorizer(self): - return self.__mdf_authorizer + return self.__data_mdf_authorizer # *********************************************** @@ -368,6 +370,9 @@ def match_source_names(self, source_names): return self if isinstance(source_names, string_types): source_names = [source_names] + # If no version supplied, add * to each source name to match all versions + source_names = [(sn+"*" if re.search(".*_v[0-9]+", sn) is None else sn) + for sn in source_names] # First source should be in new group and required self.match_field(field="mdf.source_name", value=source_names[0], required=True, new_group=True) @@ -719,12 +724,12 @@ def http_download(self, results, dest=".", preserve_dir=False, verbose=True): else: local_path = local_path + new_add + ext headers = {} - self.__mdf_authorizer.set_authorization_header(headers) + self.__data_mdf_authorizer.set_authorization_header(headers) response = requests.get(url, headers=headers) # Handle first 401 by regenerating auth headers if response.status_code == 401: - self.__mdf_authorizer.handle_missing_authorization() - self.__mdf_authorizer.set_authorization_header(headers) + self.__data_mdf_authorizer.handle_missing_authorization() + self.__data_mdf_authorizer.set_authorization_header(headers) self.response = requests.get(url, headers=headers) # Handle other errors by passing the buck to the user if response.status_code != 200: @@ -892,7 +897,7 @@ def http_stream(self, results, verbose=True): # If results have info attached, remove it if type(results) is tuple: results = results[0] - elif type(results) is not list: + if type(results) is not list: results = [results] if len(results) > HTTP_NUM_LIMIT: print_("Too many results supplied. Use globus_download()" @@ -912,12 +917,12 @@ def http_stream(self, results, verbose=True): url = dl.get("url", None) if url: headers = {} - self.__mdf_authorizer.set_authorization_header(headers) + self.__data_mdf_authorizer.set_authorization_header(headers) response = requests.get(url, headers=headers) # Handle first 401 by regenerating auth headers if response.status_code == 401: - self.__mdf_authorizer.handle_missing_authorization() - self.__mdf_authorizer.set_authorization_header(headers) + self.__data_mdf_authorizer.handle_missing_authorization() + self.__data_mdf_authorizer.set_authorization_header(headers) self.response = requests.get(url, headers=headers) # Handle other errors by passing the buck to the user if response.status_code != 200: diff --git a/tests/test_forge.py b/tests/test_forge.py index 5837144..e826c41 100644 --- a/tests/test_forge.py +++ b/tests/test_forge.py @@ -1,10 +1,12 @@ import os +import re import types -import pytest + import globus_sdk from globus_sdk.exc import SearchAPIError from mdf_forge import forge import mdf_toolbox +import pytest # Manually logging in for Query testing @@ -142,23 +144,23 @@ def test_query_search(capsys): assert isinstance(res3[1], dict) # Check limit - res4 = q.search("oqmd", index="mdf", limit=3) + res4 = q.search("Al", index="mdf", limit=3) assert len(res4) == 3 # Check limit correction - res5 = q.search("nist_xps_db", index="mdf", limit=20000) + res5 = q.search("mdf.source_name:nist_xps_db*", advanced=True, index="mdf", limit=20000) assert len(res5) == 10000 # Test index translation - # mdf = d6cc98c3-ff53-4ee2-b22b-c6f945c0d30c + # mdf = 1a57bbe5-5272-477f-9d31-343b8258b7a5 res6 = q.search(q="data", index="mdf", limit=1, info=True) assert len(res6[0]) == 1 assert res6[1]["index"] == "mdf" - assert res6[1]["index_uuid"] == "d6cc98c3-ff53-4ee2-b22b-c6f945c0d30c" - res7 = q.search(q="data", index="d6cc98c3-ff53-4ee2-b22b-c6f945c0d30c", limit=1, info=True) + assert res6[1]["index_uuid"] == "1a57bbe5-5272-477f-9d31-343b8258b7a5" + res7 = q.search(q="data", index="1a57bbe5-5272-477f-9d31-343b8258b7a5", limit=1, info=True) assert len(res7[0]) == 1 - assert res7[1]["index"] == "d6cc98c3-ff53-4ee2-b22b-c6f945c0d30c" - assert res7[1]["index_uuid"] == "d6cc98c3-ff53-4ee2-b22b-c6f945c0d30c" + assert res7[1]["index"] == "1a57bbe5-5272-477f-9d31-343b8258b7a5" + assert res7[1]["index_uuid"] == "1a57bbe5-5272-477f-9d31-343b8258b7a5" with pytest.raises(SearchAPIError): q.search(q="data", index="invalid", limit=1, info=True) @@ -176,29 +178,29 @@ def test_query_aggregate(capsys): assert "Error: No index specified" in out # Basic aggregation - res1 = q.aggregate("mdf.source_name:nist_xps_db", index="mdf") + res1 = q.aggregate("mdf.source_name:nist_xps_db*", index="mdf") assert len(res1) > 10000 assert isinstance(res1[0], dict) # Multi-dataset aggregation - res2 = q.aggregate("(mdf.source_name:nist_xps_db OR mdf.source_name:khazana_vasp)", + res2 = q.aggregate("(mdf.source_name:nist_xps_db* OR mdf.source_name:khazana_vasp*)", index="mdf") assert len(res2) > 10000 assert len(res2) > len(res1) # Unnecessary aggregation fallback to .search() # Check success in Coveralls - assert len(q.aggregate("mdf.source_name:khazana_vasp")) < 10000 + assert len(q.aggregate("mdf.source_name:khazana_vasp*")) < 10000 def test_query_chaining(): q = forge.Query(query_search_client) - q.field("source_name", "cip") + q.field("source_name", "cip*") q.and_join() q.field("elements", "Al") res1 = q.search(limit=10000, index="mdf") res2 = (forge.Query(query_search_client) - .field("source_name", "cip") + .field("source_name", "cip*") .and_join() .field("elements", "Al") .search(limit=10000, index="mdf")) @@ -241,53 +243,38 @@ def test_forge_properties(): # Sample results for download testing example_result1 = { - 'mdf': { - 'links': { - 'landing_page': 'https://data.materialsdatafacility.org/test/test_fetch.txt', - 'txt': { - 'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec', - 'http_host': 'https://data.materialsdatafacility.org', - 'path': '/test/test_fetch.txt' - } - } - } - } + "files": [{ + "globus": "globus://82f1b5c6-6e9b-11e5-ba47-22000b92c6ec/test/test_fetch.txt", + "url": "https://data.materialsdatafacility.org/test/test_fetch.txt" + }] +} example_result2 = [{ - 'mdf': { - 'links': { - 'landing_page': 'https://data.materialsdatafacility.org/test/test_fetch.txt', - 'txt': { - 'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec', - 'http_host': 'https://data.materialsdatafacility.org', - 'path': '/test/test_fetch.txt' - } - } - } + "files": [{ + "globus": "globus://82f1b5c6-6e9b-11e5-ba47-22000b92c6ec/test/test_fetch.txt", + "url": "https://data.materialsdatafacility.org/test/test_fetch.txt" + }] +}, { + "files": [{ + "globus": "globus://82f1b5c6-6e9b-11e5-ba47-22000b92c6ec/test/test_multifetch.txt", + "url": "https://data.materialsdatafacility.org/test/test_multifetch.txt" + }] +}] +example_result3 = { + "files": [{ + "globus": "globus://82f1b5c6-6e9b-11e5-ba47-22000b92c6ec/test/test_fetch.txt", + "url": "https://data.materialsdatafacility.org/test/test_fetch.txt" }, { - 'mdf': { - 'links': { - 'landing_page': 'https://data.materialsdatafacility.org/test/test_multifetch.txt', - 'txt': { - 'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec', - 'http_host': 'https://data.materialsdatafacility.org', - 'path': '/test/test_multifetch.txt' - } - } - } + "globus": "globus://82f1b5c6-6e9b-11e5-ba47-22000b92c6ec/test/test_multifetch.txt", + "url": "https://data.materialsdatafacility.org/test/test_multifetch.txt" }] +} # NOTE: This example file does not exist -example_result_missing = [{ - 'mdf': { - 'links': { - 'landing_page': 'https://data.materialsdatafacility.org/test/missing.txt', - 'txt': { - 'globus_endpoint': '82f1b5c6-6e9b-11e5-ba47-22000b92c6ec', - 'http_host': 'https://data.materialsdatafacility.org', - 'path': '/test/missing.txt' - } - } - } +example_result_missing = { + "files": [{ + "globus": "globus://82f1b5c6-6e9b-11e5-ba47-22000b92c6ec/test/missing.txt", + "url": "https://data.materialsdatafacility.org/test/missing.txt" }] +} # Helper @@ -296,10 +283,13 @@ def test_forge_properties(): # 0: Exclusive match, no values other than argument found # 1: Inclusive match, some values other than argument found # 2: Partial match, value is found in some but not all results -def check_field(res, field, value): +def check_field(res, field, regex): dict_path = "" for key in field.split("."): - dict_path += "['{}']".format(key) + if key == "[]": + dict_path += "[0]" + else: + dict_path += "['{}']".format(key) # If no results, set matches to false all_match = (len(res) > 0) only_match = (len(res) > 0) @@ -309,7 +299,7 @@ def check_field(res, field, value): if type(vals) is not list: vals = [vals] # If a result does not contain the value, no match - if value not in vals: + if regex not in vals and not any([re.search(str(regex), value) for value in vals]): all_match = False only_match = False # If a result contains other values, inclusive match @@ -336,7 +326,7 @@ def check_field(res, field, value): def test_forge_match_field(): f = forge.Forge(index="mdf") # Basic usage - f.match_field("mdf.source_name", "khazana_vasp") + f.match_field("mdf.source_name", "khazana_vasp*") res1 = f.search() assert check_field(res1, "mdf.source_name", "khazana_vasp") == 0 # Check that query clears @@ -352,7 +342,7 @@ def test_forge_exclude_field(): f = forge.Forge(index="mdf") # Basic usage f.exclude_field("material.elements", "Al") - f.match_field("mdf.source_name", "ab_initio_solute_database") + f.match_field("mdf.source_name", "ab_initio_solute_database*") res1 = f.search() assert check_field(res1, "material.elements", "Al") == -1 @@ -387,6 +377,7 @@ def test_forge_exclude_range(): f = forge.Forge(index="mdf") f.exclude_range("material.elements", "Am", "*") f.exclude_range("material.elements", "*", "Ak") + f.match_field("material.elements", "*") res1, info1 = f.search(info=True) assert (check_field(res1, "material.elements", "Al") == 0 or check_field(res1, "material.elements", "Al") == 2) @@ -398,6 +389,7 @@ def test_forge_exclude_range(): f.exclude_range("material.elements", "Am", "*") f.exclude_range("material.elements", "*", "Ak") f.exclude_range("material.elements", "Al", "Al", inclusive=False) + f.match_field("material.elements", "*") res3, info3 = f.search(info=True) assert info1["total_query_matches"] == info3["total_query_matches"] @@ -442,7 +434,7 @@ def test_forge_match_source_names(): def test_forge_match_ids(): # Get a couple IDs f = forge.Forge(index="mdf") - res0 = f.search("mdf.source_name:khazana_vasp", advanced=True, limit=2) + res0 = f.search("mdf.source_name:khazana_vasp*", advanced=True, limit=2) id1 = res0[0]["mdf"]["mdf_id"] id2 = res0[1]["mdf"]["mdf_id"] @@ -489,7 +481,7 @@ def test_forge_match_titles(): titles1 = '"High-throughput Ab-initio Dilute Solute Diffusion Database"' res1 = f.match_titles(titles1).search() assert res1 != [] - assert check_field(res1, "dc.titles.title", + assert check_field(res1, "dc.titles.[].title", "High-throughput Ab-initio Dilute Solute Diffusion Database") == 0 # Multiple titles @@ -499,7 +491,7 @@ def test_forge_match_titles(): ] res2 = f.match_titles(titles2).search() assert res2 != [] - assert check_field(res2, "dc.titles.title", "Khazana (VASP)") == 2 + assert check_field(res2, "dc.titles.[].title", "Khazana (VASP)") == 2 # No titles assert f.match_titles("") == f @@ -513,8 +505,8 @@ def test_forge_match_years(capsys): assert check_field(res1, "dc.publicationYear", 2015) == 0 # Multiple years - res2 = f.match_years(years=["2015", 2011]).search() - assert check_field(res2, "dc.publicationYear", 2011) == 2 + res2 = f.match_years(years=["2015", 2016]).search() + assert check_field(res2, "dc.publicationYear", 2016) == 2 # Wrong input f.match_years(["20x5"]).search() @@ -582,11 +574,11 @@ def test_forge_search(capsys): assert isinstance(res3[1], dict) # Check limit - res4 = f.search("oqmd", limit=3) + res4 = f.search("Al", limit=3) assert len(res4) == 3 # Check reset_query - f.match_field("mdf.source_name", "ta_melting") + f.match_field("mdf.source_name", "ta_melting*") res5 = f.search(reset_query=False) res6 = f.search() assert all([r in res6 for r in res5]) and all([r in res5 for r in res6]) @@ -612,13 +604,13 @@ def test_forge_search_by_titles(): f = forge.Forge(index="mdf") titles1 = ['"High-throughput Ab-initio Dilute Solute Diffusion Database"'] res1 = f.search_by_titles(titles1) - assert check_field(res1, "dc.titles.title", + assert check_field(res1, "dc.titles.[].title", "High-throughput Ab-initio Dilute Solute Diffusion Database") == 0 - titles2 = ["Diffusion"] + titles2 = ["Database"] res2 = f.search_by_titles(titles2) - assert check_field(res2, "mdf.title", - "High-throughput Ab-initio Dilute Solute Diffusion Database") == 2 + assert check_field(res2, "dc.titles.[].title", + "NIST X-ray Photoelectron Spectroscopy Database") == 2 def test_forge_aggregate_sources(): @@ -634,20 +626,20 @@ def test_forge_fetch_datasets_from_results(): # Get some results f = forge.Forge(index="mdf") # Record from OQMD - res01 = f.search("mdf.source_name:oqmd AND mdf.resource_type:record", advanced=True, limit=1) + res01 = f.search("mdf.source_name:oqmd* AND mdf.resource_type:record", advanced=True, limit=1) # Record from OQMD with info - res02 = f.search("mdf.source_name:oqmd AND mdf.resource_type:record", + res02 = f.search("mdf.source_name:oqmd* AND mdf.resource_type:record", advanced=True, limit=1, info=True) # Records from JANAF - res03 = f.search("mdf.source_name:khazana_vasp AND mdf.resource_type:record", + res03 = f.search("mdf.source_name:khazana_vasp* AND mdf.resource_type:record", advanced=True, limit=2) # Dataset for NIST XPS DB - res04 = f.search("mdf.source_name:nist_xps_db AND mdf.resource_type:dataset", advanced=True) + res04 = f.search("mdf.source_name:nist_xps_db* AND mdf.resource_type:dataset", advanced=True) # Get the correct dataset entries - oqmd = f.search("mdf.source_name:oqmd AND mdf.resource_type:dataset", advanced=True)[0] - khazana_vasp = f.search("mdf.source_name:khazana_vasp AND mdf.resource_type:dataset", - advanced=True)[0] + oqmd = f.search("mdf.source_name:oqmd* AND mdf.resource_type:dataset", advanced=True)[0] + khazana_vasp = f.search("mdf.source_name:khazana_vasp* AND mdf.resource_type:dataset", + advanced=True)[0] # Fetch single dataset res1 = f.fetch_datasets_from_results(res01[0]) @@ -682,7 +674,7 @@ def test_forge_aggregate(): # And returns results # And respects the reset_query arg f = forge.Forge(index="mdf") - f.match_field("mdf.source_name", "nist_xps_db") + f.match_field("mdf.source_name", "nist_xps_db*") res1 = f.aggregate(reset_query=False, index="mdf") assert len(res1) > 10000 assert check_field(res1, "mdf.source_name", "nist_xps_db") == 0 @@ -736,6 +728,12 @@ def test_forge_http_download(capsys): os.remove(os.path.join(dest_path, "test_fetch.txt")) os.remove(os.path.join(dest_path, "test_multifetch.txt")) + f.http_download(example_result3, dest=dest_path) + assert os.path.exists(os.path.join(dest_path, "test_fetch.txt")) + assert os.path.exists(os.path.join(dest_path, "test_multifetch.txt")) + os.remove(os.path.join(dest_path, "test_fetch.txt")) + os.remove(os.path.join(dest_path, "test_multifetch.txt")) + # Too many files assert f.http_download(list(range(10001)))["success"] is False @@ -769,6 +767,12 @@ def test_forge_globus_download(): os.remove(os.path.join(dest_path, "test_fetch.txt")) os.remove(os.path.join(dest_path, "test_multifetch.txt")) + f.globus_download(example_result3, dest=dest_path) + assert os.path.exists(os.path.join(dest_path, "test_fetch.txt")) + assert os.path.exists(os.path.join(dest_path, "test_multifetch.txt")) + os.remove(os.path.join(dest_path, "test_fetch.txt")) + os.remove(os.path.join(dest_path, "test_multifetch.txt")) + def test_forge_http_stream(capsys): f = forge.Forge(index="mdf") @@ -783,14 +787,19 @@ def test_forge_http_stream(capsys): assert next(res2) == "This is a test document for Forge testing. Please do not remove.\n" assert next(res2) == "This is a second test document for Forge testing. Please do not remove.\n" + res3 = f.http_stream((example_result3, {"info": {}})) + assert isinstance(res3, types.GeneratorType) + assert next(res3) == "This is a test document for Forge testing. Please do not remove.\n" + assert next(res3) == "This is a second test document for Forge testing. Please do not remove.\n" + # Too many results - res3 = f.http_stream(list(range(10001))) - assert next(res3)["success"] is False + res4 = f.http_stream(list(range(10001))) + assert next(res4)["success"] is False out, err = capsys.readouterr() assert ("Too many results supplied. Use globus_download() for " - "fetching more than 2000 entries.") in out + "fetching more than") in out with pytest.raises(StopIteration): - next(res3) + next(res4) # "Missing" files assert next(f.http_stream(example_result_missing)) is None @@ -802,10 +811,10 @@ def test_forge_http_stream(capsys): def test_forge_chaining(): f = forge.Forge(index="mdf") - f.match_field("source_name", "cip") + f.match_field("source_name", "cip*") f.match_field("material.elements", "Al") res1 = f.search() - res2 = f.match_field("source_name", "cip").match_field("material.elements", "Al").search() + res2 = f.match_field("source_name", "cip*").match_field("material.elements", "Al").search() assert all([r in res2 for r in res1]) and all([r in res1 for r in res2]) @@ -820,10 +829,11 @@ def test_forge_show_fields(): def test_forge_anonymous(capsys): f = forge.Forge(anonymous=True) # Test search - assert len(f.search("mdf.source_name:oqmd", advanced=True, limit=300)) == 300 + assert len(f.search("mdf.source_name:ab_initio_solute_database*", + advanced=True, limit=300)) == 300 # Test aggregation - assert len(f.aggregate("mdf.source_name:nist_xps_db")) > 10000 + assert len(f.aggregate("mdf.source_name:nist_xps_db*")) > 10000 # Error on auth-only functions # http_download diff --git a/travis.tar.enc b/travis.tar.enc index 20ae82383bc4767136f4d9a5a118a75f6b823284..e2bdc0c8ce696b6e0030cf0ef58b1594bf6b726a 100644 GIT binary patch literal 10256 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 W5uC7XKE(f%zNYr??fe5g1d8~L5&R4Q From 0c875f11126adf24e4882f0ecadfd9e12be05adb Mon Sep 17 00:00:00 2001 From: jgaff Date: Thu, 5 Apr 2018 13:31:09 -0500 Subject: [PATCH 07/10] Petrel HTTPS support --- mdf_forge/forge.py | 40 ++++++++++++++++++++++++--------- setup.py | 4 ++-- tests/test_forge.py | 53 +++++++++++++++++++++++++++++++++++++------- travis.tar.enc | Bin 10256 -> 10256 bytes 4 files changed, 76 insertions(+), 21 deletions(-) diff --git a/mdf_forge/forge.py b/mdf_forge/forge.py index 92dd1b6..b6b9243 100644 --- a/mdf_forge/forge.py +++ b/mdf_forge/forge.py @@ -62,8 +62,8 @@ def __init__(self, index=__default_index, local_ep=None, anonymous=False, **kwar "index": self.index}) self.__search_client = clients.get("search") self.__transfer_client = clients.get("transfer") - self.__data_mdf_authorizer = clients.get("data_mdf") - self.__petrel_authorizer = clients.get("petrel") + self.__data_mdf_authorizer = clients.get("data_mdf", globus_sdk.NullAuthorizer()) + self.__petrel_authorizer = clients.get("petrel", globus_sdk.NullAuthorizer()) self.__query = Query(self.__search_client) @@ -688,7 +688,8 @@ def http_download(self, results, dest=".", preserve_dir=False, verbose=True): for dl in res.get("files", []): url = dl.get("url", None) if url: - remote_path = urlparse(url).path + parsed_url = urlparse(url) + remote_path = parsed_url.path # local_path should be either dest + whole path or dest + filename if preserve_dir: local_path = os.path.normpath(dest + "/" + remote_path) @@ -724,13 +725,21 @@ def http_download(self, results, dest=".", preserve_dir=False, verbose=True): else: local_path = local_path + new_add + ext headers = {} - self.__data_mdf_authorizer.set_authorization_header(headers) + # Check for Petrel vs. NCSA url for authorizer + # Petrel + if parsed_url.netloc == "e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org": + authorizer = self.__petrel_authorizer + elif parsed_url.netloc == "data.materialsdatafacility.org": + authorizer = self.__data_mdf_authorizer + else: + authorizer = globus_sdk.NullAuthorizer() + authorizer.set_authorization_header(headers) response = requests.get(url, headers=headers) # Handle first 401 by regenerating auth headers if response.status_code == 401: - self.__data_mdf_authorizer.handle_missing_authorization() - self.__data_mdf_authorizer.set_authorization_header(headers) - self.response = requests.get(url, headers=headers) + authorizer.handle_missing_authorization() + authorizer.set_authorization_header(headers) + response = requests.get(url, headers=headers) # Handle other errors by passing the buck to the user if response.status_code != 200: print_("Error {} when attempting to access '{}'".format( @@ -916,14 +925,23 @@ def http_stream(self, results, verbose=True): for dl in res.get("files", []): url = dl.get("url", None) if url: + parsed_url = urlparse(url) headers = {} - self.__data_mdf_authorizer.set_authorization_header(headers) + # Check for Petrel vs. NCSA url for authorizer + # Petrel + if parsed_url.netloc == "e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org": + authorizer = self.__petrel_authorizer + elif parsed_url.netloc == "data.materialsdatafacility.org": + authorizer = self.__data_mdf_authorizer + else: + authorizer = globus_sdk.NullAuthorizer() + authorizer.set_authorization_header(headers) response = requests.get(url, headers=headers) # Handle first 401 by regenerating auth headers if response.status_code == 401: - self.__data_mdf_authorizer.handle_missing_authorization() - self.__data_mdf_authorizer.set_authorization_header(headers) - self.response = requests.get(url, headers=headers) + authorizer.handle_missing_authorization() + authorizer.set_authorization_header(headers) + response = requests.get(url, headers=headers) # Handle other errors by passing the buck to the user if response.status_code != 200: print_("Error ", response.status_code, " when attempting to access '", diff --git a/setup.py b/setup.py index bc7683f..3feca16 100644 --- a/setup.py +++ b/setup.py @@ -10,8 +10,8 @@ "Forge allows users to perform simple queries and " "facilitiates moving and synthesizing results."), install_requires=[ - "mdf-toolbox>=0.1.7", - "globus-sdk>=1.4.1", + "mdf-toolbox>=0.2.0", + "globus-sdk>=1.5.0", "requests>=2.18.4", "tqdm>=4.19.4", "six>=1.10.0" diff --git a/tests/test_forge.py b/tests/test_forge.py index e826c41..66c24ce 100644 --- a/tests/test_forge.py +++ b/tests/test_forge.py @@ -258,6 +258,20 @@ def test_forge_properties(): "globus": "globus://82f1b5c6-6e9b-11e5-ba47-22000b92c6ec/test/test_multifetch.txt", "url": "https://data.materialsdatafacility.org/test/test_multifetch.txt" }] +}, { + "files": [{ + "globus": ("globus://e38ee745-6d04-11e5-ba46-22000b92c6ec" + "/MDF/mdf_connect/test_files/petrel_fetch.txt"), + "url": ("https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org" + "/MDF/mdf_connect/test_files/petrel_fetch.txt") + }] +}, { + "files": [{ + "globus": ("globus://e38ee745-6d04-11e5-ba46-22000b92c6ec" + "/MDF/mdf_connect/test_files/petrel_multifetch.txt"), + "url": ("https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org" + "/MDF/mdf_connect/test_files/petrel_multifetch.txt") + }] }] example_result3 = { "files": [{ @@ -266,13 +280,23 @@ def test_forge_properties(): }, { "globus": "globus://82f1b5c6-6e9b-11e5-ba47-22000b92c6ec/test/test_multifetch.txt", "url": "https://data.materialsdatafacility.org/test/test_multifetch.txt" + }, { + "globus": ("globus://e38ee745-6d04-11e5-ba46-22000b92c6ec" + "/MDF/mdf_connect/test_files/petrel_fetch.txt"), + "url": ("https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org" + "/MDF/mdf_connect/test_files/petrel_fetch.txt") + }, { + "globus": ("globus://e38ee745-6d04-11e5-ba46-22000b92c6ec" + "/MDF/mdf_connect/test_files/petrel_multifetch.txt"), + "url": ("https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org" + "/MDF/mdf_connect/test_files/petrel_multifetch.txt") }] } # NOTE: This example file does not exist example_result_missing = { "files": [{ - "globus": "globus://82f1b5c6-6e9b-11e5-ba47-22000b92c6ec/test/missing.txt", - "url": "https://data.materialsdatafacility.org/test/missing.txt" + "globus": "globus://82f1b5c6-6e9b-11e5-ba47-22000b92c6ec/test/should_not_exist.txt", + "url": "https://data.materialsdatafacility.org/test/should_not_exist.txt" }] } @@ -725,24 +749,34 @@ def test_forge_http_download(capsys): f.http_download(example_result2, dest=dest_path) assert os.path.exists(os.path.join(dest_path, "test_fetch.txt")) assert os.path.exists(os.path.join(dest_path, "test_multifetch.txt")) + assert os.path.exists(os.path.join(dest_path, "petrel_fetch.txt")) + assert os.path.exists(os.path.join(dest_path, "petrel_multifetch.txt")) os.remove(os.path.join(dest_path, "test_fetch.txt")) os.remove(os.path.join(dest_path, "test_multifetch.txt")) + os.remove(os.path.join(dest_path, "petrel_fetch.txt")) + os.remove(os.path.join(dest_path, "petrel_multifetch.txt")) f.http_download(example_result3, dest=dest_path) assert os.path.exists(os.path.join(dest_path, "test_fetch.txt")) assert os.path.exists(os.path.join(dest_path, "test_multifetch.txt")) + assert os.path.exists(os.path.join(dest_path, "petrel_fetch.txt")) + assert os.path.exists(os.path.join(dest_path, "petrel_multifetch.txt")) os.remove(os.path.join(dest_path, "test_fetch.txt")) os.remove(os.path.join(dest_path, "test_multifetch.txt")) + os.remove(os.path.join(dest_path, "petrel_fetch.txt")) + os.remove(os.path.join(dest_path, "petrel_multifetch.txt")) # Too many files assert f.http_download(list(range(10001)))["success"] is False + out, err = capsys.readouterr() + assert "Too many results supplied. Use globus_download()" in out # "Missing" files f.http_download(example_result_missing) out, err = capsys.readouterr() - assert not os.path.exists("./missing.txt") + assert not os.path.exists("./should_not_exist.txt") assert ("Error 404 when attempting to access " - "'https://data.materialsdatafacility.org/test/missing.txt'") in out + "'https://data.materialsdatafacility.org/test/should_not_exist.txt'") in out @pytest.mark.xfail(reason="Test relies on get_local_ep() which can require user input.") @@ -786,27 +820,30 @@ def test_forge_http_stream(capsys): assert isinstance(res2, types.GeneratorType) assert next(res2) == "This is a test document for Forge testing. Please do not remove.\n" assert next(res2) == "This is a second test document for Forge testing. Please do not remove.\n" + assert next(res2) == "This is a test document for Forge testing. Please do not remove.\n" + assert next(res2) == "This is a second test document for Forge testing. Please do not remove.\n" res3 = f.http_stream((example_result3, {"info": {}})) assert isinstance(res3, types.GeneratorType) assert next(res3) == "This is a test document for Forge testing. Please do not remove.\n" assert next(res3) == "This is a second test document for Forge testing. Please do not remove.\n" + assert next(res3) == "This is a test document for Forge testing. Please do not remove.\n" + assert next(res3) == "This is a second test document for Forge testing. Please do not remove.\n" # Too many results res4 = f.http_stream(list(range(10001))) assert next(res4)["success"] is False out, err = capsys.readouterr() - assert ("Too many results supplied. Use globus_download() for " - "fetching more than") in out + assert "Too many results supplied. Use globus_download()" in out with pytest.raises(StopIteration): next(res4) # "Missing" files assert next(f.http_stream(example_result_missing)) is None out, err = capsys.readouterr() - assert not os.path.exists("./missing.txt") + assert not os.path.exists("./should_not_exist.txt") assert ("Error 404 when attempting to access " - "'https://data.materialsdatafacility.org/test/missing.txt'") in out + "'https://data.materialsdatafacility.org/test/should_not_exist.txt'") in out def test_forge_chaining(): diff --git a/travis.tar.enc b/travis.tar.enc index e2bdc0c8ce696b6e0030cf0ef58b1594bf6b726a..0464f13a59df6d11b6c80da6a72ab3c75858ea03 100644 GIT binary patch literal 10256 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 literal 10256 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 Date: Thu, 5 Apr 2018 14:59:58 -0500 Subject: [PATCH 08/10] Minor style change --- mdf_forge/__init__.py | 2 +- setup.cfg | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mdf_forge/__init__.py b/mdf_forge/__init__.py index 6e5db86..a193608 100644 --- a/mdf_forge/__init__.py +++ b/mdf_forge/__init__.py @@ -1 +1 @@ -from .forge import Forge +from .forge import Forge # noqa: F401 diff --git a/setup.cfg b/setup.cfg index 73c5409..585ec41 100644 --- a/setup.cfg +++ b/setup.cfg @@ -6,5 +6,5 @@ universal = 1 addopts = --ignore=setup.py --cov=mdf_forge [flake8] -exclude = .git,*.egg*, *__init__.py +exclude = .git,*.egg* max-line-length = 100 From 68dcab5c76826e431365047cc7c1e4358b3f08ed Mon Sep 17 00:00:00 2001 From: jgaff Date: Wed, 11 Apr 2018 09:12:13 -0500 Subject: [PATCH 09/10] Limit non-advanced queries to 10 results be default --- mdf_forge/forge.py | 8 ++++++-- tests/test_forge.py | 26 ++++++++++++++++---------- 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/mdf_forge/forge.py b/mdf_forge/forge.py index b6b9243..947713b 100644 --- a/mdf_forge/forge.py +++ b/mdf_forge/forge.py @@ -14,6 +14,8 @@ HTTP_NUM_LIMIT = 50 # Maximum number of results per search allowed by Globus Search SEARCH_LIMIT = 10000 +# Maximum number of results to return when advanced=False +NONADVANCED_LIMIT = 10 class Forge: @@ -1118,7 +1120,7 @@ def negate(self): self.operator("NOT") return self - def search(self, q=None, index=None, advanced=None, limit=SEARCH_LIMIT, info=False): + def search(self, q=None, index=None, advanced=None, limit=None, info=False): """Execute a search and return the results. Arguments: @@ -1132,6 +1134,8 @@ def search(self, q=None, index=None, advanced=None, limit=SEARCH_LIMIT, info=Fal the query is built with helpers. limit (int): The maximum number of results to return. The max for this argument is the SEARCH_LIMIT imposed by Globus Search. + The default for advanced-mode queries is SEARCH_LIMIT. + The default for non-advanced queries is NONADVANCED_LIMIT. info (bool): If False, search will return a list of the results. If True, search will return a tuple containing the results list and other information about the query. @@ -1154,7 +1158,7 @@ def search(self, q=None, index=None, advanced=None, limit=SEARCH_LIMIT, info=Fal if advanced is None or self.advanced: advanced = self.advanced if limit is None: - limit = self.limit or SEARCH_LIMIT + limit = self.limit or (SEARCH_LIMIT if advanced else NONADVANCED_LIMIT) if limit > SEARCH_LIMIT: limit = SEARCH_LIMIT diff --git a/tests/test_forge.py b/tests/test_forge.py index 66c24ce..3cf1f29 100644 --- a/tests/test_forge.py +++ b/tests/test_forge.py @@ -147,20 +147,26 @@ def test_query_search(capsys): res4 = q.search("Al", index="mdf", limit=3) assert len(res4) == 3 + # Check default limits + res5 = q.search("Al", index="mdf") + assert len(res5) == 10 + res6 = q.search("mdf.source_name:nist_xps_db*", advanced=True, index="mdf") + assert len(res6) == 10000 + # Check limit correction - res5 = q.search("mdf.source_name:nist_xps_db*", advanced=True, index="mdf", limit=20000) - assert len(res5) == 10000 + res7 = q.search("mdf.source_name:nist_xps_db*", advanced=True, index="mdf", limit=20000) + assert len(res7) == 10000 # Test index translation # mdf = 1a57bbe5-5272-477f-9d31-343b8258b7a5 - res6 = q.search(q="data", index="mdf", limit=1, info=True) - assert len(res6[0]) == 1 - assert res6[1]["index"] == "mdf" - assert res6[1]["index_uuid"] == "1a57bbe5-5272-477f-9d31-343b8258b7a5" - res7 = q.search(q="data", index="1a57bbe5-5272-477f-9d31-343b8258b7a5", limit=1, info=True) - assert len(res7[0]) == 1 - assert res7[1]["index"] == "1a57bbe5-5272-477f-9d31-343b8258b7a5" - assert res7[1]["index_uuid"] == "1a57bbe5-5272-477f-9d31-343b8258b7a5" + res8 = q.search(q="data", index="mdf", limit=1, info=True) + assert len(res8[0]) == 1 + assert res8[1]["index"] == "mdf" + assert res8[1]["index_uuid"] == "1a57bbe5-5272-477f-9d31-343b8258b7a5" + res9 = q.search(q="data", index="1a57bbe5-5272-477f-9d31-343b8258b7a5", limit=1, info=True) + assert len(res9[0]) == 1 + assert res9[1]["index"] == "1a57bbe5-5272-477f-9d31-343b8258b7a5" + assert res9[1]["index_uuid"] == "1a57bbe5-5272-477f-9d31-343b8258b7a5" with pytest.raises(SearchAPIError): q.search(q="data", index="invalid", limit=1, info=True) From a55b52f89a1589d800a7f815a1db01b75f21c718 Mon Sep 17 00:00:00 2001 From: jgaff Date: Wed, 11 Apr 2018 15:02:07 -0500 Subject: [PATCH 10/10] Re-run examples for output --- docs/examples/Example Aggregations.ipynb | 241 ++++++++- .../Example Statistics - MDF Datasets.ipynb | 209 +++++++- docs/tutorials/1 - Introduction.ipynb | 121 ++++- .../2 - Core Query Builder Functions.ipynb | 141 +++++- ...3 - Expanded Query Builder Functions.ipynb | 472 ++++++++++++++++- .../4 - General Helper Functions.ipynb | 345 +++++++++++-- .../5 - Field-Specific Helper Functions.ipynb | 474 ++++++++++++++++-- .../6 - Data Retrieval Functions.ipynb | 45 +- mdf_forge/forge.py | 2 +- 9 files changed, 1902 insertions(+), 148 deletions(-) diff --git a/docs/examples/Example Aggregations.ipynb b/docs/examples/Example Aggregations.ipynb index 8d0145e..814b4b0 100644 --- a/docs/examples/Example Aggregations.ipynb +++ b/docs/examples/Example Aggregations.ipynb @@ -16,7 +16,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -26,7 +26,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -38,36 +38,114 @@ "metadata": {}, "source": [ "## aggregate_source - NIST XPS DB\n", - "Example: We want to collect all records from the NIST XPS Database and analyze the quality metrics. This database has almost 30,000 records, so we have to use `aggregate()`." + "Example: We want to collect all records from the NIST XPS Database and analyze the binding energies. This database has almost 30,000 records, so we have to use `aggregate()`." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 29189/29189 [00:27<00:00, 1056.63it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "29189\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], "source": [ "# First, let's aggregate all the nist_xps_db data.\n", - "all_entries = mdf.aggregate_source_names(\"nist_xps_db\")\n", + "all_entries = mdf.aggregate_sources(\"nist_xps_db\")\n", "print(len(all_entries))" ] }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 4, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"\": 24344,\n", + " \"0.001\": 2,\n", + " \"0.003\": 2,\n", + " \"0.005\": 12,\n", + " \"0.01\": 27,\n", + " \"0.010\": 3,\n", + " \"0.012\": 2,\n", + " \"0.015\": 2,\n", + " \"0.02\": 159,\n", + " \"0.020\": 6,\n", + " \"0.025\": 10,\n", + " \"0.026\": 1,\n", + " \"0.03\": 122,\n", + " \"0.030\": 14,\n", + " \"0.04\": 56,\n", + " \"0.042\": 1,\n", + " \"0.05\": 416,\n", + " \"0.050\": 1,\n", + " \"0.06\": 12,\n", + " \"0.07\": 33,\n", + " \"0.070\": 1,\n", + " \"0.075\": 1,\n", + " \"0.08\": 14,\n", + " \"0.1\": 1501,\n", + " \"0.10\": 14,\n", + " \"0.100\": 2,\n", + " \"0.12\": 4,\n", + " \"0.13\": 1,\n", + " \"0.15\": 220,\n", + " \"0.17\": 1,\n", + " \"0.2\": 1660,\n", + " \"0.20\": 2,\n", + " \"0.200\": 1,\n", + " \"0.25\": 24,\n", + " \"0.3\": 266,\n", + " \"0.30\": 4,\n", + " \"0.4\": 117,\n", + " \"0.40\": 4,\n", + " \"0.5\": 108,\n", + " \"0.6\": 9,\n", + " \"0.7\": 2,\n", + " \"0.8\": 4,\n", + " \"0.9\": 2,\n", + " \"1.2\": 1,\n", + " \"2.0\": 1\n", + "}\n" + ] + } + ], "source": [ - "# Now, let's parse out the \"Quality of Data\" and print te results for analysis.\n", - "qualities = {}\n", + "# Now, let's parse out the enery_uncertainty_ev and print the results for analysis.\n", + "uncertainties = {}\n", "for record in all_entries:\n", " if record[\"mdf\"][\"resource_type\"] == \"record\":\n", - " raw = json.loads(record[\"mdf\"][\"raw\"])\n", - " if raw[\"Quality of Data\"] in qualities.keys():\n", - " qualities[raw[\"Quality of Data\"]] += 1\n", + " unc = record.get(\"nist_xps_db_v1\", {}).get(\"energy_uncertainty_ev\", 0)\n", + " if not uncertainties.get(unc):\n", + " uncertainties[unc] = 1\n", " else:\n", - " qualities[raw[\"Quality of Data\"]] = 1\n", - "print(qualities)" + " uncertainties[unc] += 1\n", + "print(json.dumps(uncertainties, sort_keys=True, indent=4, separators=(',', ': ')))" ] }, { @@ -80,9 +158,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 25582/25582 [01:03<00:00, 381.77it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "25582\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], "source": [ "# First, let's aggregate everything that has \"Ga\" in the list of elements.\n", "all_results = mdf.aggregate(\"material.elements:Ga\")\n", @@ -91,9 +191,108 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 6, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "{\n", + " \"Ac\": 651,\n", + " \"Ag\": 550,\n", + " \"Al\": 556,\n", + " \"Ar\": 2,\n", + " \"As\": 1296,\n", + " \"Au\": 589,\n", + " \"B\": 528,\n", + " \"Ba\": 670,\n", + " \"Be\": 496,\n", + " \"Bi\": 550,\n", + " \"Br\": 52,\n", + " \"C\": 85,\n", + " \"Ca\": 613,\n", + " \"Cd\": 562,\n", + " \"Ce\": 599,\n", + " \"Cl\": 75,\n", + " \"Co\": 875,\n", + " \"Cr\": 678,\n", + " \"Cs\": 501,\n", + " \"Cu\": 741,\n", + " \"Dy\": 578,\n", + " \"Er\": 641,\n", + " \"Eu\": 561,\n", + " \"F\": 105,\n", + " \"Fe\": 708,\n", + " \"Ga\": 25582,\n", + " \"Gd\": 575,\n", + " \"Ge\": 643,\n", + " \"H\": 167,\n", + " \"Hf\": 630,\n", + " \"Hg\": 526,\n", + " \"Ho\": 567,\n", + " \"I\": 59,\n", + " \"In\": 585,\n", + " \"Ir\": 543,\n", + " \"K\": 583,\n", + " \"La\": 719,\n", + " \"Li\": 851,\n", + " \"Lu\": 513,\n", + " \"Mg\": 1004,\n", + " \"Mn\": 608,\n", + " \"Mo\": 635,\n", + " \"N\": 150,\n", + " \"Na\": 722,\n", + " \"Nb\": 539,\n", + " \"Nd\": 573,\n", + " \"Ni\": 754,\n", + " \"Np\": 503,\n", + " \"O\": 2514,\n", + " \"On\": 6,\n", + " \"Os\": 665,\n", + " \"Ox\": 39,\n", + " \"P\": 160,\n", + " \"Pa\": 609,\n", + " \"Pb\": 519,\n", + " \"Pd\": 604,\n", + " \"Pm\": 624,\n", + " \"Pr\": 692,\n", + " \"Pt\": 699,\n", + " \"Pu\": 527,\n", + " \"Rb\": 544,\n", + " \"Re\": 496,\n", + " \"Rh\": 554,\n", + " \"Ru\": 533,\n", + " \"S\": 186,\n", + " \"Sb\": 568,\n", + " \"Sc\": 680,\n", + " \"Se\": 167,\n", + " \"Si\": 782,\n", + " \"Sm\": 732,\n", + " \"Sn\": 540,\n", + " \"Sr\": 605,\n", + " \"Ta\": 543,\n", + " \"Tb\": 566,\n", + " \"Tc\": 508,\n", + " \"Te\": 682,\n", + " \"Th\": 511,\n", + " \"Ti\": 638,\n", + " \"Tl\": 680,\n", + " \"Tm\": 571,\n", + " \"U\": 484,\n", + " \"V\": 676,\n", + " \"W\": 616,\n", + " \"Xe\": 1,\n", + " \"Y\": 668,\n", + " \"Yb\": 702,\n", + " \"Zn\": 614,\n", + " \"Zr\": 618\n", + "}\n" + ] + } + ], "source": [ "# Now, let's parse out the other elements in each record and keep a running tally to print out.\n", "elements = {}\n", diff --git a/docs/examples/Example Statistics - MDF Datasets.ipynb b/docs/examples/Example Statistics - MDF Datasets.ipynb index e4ac592..af5bd42 100644 --- a/docs/examples/Example Statistics - MDF Datasets.ipynb +++ b/docs/examples/Example Statistics - MDF Datasets.ipynb @@ -5,12 +5,15 @@ "metadata": {}, "source": [ "# Example Statistics\n", - "Example: We want to know how many datasets are in MDF and which datasets have the most records." + "Example: We want to know how many datasets are in MDF and which datasets have the most records.\n", + "\n", + "## Note: This example is not kept up-to-date with the latest statistics.\n", + "If you want the current MDF statistics, you must run this code yourself." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -21,7 +24,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -30,9 +33,17 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 50/50 [00:16<00:00, 3.06it/s]\n" + ] + } + ], "source": [ "# First, let's search for all the datasets. There are less than 10,000 currently, so `search()` will work fine.\n", "res = mdf.search(\"mdf.resource_type:dataset\", advanced=True)\n", @@ -47,9 +58,178 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of data resources: 50\n" + ] + }, + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
source_nametitlenum_records
12oqmd_v3The Open Quantum Materials Database687393
36h2o_13_v1Machine-learning approach for one- and two-bod...45482
40nist_xps_db_v1NIST X-ray Photoelectron Spectroscopy Database29189
22ab_initio_solute_database_v3High-throughput Ab-initio Dilute Solute Diffus...23454
29amcs_v1The American Mineralogist Crystal Structure Da...19576
8w_14_v1Accuracy and transferability of Gaussian appro...9693
30bfcc13_v1Cluster expansion made easy with Bayesian comp...3806
32cip_v1Evaluation and comparison of classical interat...3291
33cip_v2Evaluation and comparison of classical interat...3291
23sluschi_v3Solid and Liquid in Ultra Small Coexistence wi...1546
20surface_crystal_energy_v1Data from: Surface energies of elemental crystals1216
37khazana_polymer_v1Khazana (Polymer)1073
11doak_strain_energies_v4GeTe-PbTe PbS-PbTe PbSe-PbS PbTe-PbSe PbTe-SnT...795
41second_order_magnetic_prop_v4On the calculation of second-order magnetic pr...624
43ohmic_si_c_contacts_v1Synthesis of Ti3AuC2, Ti3Au2C2 and Ti3IrC2 by ...360
\n", + "
" + ], + "text/plain": [ + " source_name \\\n", + "12 oqmd_v3 \n", + "36 h2o_13_v1 \n", + "40 nist_xps_db_v1 \n", + "22 ab_initio_solute_database_v3 \n", + "29 amcs_v1 \n", + "8 w_14_v1 \n", + "30 bfcc13_v1 \n", + "32 cip_v1 \n", + "33 cip_v2 \n", + "23 sluschi_v3 \n", + "20 surface_crystal_energy_v1 \n", + "37 khazana_polymer_v1 \n", + "11 doak_strain_energies_v4 \n", + "41 second_order_magnetic_prop_v4 \n", + "43 ohmic_si_c_contacts_v1 \n", + "\n", + " title num_records \n", + "12 The Open Quantum Materials Database 687393 \n", + "36 Machine-learning approach for one- and two-bod... 45482 \n", + "40 NIST X-ray Photoelectron Spectroscopy Database 29189 \n", + "22 High-throughput Ab-initio Dilute Solute Diffus... 23454 \n", + "29 The American Mineralogist Crystal Structure Da... 19576 \n", + "8 Accuracy and transferability of Gaussian appro... 9693 \n", + "30 Cluster expansion made easy with Bayesian comp... 3806 \n", + "32 Evaluation and comparison of classical interat... 3291 \n", + "33 Evaluation and comparison of classical interat... 3291 \n", + "23 Solid and Liquid in Ultra Small Coexistence wi... 1546 \n", + "20 Data from: Surface energies of elemental crystals 1216 \n", + "37 Khazana (Polymer) 1073 \n", + "11 GeTe-PbTe PbS-PbTe PbSe-PbS PbTe-PbSe PbTe-SnT... 795 \n", + "41 On the calculation of second-order magnetic pr... 624 \n", + "43 Synthesis of Ti3AuC2, Ti3Au2C2 and Ti3IrC2 by ... 360 " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# Finally, we can print the data we gathered.\n", "print(\"Number of data resources: {n_datasets}\".format(n_datasets=len(df)))\n", @@ -58,9 +238,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "832189" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# Bonus: How many records are in MDF in total?\n", "df[\"num_records\"].sum()" diff --git a/docs/tutorials/1 - Introduction.ipynb b/docs/tutorials/1 - Introduction.ipynb index 6f6146a..b71ddc0 100644 --- a/docs/tutorials/1 - Introduction.ipynb +++ b/docs/tutorials/1 - Introduction.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -19,7 +19,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -47,11 +47,39 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': 'nist_xps_41530.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/nist_xps_db_v1/nist_xps_41530.json',\n", + " 'length': 1248,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '69912ca91261bba53dc0df956338baebf81a3f9d1281f4e9108200c3b8473f073ffdff7437a55c8ac3d08d40074a68a5509bbeb1a391426f838427398f3963dd',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/nist_xps_db_v1/nist_xps_41530.json'}],\n", + " 'material': {'composition': 'Al', 'elements': ['Al']},\n", + " 'mdf': {'ingest_date': '2018-03-28T15:04:09.928376Z',\n", + " 'mdf_id': '5abbaeff34a2263dfa3de0e1',\n", + " 'parent_id': '5abbaee934a2263dfa3dbf78',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 8553,\n", + " 'source_name': 'nist_xps_db_v1'},\n", + " 'nist_xps_db_v1': {'binding_energy_ev': '72.5',\n", + " 'energy_uncertainty_ev': '',\n", + " 'notes': 'Al(111).',\n", + " 'temperature_k': '300'}}" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res = mdf.search(\"Al\")\n", "res[0]" @@ -71,11 +99,38 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'crystal_structure': {'number_of_atoms': 4,\n", + " 'space_group_number': 225,\n", + " 'volume': 66.01028844534864},\n", + " 'files': [{'data_type': 'ASCII text',\n", + " 'filename': '15628.cif',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/amcs_v1/15628.cif',\n", + " 'length': 4073,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': 'cccd06663cc04a45b2fda17680e78d509e37d6d69a5bd1bf37695ab90e45ae602bd7a44dc365a3b2a2fa1708510a3803e94533c0c6624b25214dfdacb20aee1d',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/amcs_v1/15628.cif'}],\n", + " 'material': {'composition': 'Al4', 'elements': ['Al']},\n", + " 'mdf': {'ingest_date': '2018-03-26T22:23:18.021883Z',\n", + " 'mdf_id': '5ab972da34a2262cce3694b9',\n", + " 'parent_id': '5ab972d634a2262cce368d5c',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 1885,\n", + " 'source_name': 'amcs_v1'}}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res = mdf.search(\"material.elements:Al\", advanced=True, limit=10)\n", "res[0]" @@ -90,13 +145,61 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'dc': {'contributors': [{'affiliations': ['University of Wisconsin-Madison'],\n", + " 'contributorName': 'Morgan, Dane',\n", + " 'contributorType': 'ContactPerson',\n", + " 'familyName': 'Morgan',\n", + " 'givenName': 'Dane'}],\n", + " 'creators': [{'affiliations': ['University of Wisconsin-Madison'],\n", + " 'creatorName': 'Morgan, Dane',\n", + " 'familyName': 'Morgan',\n", + " 'givenName': 'Dane'},\n", + " {'affiliations': ['University of Wisconsin-Madison'],\n", + " 'creatorName': 'Mayeshiba, Tam',\n", + " 'familyName': 'Mayeshiba',\n", + " 'givenName': 'Tam'},\n", + " {'affiliations': ['University of Wisconsin-Madison'],\n", + " 'creatorName': 'Henry, Wu',\n", + " 'familyName': 'Henry',\n", + " 'givenName': 'Wu'}],\n", + " 'dates': [{'date': '2017-08-07T16:07:32.938812Z', 'dateType': 'Collected'}],\n", + " 'descriptions': [{'description': 'We demonstrate automated generation of diffusion databases from high-throughput density functional theory (DFT) calculations. A total of more than 230 dilute solute diffusion systems in Mg, Al, Cu, Ni, Pd, and Pt host lattices have been determined using multi-frequency diffusion models. We apply a correction method for solute diffusion in alloys using experimental and simulated values of host self-diffusivity.',\n", + " 'descriptionType': 'Other'}],\n", + " 'publicationYear': '2016',\n", + " 'publisher': 'MDF (placeholder)',\n", + " 'relatedIdentifiers': [{'relatedIdentifier': 'http://dx.doi.org/10.1038/sdata.2016.54',\n", + " 'relatedIdentifierType': 'DOI',\n", + " 'relationType': 'IsPartOf'}],\n", + " 'resourceType': {'resourceType': 'JSON', 'resourceTypeGeneral': 'Dataset'},\n", + " 'subjects': [{'subject': 'dilute'},\n", + " {'subject': 'solute'},\n", + " {'subject': 'DFT'},\n", + " {'subject': 'diffusion'},\n", + " {'subject': 'dataset'}],\n", + " 'titles': [{'title': 'High-throughput Ab-initio Dilute Solute Diffusion Database'}]},\n", + " 'mdf': {'ingest_date': '2018-03-30T00:32:34.081287Z',\n", + " 'mdf_id': '5abd85a234a22620d109ae2b',\n", + " 'resource_type': 'dataset',\n", + " 'scroll_id': 0,\n", + " 'source_name': 'ab_initio_solute_database_v3',\n", + " 'version': 3}}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "res = mdf.search('dc.titles.title:\"ChEMBL Database\"', advanced=True)\n", + "res = mdf.search('dc.titles.title:\"High-throughput Ab-initio Dilute Solute Diffusion Database\"', advanced=True)\n", "res[0]" ] }, diff --git a/docs/tutorials/2 - Core Query Builder Functions.ipynb b/docs/tutorials/2 - Core Query Builder Functions.ipynb index f23d0b8..3ac17d9 100644 --- a/docs/tutorials/2 - Core Query Builder Functions.ipynb +++ b/docs/tutorials/2 - Core Query Builder Functions.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -11,7 +11,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -37,9 +37,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.match_field(\"material.elements\", \"Al\")" ] @@ -53,11 +64,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "mdf.match_field(\"mdf.source_name\", \"oqmd\")" + "mdf.match_field(\"mdf.source_name\", \"oqmd*\")" ] }, { @@ -71,9 +93,47 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 5, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'crystal_structure': {'cross_reference': {'icsd': 43492},\n", + " 'number_of_atoms': 1,\n", + " 'space_group_number': 225,\n", + " 'volume': 15.8057},\n", + " 'dft': {'converged': True,\n", + " 'cutoff_energy': 650.0,\n", + " 'exchange_correlation_functional': 'LDA'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': '1038497.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/oqmd_v3/metadata-files/1038497.json',\n", + " 'length': 11249,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '1d7331786eb06dcbf3c5d2036cfbc5f7e46a1fdd57e69201a9662e01d7a63cc11e1894a3fbbe556ce0a1e6243dbbb5bf00662cca6d4022fde148b40930da5f70',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/oqmd_v3/metadata-files/1038497.json'}],\n", + " 'material': {'composition': 'Al1', 'elements': ['Al']},\n", + " 'mdf': {'ingest_date': '2018-04-11T18:00:55.808133Z',\n", + " 'mdf_id': '5ace50d334a2265849f80d64',\n", + " 'parent_id': '5ace4d5734a2265849f44fba',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 245162,\n", + " 'source_name': 'oqmd_v3'},\n", + " 'oqmd_v3': {'band_gap': {'units': 'eV', 'value': 0.0},\n", + " 'configuration': 'static_lda',\n", + " 'magnetic_moment': {'units': 'bohr/atom'},\n", + " 'total_energy': {'units': 'eV/atom', 'value': -4.1914643},\n", + " 'volume_pa': {'units': 'angstrom^3/atom', 'value': 15.8057}}}" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res = mdf.search(limit=10)\n", "res[0]" @@ -89,9 +149,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.exclude_field(\"material.elements\", \"Cu\")" ] @@ -105,18 +176,56 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.exclude_field(\"mdf.source_name\", \"sluschi\").match_field(\"material.elements\", \"Al\").exclude_field(\"mdf.source_name\", \"oqmd\")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'crystal_structure': {'number_of_atoms': 4,\n", + " 'space_group_number': 225,\n", + " 'volume': 66.01028844534864},\n", + " 'files': [{'data_type': 'ASCII text',\n", + " 'filename': '15628.cif',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/amcs_v1/15628.cif',\n", + " 'length': 4073,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': 'cccd06663cc04a45b2fda17680e78d509e37d6d69a5bd1bf37695ab90e45ae602bd7a44dc365a3b2a2fa1708510a3803e94533c0c6624b25214dfdacb20aee1d',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/amcs_v1/15628.cif'}],\n", + " 'material': {'composition': 'Al4', 'elements': ['Al']},\n", + " 'mdf': {'ingest_date': '2018-03-26T22:23:18.021883Z',\n", + " 'mdf_id': '5ab972da34a2262cce3694b9',\n", + " 'parent_id': '5ab972d634a2262cce368d5c',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 1885,\n", + " 'source_name': 'amcs_v1'}}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res = mdf.search(limit=10)\n", "res[0]" diff --git a/docs/tutorials/3 - Expanded Query Builder Functions.ipynb b/docs/tutorials/3 - Expanded Query Builder Functions.ipynb index 76b596c..a122642 100644 --- a/docs/tutorials/3 - Expanded Query Builder Functions.ipynb +++ b/docs/tutorials/3 - Expanded Query Builder Functions.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -11,7 +11,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -35,11 +35,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "mdf.match_range(\"oqmd.band_gap.value\", 0, 10)" + "mdf.match_range(\"mdf.scroll_id\", 0, 10)" ] }, { @@ -52,18 +63,245 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "mdf.exclude_range(\"oqmd.spacegroup\", 100, 199)" + "mdf.exclude_range(\"mdf.scroll_id\", 100, 199)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[{'dc': {'contributors': [{'affiliations': ['University of Arizona'],\n", + " 'contributorName': 'Downs, Robert',\n", + " 'contributorType': 'ContactPerson',\n", + " 'familyName': 'Downs',\n", + " 'givenName': 'Robert'}],\n", + " 'creators': [{'affiliations': ['University of Arizona'],\n", + " 'creatorName': 'Downs, Robert',\n", + " 'familyName': 'Downs',\n", + " 'givenName': 'Robert'},\n", + " {'affiliations': ['University of Arizona'],\n", + " 'creatorName': 'Hall-Wallace, Michelle',\n", + " 'familyName': 'Hall-Wallace',\n", + " 'givenName': 'Michelle'}],\n", + " 'dates': [{'date': '2017-08-04T18:47:01.096482Z', 'dateType': 'Collected'}],\n", + " 'descriptions': [{'description': 'A crystal structure database that includes every structure published in the American Mineralogist, The Canadian Mineralogist, European Journal of Mineralogy and Physics and Chemistry of Minerals, as well as selected datasets from other journals.',\n", + " 'descriptionType': 'Other'}],\n", + " 'publicationYear': '2003',\n", + " 'publisher': 'MDF (placeholder)',\n", + " 'resourceType': {'resourceType': 'JSON', 'resourceTypeGeneral': 'Dataset'},\n", + " 'subjects': [{'subject': 'crystal structure'}, {'subject': 'minerals'}],\n", + " 'titles': [{'title': 'The American Mineralogist Crystal Structure Database'}]},\n", + " 'mdf': {'ingest_date': '2018-03-26T22:23:18.021883Z',\n", + " 'mdf_id': '5ab972d634a2262cce368d5c',\n", + " 'resource_type': 'dataset',\n", + " 'scroll_id': 0,\n", + " 'source_name': 'amcs_v1',\n", + " 'version': 1}},\n", + " {'crystal_structure': {'number_of_atoms': 8,\n", + " 'space_group_number': 225,\n", + " 'volume': 241.385429855744},\n", + " 'files': [{'data_type': 'ASCII text',\n", + " 'filename': '03294.cif',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/amcs_v1/03294.cif',\n", + " 'length': 4184,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '37037fe5f5665da7582b178907c598f9527af12b12fcb933a3259fdc68612553385a282749c9b0ce9e1e00fa3cbd6e76896f4dab4f09486aebb4bd990f966fc0',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/amcs_v1/03294.cif'}],\n", + " 'material': {'composition': 'K3.2Na0.8Cl4', 'elements': ['K', 'Cl', 'Na']},\n", + " 'mdf': {'ingest_date': '2018-03-26T22:23:18.021883Z',\n", + " 'mdf_id': '5ab972d634a2262cce368d5d',\n", + " 'parent_id': '5ab972d634a2262cce368d5c',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 1,\n", + " 'source_name': 'amcs_v1'}},\n", + " {'crystal_structure': {'number_of_atoms': 52,\n", + " 'space_group_number': 12,\n", + " 'volume': 709.8954060972311},\n", + " 'files': [{'data_type': 'ASCII text',\n", + " 'filename': '18904.cif',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/amcs_v1/18904.cif',\n", + " 'length': 1543,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '6cae6f3deaf8723cc33f3b55faee8c19dc21db919f86977b8f5868a9e2cfc1a754a762d669f27e92a3d8006813d416f55c4d6d29b5e9c910173b0536f305761d',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/amcs_v1/18904.cif'}],\n", + " 'material': {'composition': 'K4Al4.0Si12O32',\n", + " 'elements': ['O', 'K', 'Al', 'Si']},\n", + " 'mdf': {'ingest_date': '2018-03-26T22:23:18.021883Z',\n", + " 'mdf_id': '5ab972d634a2262cce368d5f',\n", + " 'parent_id': '5ab972d634a2262cce368d5c',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 3,\n", + " 'source_name': 'amcs_v1'}},\n", + " {'crystal_structure': {'number_of_atoms': 56,\n", + " 'space_group_number': 227,\n", + " 'volume': 542.1966878632827},\n", + " 'files': [{'data_type': 'ASCII text',\n", + " 'filename': '02176.cif',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/amcs_v1/02176.cif',\n", + " 'length': 4980,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': 'edaff24b2f3e46f7323d049da9fa19d5e35b01ccd8bb9d619163d1877a735eb20a49b66ed40ac627c0fcafd9d17985523062495bb959773328f5bc8d97c197c3',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/amcs_v1/02176.cif'}],\n", + " 'material': {'composition': 'Mg8Al16O32', 'elements': ['O', 'Mg', 'Al']},\n", + " 'mdf': {'ingest_date': '2018-03-26T22:23:18.021883Z',\n", + " 'mdf_id': '5ab972d634a2262cce368d60',\n", + " 'parent_id': '5ab972d634a2262cce368d5c',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 4,\n", + " 'source_name': 'amcs_v1'}},\n", + " {'crystal_structure': {'number_of_atoms': 44,\n", + " 'space_group_number': 14,\n", + " 'volume': 571.0766745749353},\n", + " 'files': [{'data_type': 'ASCII text',\n", + " 'filename': '10564.cif',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/amcs_v1/10564.cif',\n", + " 'length': 1355,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': 'acffedef53bc4af7c9fc0b3085adb00e487e1006a5f6be5c5b0c00d6a6135e2467209c5c3f498c99a2de76f6beb51d01b707ef4a0ab738b1c79cfcf01f1134b2',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/amcs_v1/10564.cif'}],\n", + " 'material': {'composition': 'Cu12As4O28', 'elements': ['O', 'Cu', 'As']},\n", + " 'mdf': {'ingest_date': '2018-03-26T22:23:18.021883Z',\n", + " 'mdf_id': '5ab972d634a2262cce368d66',\n", + " 'parent_id': '5ab972d634a2262cce368d5c',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 10,\n", + " 'source_name': 'amcs_v1'}},\n", + " {'dc': {'contributors': [{'affiliations': ['Brigham Young University'],\n", + " 'contributorName': 'Hart, Gus',\n", + " 'contributorType': 'ContactPerson',\n", + " 'familyName': 'Hart',\n", + " 'givenName': 'Gus'}],\n", + " 'creators': [{'affiliations': [''],\n", + " 'creatorName': 'Hart, Gus',\n", + " 'familyName': 'Hart',\n", + " 'givenName': 'Gus'},\n", + " {'affiliations': ['Brigham Young University'],\n", + " 'creatorName': 'Nelson, Lance',\n", + " 'familyName': 'Nelson',\n", + " 'givenName': 'Lance'},\n", + " {'affiliations': [''],\n", + " 'creatorName': 'Ozoliņš, Vidvuds',\n", + " 'familyName': 'Ozoliņš',\n", + " 'givenName': 'Vidvuds'},\n", + " {'affiliations': [''],\n", + " 'creatorName': 'Reese, Shane',\n", + " 'familyName': 'Reese',\n", + " 'givenName': 'Shane'},\n", + " {'affiliations': [''],\n", + " 'creatorName': 'Zhou, Fei',\n", + " 'familyName': 'Zhou',\n", + " 'givenName': 'Fei'}],\n", + " 'dates': [{'date': '2017-08-09T16:34:52.925299Z', 'dateType': 'Collected'}],\n", + " 'descriptions': [{'description': '4k DFT calculations for solid AgPd, CuPt and AgPt FCC superstructures. DFT/PBE energy, forces and stresses for cell sizes 1-16 across all compositions including primitive cells.',\n", + " 'descriptionType': 'Other'}],\n", + " 'publicationYear': '2013',\n", + " 'publisher': 'MDF (placeholder)',\n", + " 'relatedIdentifiers': [{'relatedIdentifier': 'https://journals.aps.org/prb/abstract/10.1103/PhysRevB.88.155105',\n", + " 'relatedIdentifierType': 'DOI',\n", + " 'relationType': 'IsPartOf'}],\n", + " 'resourceType': {'resourceType': 'JSON', 'resourceTypeGeneral': 'Dataset'},\n", + " 'subjects': [{'subject': 'tar_bz2'}],\n", + " 'titles': [{'title': 'Cluster expansion made easy with Bayesian compressive sensing'}]},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:11:28.073432Z',\n", + " 'mdf_id': '5aba511034a226348355ce1b',\n", + " 'resource_type': 'dataset',\n", + " 'scroll_id': 0,\n", + " 'source_name': 'bfcc13_v1',\n", + " 'version': 1}},\n", + " {'crystal_structure': {'number_of_atoms': 5,\n", + " 'space_group_number': 12,\n", + " 'volume': 72.0681447541587},\n", + " 'files': [{'data_type': 'ASCII text',\n", + " 'filename': 'OUTCAR.str36',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/bfcc13_v1/bfcc13/Cu_Pt.OUTCARS/OUTCAR.str36',\n", + " 'length': 3263105,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '6951816745fdf7d2e9173d746a19c1f62deb336bb29c5b5ada640b2f387262bc06f4504f83d23aadb0e91b5b4eb07a2f229f4bc8484527947cd984e9892f1bfa',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/bfcc13_v1/bfcc13/Cu_Pt.OUTCARS/OUTCAR.str36'}],\n", + " 'material': {'composition': 'Cu2Pt3', 'elements': ['Pt', 'Cu']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:11:28.073432Z',\n", + " 'mdf_id': '5aba511034a226348355ce1c',\n", + " 'parent_id': '5aba511034a226348355ce1b',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 1,\n", + " 'source_name': 'bfcc13_v1'}},\n", + " {'crystal_structure': {'number_of_atoms': 9,\n", + " 'space_group_number': 12,\n", + " 'volume': 134.8999346410581},\n", + " 'files': [{'data_type': 'ASCII text',\n", + " 'filename': 'OUTCAR.str645',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/bfcc13_v1/bfcc13/Cu_Pt.OUTCARS/OUTCAR.str645',\n", + " 'length': 1650783,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': 'a39d988a45785e9312e8dfbd6f9a7f80cd3fe87873324e7c69a854147318fe8cde07bfb8abe0e02eb0d3d87e2c4909d0c873909c7e23508b1496a4787a4b5896',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/bfcc13_v1/bfcc13/Cu_Pt.OUTCARS/OUTCAR.str645'}],\n", + " 'material': {'composition': 'Cu2Pt7', 'elements': ['Pt', 'Cu']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:11:28.073432Z',\n", + " 'mdf_id': '5aba511034a226348355ce1d',\n", + " 'parent_id': '5aba511034a226348355ce1b',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 2,\n", + " 'source_name': 'bfcc13_v1'}},\n", + " {'crystal_structure': {'number_of_atoms': 11,\n", + " 'space_group_number': 2,\n", + " 'volume': 156.45812198249544},\n", + " 'files': [{'data_type': 'ASCII text',\n", + " 'filename': 'OUTCAR.str3268',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/bfcc13_v1/bfcc13/Cu_Pt.OUTCARS/OUTCAR.str3268',\n", + " 'length': 18298966,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': 'c6dfc4f286f6877afd6fa31e0a2b4abd501075fee0a3f1dbb47353bf43d8a42f8676bf11b6943daaf271a7e5f070cae0cd95cb651344deb26d523e89f8795fe7',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/bfcc13_v1/bfcc13/Cu_Pt.OUTCARS/OUTCAR.str3268'}],\n", + " 'material': {'composition': 'Cu5Pt6', 'elements': ['Pt', 'Cu']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:11:28.073432Z',\n", + " 'mdf_id': '5aba511034a226348355ce1f',\n", + " 'parent_id': '5aba511034a226348355ce1b',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 4,\n", + " 'source_name': 'bfcc13_v1'}},\n", + " {'crystal_structure': {'number_of_atoms': 12,\n", + " 'space_group_number': 1,\n", + " 'volume': 164.19035220804295},\n", + " 'files': [{'data_type': 'ASCII text',\n", + " 'filename': 'OUTCAR.str6788',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/bfcc13_v1/bfcc13/Cu_Pt.OUTCARS/OUTCAR.str6788',\n", + " 'length': 1135486,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': 'da8c61f1b6990ef9fde4405e1aadc44a547951f8b50f15378fac3403bb631a337707ef060df3bd3166cd76a0f98d56f3e15a221e321bbcd8358ead12ffd19391',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/bfcc13_v1/bfcc13/Cu_Pt.OUTCARS/OUTCAR.str6788'}],\n", + " 'material': {'composition': 'Cu7Pt5', 'elements': ['Pt', 'Cu']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:11:28.073432Z',\n", + " 'mdf_id': '5aba511034a226348355ce20',\n", + " 'parent_id': '5aba511034a226348355ce1b',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 5,\n", + " 'source_name': 'bfcc13_v1'}}]" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.search(limit=10)" ] @@ -78,9 +316,219 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[{'cip_v1': {'bv': '117.4',\n", + " 'energy': '-2.46',\n", + " 'forcefield': 'ffield.TiO.comb3',\n", + " 'gv': '34.5',\n", + " 'mpid': 'mp-12957',\n", + " 'totenergy': '-2515.3108'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': 'classical_interatomic_potentials.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json',\n", + " 'length': 1841203,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '96635ee0c15d1d0187b18805653a02b1a6dfa5648db82153467045de18adcc08c753e2897d2b48a78a2167a442219e9aeff6b1103732c2158facac8fa4911b33',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json'}],\n", + " 'material': {'composition': 'O1024', 'elements': ['O']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:38:34.068719Z',\n", + " 'mdf_id': '5aba576a34a226348355dd4a',\n", + " 'parent_id': '5aba576a34a226348355dcfa',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 80,\n", + " 'source_name': 'cip_v1'}},\n", + " {'cip_v1': {'bv': '0.0',\n", + " 'energy': '-2.58',\n", + " 'forcefield': 'ffield.TiO.comb3',\n", + " 'gv': '0.0',\n", + " 'mpid': 'mp-610917',\n", + " 'totenergy': '-991.44286'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': 'classical_interatomic_potentials.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json',\n", + " 'length': 1841203,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '96635ee0c15d1d0187b18805653a02b1a6dfa5648db82153467045de18adcc08c753e2897d2b48a78a2167a442219e9aeff6b1103732c2158facac8fa4911b33',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json'}],\n", + " 'material': {'composition': 'O384', 'elements': ['O']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:38:34.068719Z',\n", + " 'mdf_id': '5aba576a34a226348355dd4b',\n", + " 'parent_id': '5aba576a34a226348355dcfa',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 81,\n", + " 'source_name': 'cip_v1'}},\n", + " {'cip_v1': {'bv': '13565.4',\n", + " 'energy': '-2.08',\n", + " 'forcefield': 'ffield.TiO.comb3',\n", + " 'gv': '757.8',\n", + " 'mpid': 'mp-560602',\n", + " 'totenergy': '-1350.9046'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': 'classical_interatomic_potentials.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json',\n", + " 'length': 1841203,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '96635ee0c15d1d0187b18805653a02b1a6dfa5648db82153467045de18adcc08c753e2897d2b48a78a2167a442219e9aeff6b1103732c2158facac8fa4911b33',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json'}],\n", + " 'material': {'composition': 'O648', 'elements': ['O']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:38:34.068719Z',\n", + " 'mdf_id': '5aba576a34a226348355dd4d',\n", + " 'parent_id': '5aba576a34a226348355dcfa',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 83,\n", + " 'source_name': 'cip_v1'}},\n", + " {'cip_v1': {'bv': '0.0',\n", + " 'energy': '-1.45',\n", + " 'forcefield': 'SiO.tersoff',\n", + " 'gv': '0.0',\n", + " 'mpid': 'mp-560602',\n", + " 'totenergy': '-277.97382'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': 'classical_interatomic_potentials.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json',\n", + " 'length': 1841203,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '96635ee0c15d1d0187b18805653a02b1a6dfa5648db82153467045de18adcc08c753e2897d2b48a78a2167a442219e9aeff6b1103732c2158facac8fa4911b33',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json'}],\n", + " 'material': {'composition': 'O192', 'elements': ['O']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:38:34.068719Z',\n", + " 'mdf_id': '5aba576a34a226348355de1f',\n", + " 'parent_id': '5aba576a34a226348355dcfa',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 293,\n", + " 'source_name': 'cip_v1'}},\n", + " {'cip_v1': {'bv': '0.0',\n", + " 'energy': '-1.38',\n", + " 'forcefield': 'SiO.tersoff',\n", + " 'gv': '0.0',\n", + " 'mpid': 'mp-607540',\n", + " 'totenergy': '-22.135599'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': 'classical_interatomic_potentials.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json',\n", + " 'length': 1841203,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '96635ee0c15d1d0187b18805653a02b1a6dfa5648db82153467045de18adcc08c753e2897d2b48a78a2167a442219e9aeff6b1103732c2158facac8fa4911b33',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json'}],\n", + " 'material': {'composition': 'O16', 'elements': ['O']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:38:34.068719Z',\n", + " 'mdf_id': '5aba576a34a226348355de20',\n", + " 'parent_id': '5aba576a34a226348355dcfa',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 294,\n", + " 'source_name': 'cip_v1'}},\n", + " {'cip_v1': {'bv': '0.0',\n", + " 'energy': '-2.58',\n", + " 'forcefield': 'ffield.CuOCH.comb3',\n", + " 'gv': '0.0',\n", + " 'mpid': 'mp-610917',\n", + " 'totenergy': '-991.44286'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': 'classical_interatomic_potentials.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json',\n", + " 'length': 1841203,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '96635ee0c15d1d0187b18805653a02b1a6dfa5648db82153467045de18adcc08c753e2897d2b48a78a2167a442219e9aeff6b1103732c2158facac8fa4911b33',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json'}],\n", + " 'material': {'composition': 'O384', 'elements': ['O']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:38:34.068719Z',\n", + " 'mdf_id': '5aba576c34a226348355e0b0',\n", + " 'parent_id': '5aba576a34a226348355dcfa',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 950,\n", + " 'source_name': 'cip_v1'}},\n", + " {'cip_v1': {'bv': '13565.4',\n", + " 'energy': '-2.08',\n", + " 'forcefield': 'ffield.CuOCH.comb3',\n", + " 'gv': '757.8',\n", + " 'mpid': 'mp-560602',\n", + " 'totenergy': '-1350.9046'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': 'classical_interatomic_potentials.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json',\n", + " 'length': 1841203,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '96635ee0c15d1d0187b18805653a02b1a6dfa5648db82153467045de18adcc08c753e2897d2b48a78a2167a442219e9aeff6b1103732c2158facac8fa4911b33',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json'}],\n", + " 'material': {'composition': 'O648', 'elements': ['O']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:38:34.068719Z',\n", + " 'mdf_id': '5aba576c34a226348355e0b2',\n", + " 'parent_id': '5aba576a34a226348355dcfa',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 952,\n", + " 'source_name': 'cip_v1'}},\n", + " {'cip_v1': {'bv': '-613291.1',\n", + " 'energy': '-1.64',\n", + " 'forcefield': 'ffield.CuOCH.comb3',\n", + " 'gv': '39619.1',\n", + " 'mpid': 'mp-607540',\n", + " 'totenergy': '-471.55491'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': 'classical_interatomic_potentials.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json',\n", + " 'length': 1841203,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '96635ee0c15d1d0187b18805653a02b1a6dfa5648db82153467045de18adcc08c753e2897d2b48a78a2167a442219e9aeff6b1103732c2158facac8fa4911b33',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json'}],\n", + " 'material': {'composition': 'O288', 'elements': ['O']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:38:34.068719Z',\n", + " 'mdf_id': '5aba576c34a226348355e0b3',\n", + " 'parent_id': '5aba576a34a226348355dcfa',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 953,\n", + " 'source_name': 'cip_v1'}},\n", + " {'cip_v1': {'bv': '-75.4',\n", + " 'energy': '-2.46',\n", + " 'forcefield': 'ffield.CuOCH.comb3',\n", + " 'gv': '-11.8',\n", + " 'mpid': 'mp-973916',\n", + " 'totenergy': '-2522.4124'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': 'classical_interatomic_potentials.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json',\n", + " 'length': 1841203,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '96635ee0c15d1d0187b18805653a02b1a6dfa5648db82153467045de18adcc08c753e2897d2b48a78a2167a442219e9aeff6b1103732c2158facac8fa4911b33',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json'}],\n", + " 'material': {'composition': 'O1024', 'elements': ['O']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:38:34.068719Z',\n", + " 'mdf_id': '5aba576c34a226348355e0b4',\n", + " 'parent_id': '5aba576a34a226348355dcfa',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 954,\n", + " 'source_name': 'cip_v1'}},\n", + " {'cip_v1': {'bv': '0.0',\n", + " 'energy': '-2.56',\n", + " 'forcefield': 'ffield.comb',\n", + " 'gv': '0.0',\n", + " 'mpid': 'mp-611836',\n", + " 'totenergy': '-1023.0162'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': 'classical_interatomic_potentials.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json',\n", + " 'length': 1841203,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '96635ee0c15d1d0187b18805653a02b1a6dfa5648db82153467045de18adcc08c753e2897d2b48a78a2167a442219e9aeff6b1103732c2158facac8fa4911b33',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/cip_v1/classical_interatomic_potentials.json'}],\n", + " 'material': {'composition': 'O400', 'elements': ['O']},\n", + " 'mdf': {'ingest_date': '2018-03-27T14:38:34.068719Z',\n", + " 'mdf_id': '5aba576d34a226348355e147',\n", + " 'parent_id': '5aba576a34a226348355dcfa',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 1101,\n", + " 'source_name': 'cip_v1'}}]" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.exclusive_match(\"material.elements\", \"O\").search(limit=10)" ] diff --git a/docs/tutorials/4 - General Helper Functions.ipynb b/docs/tutorials/4 - General Helper Functions.ipynb index 8b49137..41f0c21 100644 --- a/docs/tutorials/4 - General Helper Functions.ipynb +++ b/docs/tutorials/4 - General Helper Functions.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -11,7 +11,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -35,9 +35,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'(mdf.source_name:oqmd)'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.match_field(\"mdf.source_name\", \"oqmd\")\n", "mdf.current_query()" @@ -53,7 +64,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, "outputs": [], "source": [ @@ -62,9 +73,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "''" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.current_query()" ] @@ -79,7 +101,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": {}, "outputs": [], "source": [ @@ -96,18 +118,67 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], + "execution_count": 7, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{'crystal_structure': {'number_of_atoms': 128,\n", + " 'space_group_number': 1,\n", + " 'volume': 2103.1050159155607},\n", + " 'dft': {'converged': True,\n", + " 'cutoff_energy': 520.0,\n", + " 'exchange_correlation_functional': 'PAW_PBE'},\n", + " 'files': [{'data_type': 'ASCII text',\n", + " 'filename': 'OUTCAR_bcc_large',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/khazana_vasp_v1/OUTCARS/OUTCAR_bcc_large',\n", + " 'length': 883373,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': 'e91555c23528363ce14413c25927835e16191ee7980685139cff9850d7e1ddd355fb231c0f181ae936a37d5c010389e63b70b760c298368a2399417359edfa9e',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/khazana_vasp_v1/OUTCARS/OUTCAR_bcc_large'}],\n", + " 'material': {'composition': 'Al128', 'elements': ['Al']},\n", + " 'mdf': {'ingest_date': '2018-03-27T21:23:27.961187Z',\n", + " 'mdf_id': '5abab64f34a2263dfa3dbf4a',\n", + " 'parent_id': '5abab64f34a2263dfa3dbf49',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 1,\n", + " 'source_name': 'khazana_vasp_v1'}}" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res[0]" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'index': 'mdf',\n", + " 'index_uuid': '1a57bbe5-5272-477f-9d31-343b8258b7a5',\n", + " 'query': {'advanced': True,\n", + " 'limit': 10,\n", + " 'offset': 0,\n", + " 'q': '( NOT mdf.source_name:sluschi AND material.elements:Al AND NOT mdf.source_name:oqmd)'},\n", + " 'total_query_matches': 36149}" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "info" ] @@ -122,18 +193,40 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.match_field(\"mdf.source_name\", \"nist_xps_db\")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'(mdf.source_name:nist_xps_db)'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res, info = mdf.search(limit=10, info=True, reset_query=False)\n", "info[\"query\"][\"q\"]" @@ -141,9 +234,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'(mdf.source_name:nist_xps_db)'" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res, info = mdf.search(limit=10, info=True)\n", "info[\"query\"][\"q\"]" @@ -159,9 +263,30 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'cip_v1': 'object',\n", + " 'cip_v2': 'object',\n", + " 'crystal_structure': 'object',\n", + " 'dc': 'object',\n", + " 'dft': 'object',\n", + " 'files': 'object',\n", + " 'image': 'object',\n", + " 'material': 'object',\n", + " 'mdf': 'object',\n", + " 'nist_xps_db_v1': 'object',\n", + " 'oqmd_v3': 'object'}" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.show_fields()" ] @@ -175,11 +300,28 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'mdf.ingest_date': 'date',\n", + " 'mdf.mdf_id': 'text',\n", + " 'mdf.parent_id': 'text',\n", + " 'mdf.resource_type': 'text',\n", + " 'mdf.scroll_id': 'long',\n", + " 'mdf.source_name': 'text',\n", + " 'mdf.version': 'long'}" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.show_fields(\"mdf\")" ] @@ -201,10 +343,8 @@ }, { "cell_type": "code", - "execution_count": null, - "metadata": { - "collapsed": true - }, + "execution_count": 14, + "metadata": {}, "outputs": [], "source": [ "records = mdf.search(\"dft.converged:true AND mdf.resource_type:record\")" @@ -212,11 +352,81 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'dc': {'contributors': [{'affiliations': ['University College London'],\n", + " 'contributorName': 'Schofield, Steven',\n", + " 'contributorType': 'ContactPerson',\n", + " 'familyName': 'Schofield',\n", + " 'givenName': 'Steven'}],\n", + " 'creators': [{'affiliations': ['Curtin University'],\n", + " 'creatorName': \"O'Donnell, Kane\",\n", + " 'familyName': \"O'Donnell\",\n", + " 'givenName': 'Kane'},\n", + " {'affiliations': ['The Open University'],\n", + " 'creatorName': 'Hedgeland, Holly',\n", + " 'familyName': 'Hedgeland',\n", + " 'givenName': 'Holly'},\n", + " {'affiliations': ['University College London'],\n", + " 'creatorName': 'Moore, Gareth',\n", + " 'familyName': 'Moore',\n", + " 'givenName': 'Gareth'},\n", + " {'affiliations': ['University College London'],\n", + " 'creatorName': 'Suleman, Asif',\n", + " 'familyName': 'Suleman',\n", + " 'givenName': 'Asif'},\n", + " {'affiliations': ['University College London'],\n", + " 'creatorName': 'Siegl, Manuel',\n", + " 'familyName': 'Siegl',\n", + " 'givenName': 'Manuel'},\n", + " {'affiliations': ['The Australian Synchrotron'],\n", + " 'creatorName': 'Thomsen, Lars',\n", + " 'familyName': 'Thomsen',\n", + " 'givenName': 'Lars'},\n", + " {'affiliations': ['The University of Sydney'],\n", + " 'creatorName': 'Warschkow, Oliver',\n", + " 'familyName': 'Warschkow',\n", + " 'givenName': 'Oliver'},\n", + " {'affiliations': ['University College London'],\n", + " 'creatorName': 'Schofield, Steven',\n", + " 'familyName': 'Schofield',\n", + " 'givenName': 'Steven'}],\n", + " 'dates': [{'date': '2017-08-03T17:06:55.772133Z', 'dateType': 'Collected'}],\n", + " 'descriptions': [{'description': 'This data set contains original XPS and NEXAFS data collected at the Australian Synchrotron. The data are the results of experiments investigating benzonitrile adsorption to the Si(001) surface. The results were written up and have been accepted for publication in Physical Chemistry Chemical Physics in Sept. 2016. The publication date is not yet known.',\n", + " 'descriptionType': 'Other'}],\n", + " 'publicationYear': '2016',\n", + " 'publisher': 'MDF (placeholder)',\n", + " 'relatedIdentifiers': [{'relatedIdentifier': 'http://pubs.rsc.org/en/content/articlepdf/2016/CP/C6CP04328C',\n", + " 'relatedIdentifierType': 'DOI',\n", + " 'relationType': 'IsPartOf'}],\n", + " 'resourceType': {'resourceType': 'JSON', 'resourceTypeGeneral': 'Dataset'},\n", + " 'rightsList': [{'rights': 'https://creativecommons.org/licenses/by/4.0/',\n", + " 'rightsURI': 'https://creativecommons.org/licenses/by/4.0/'}],\n", + " 'subjects': [{'subject': 'benzonitrile'},\n", + " {'subject': 'Si(001)'},\n", + " {'subject': 'adsorption'},\n", + " {'subject': 'XPS'},\n", + " {'subject': 'NEXAFS'}],\n", + " 'titles': [{'title': 'Benzonitrile on Si(001). XPS, NEXAFS, and STM data. Accepted for publication in PCCP Sept. 2016'}]},\n", + " 'mdf': {'ingest_date': '2018-03-27T13:37:18.690487Z',\n", + " 'mdf_id': '5aba490e34a226348355ce11',\n", + " 'resource_type': 'dataset',\n", + " 'scroll_id': 0,\n", + " 'source_name': 'benzonitrile_si_v1',\n", + " 'version': 1}}" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res = mdf.fetch_datasets_from_results(records)\n", "res[0]" @@ -231,11 +441,42 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'dc': {'contributors': [{'affiliations': ['University of Illinois Urbana-Champaign'],\n", + " 'contributorName': 'Schleife, Andre',\n", + " 'contributorType': 'ContactPerson',\n", + " 'familyName': 'Schleife',\n", + " 'givenName': 'Andre'}],\n", + " 'creators': [{'affiliations': ['University of Illinois Urbana-Champaign'],\n", + " 'creatorName': 'Schleife, Andre',\n", + " 'familyName': 'Schleife',\n", + " 'givenName': 'Andre'}],\n", + " 'dates': [{'date': '2017-10-10T15:04:02.121824Z', 'dateType': 'Collected'}],\n", + " 'publicationYear': '2015',\n", + " 'publisher': 'MDF (placeholder)',\n", + " 'resourceType': {'resourceType': 'JSON', 'resourceTypeGeneral': 'Dataset'},\n", + " 'subjects': [{'subject': 'data_link'}],\n", + " 'titles': [{'title': 'Schleife 256 Al'}]},\n", + " 'mdf': {'ingest_date': '2018-03-28T16:53:29.457529Z',\n", + " 'mdf_id': '5abbc88934a2263dfa3e3555',\n", + " 'resource_type': 'dataset',\n", + " 'scroll_id': 0,\n", + " 'source_name': 'schleife_256_al_v1',\n", + " 'version': 1}}" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res = mdf.match_field(\"material.elements\", \"Al\").fetch_datasets_from_results()\n", "res[0]" @@ -265,11 +506,19 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": {}, - "outputs": [], - "source": [ - "mdf.match_field(\"mdf.source_name\", \"oqmd\").match_field(\"material.elements\", \"Pb\").exclude_field(\"material.elements\", \"Al\")\n", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of results: 23290\n" + ] + } + ], + "source": [ + "mdf.match_field(\"mdf.source_name\", \"oqmd*\").match_field(\"material.elements\", \"Pb\").exclude_field(\"material.elements\", \"Al\")\n", "res, info = mdf.search(limit=0, info=True, reset_query=False)\n", "print(\"Number of results:\", info[\"total_query_matches\"])" ] @@ -283,9 +532,31 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 18, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100%|██████████| 23290/23290 [00:59<00:00, 382.96it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Number of results: 23290\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], "source": [ "res = mdf.aggregate()\n", "print(\"Number of results:\", len(res))" diff --git a/docs/tutorials/5 - Field-Specific Helper Functions.ipynb b/docs/tutorials/5 - Field-Specific Helper Functions.ipynb index 48ea6fd..003694e 100644 --- a/docs/tutorials/5 - Field-Specific Helper Functions.ipynb +++ b/docs/tutorials/5 - Field-Specific Helper Functions.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -11,7 +11,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -35,9 +35,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 3, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.match_source_names(\"oqmd\")" ] @@ -52,9 +63,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.match_elements([\"Al\", \"Cu\"])" ] @@ -69,20 +91,69 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.match_resource_types(\"record\")" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 6, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'crystal_structure': {'cross_reference': {'icsd': 42517},\n", + " 'number_of_atoms': 6,\n", + " 'space_group_number': 140,\n", + " 'volume': 88.5788},\n", + " 'dft': {'converged': True,\n", + " 'cutoff_energy': 520.0,\n", + " 'exchange_correlation_functional': 'PBE'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': '5724.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/oqmd_v3/metadata-files/5724.json',\n", + " 'length': 11547,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': 'f3e8743e64697ab5c6021b815ca4f780940f7ea4b50e2e31278216c3bd8bec16677d436f3b0e46e1e1cf9ea4a415899ed65dba1b4d4c7420d6d2ff4eca125990',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/oqmd_v3/metadata-files/5724.json'}],\n", + " 'material': {'composition': 'Al2Cu1', 'elements': ['Cu', 'Al']},\n", + " 'mdf': {'ingest_date': '2018-04-11T18:00:55.808133Z',\n", + " 'mdf_id': '5ace4f2334a2265849f63ff7',\n", + " 'parent_id': '5ace4d5734a2265849f44fba',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 127037,\n", + " 'source_name': 'oqmd_v3'},\n", + " 'oqmd_v3': {'band_gap': {'units': 'eV', 'value': 0.0},\n", + " 'configuration': 'static',\n", + " 'delta_e': {'units': 'eV/atom', 'value': -0.155698471666667},\n", + " 'magnetic_moment': {'units': 'bohr/atom'},\n", + " 'stability': {'units': 'eV/atom', 'value': 0.019296661666666},\n", + " 'total_energy': {'units': 'eV/atom', 'value': -3.891511245},\n", + " 'volume_pa': {'units': 'angstrom^3/atom', 'value': 14.7631}}}" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res = mdf.search(limit=10)\n", "res[0]" @@ -98,9 +169,20 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 7, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "an_id = res[1][\"mdf\"][\"mdf_id\"]\n", "mdf.match_ids(an_id)" @@ -108,11 +190,46 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 8, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[{'crystal_structure': {'cross_reference': {'icsd': 40332},\n", + " 'number_of_atoms': 10,\n", + " 'space_group_number': 12,\n", + " 'volume': 134.855},\n", + " 'dft': {'converged': True,\n", + " 'cutoff_energy': 520.0,\n", + " 'exchange_correlation_functional': 'PBE'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': '16290.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/oqmd_v3/metadata-files/16290.json',\n", + " 'length': 11470,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': '953f706130e358a03be6bfcecdbeca503cfc6f5592756a06294cc691e42282e1c5cbb1553ce55f6ac5ce4ec758d00f51dac3bb8389e71d1a551379785dd3fc6c',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/oqmd_v3/metadata-files/16290.json'}],\n", + " 'material': {'composition': 'Al1Cu1', 'elements': ['Cu', 'Al']},\n", + " 'mdf': {'ingest_date': '2018-04-11T18:00:55.808133Z',\n", + " 'mdf_id': '5ace50a534a2265849f7dc53',\n", + " 'parent_id': '5ace4d5734a2265849f44fba',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 232601,\n", + " 'source_name': 'oqmd_v3'},\n", + " 'oqmd_v3': {'band_gap': {'units': 'eV', 'value': 0.0},\n", + " 'magnetic_moment': {'units': 'bohr/atom'},\n", + " 'total_energy': {'units': 'eV/atom', 'value': -3.933290274},\n", + " 'volume_pa': {'units': 'angstrom^3/atom', 'value': 13.4855}}}]" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.search()" ] @@ -129,22 +246,84 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 9, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.match_titles('\"The Open Quantum Materials Database\"')" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 10, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "[{'dc': {'contributors': [{'affiliations': ['Northwestern University'],\n", + " 'contributorName': 'Wolverton, Chris',\n", + " 'contributorType': 'ContactPerson',\n", + " 'familyName': 'Wolverton',\n", + " 'givenName': 'Chris'}],\n", + " 'creators': [{'affiliations': ['Northwestern University'],\n", + " 'creatorName': 'Wolverton, Chris',\n", + " 'familyName': 'Wolverton',\n", + " 'givenName': 'Chris'},\n", + " {'affiliations': ['Northwestern University'],\n", + " 'creatorName': 'Kirklin, Scott',\n", + " 'familyName': 'Kirklin',\n", + " 'givenName': 'Scott'},\n", + " {'affiliations': ['Northwestern University'],\n", + " 'creatorName': 'Hegde, Vinay',\n", + " 'familyName': 'Hegde',\n", + " 'givenName': 'Vinay'},\n", + " {'affiliations': ['Northwestern University'],\n", + " 'creatorName': 'Ward, Logan',\n", + " 'familyName': 'Ward',\n", + " 'givenName': 'Logan'}],\n", + " 'dates': [{'date': '2017-08-04T14:18:51.560728Z', 'dateType': 'Collected'}],\n", + " 'descriptions': [{'description': 'The OQMD is a database of DFT-calculated thermodynamic and structural properties.',\n", + " 'descriptionType': 'Other'}],\n", + " 'publicationYear': '2013',\n", + " 'publisher': 'MDF (placeholder)',\n", + " 'relatedIdentifiers': [{'relatedIdentifier': 'http://dx.doi.org/10.1007/s11837-013-0755-4',\n", + " 'relatedIdentifierType': 'DOI',\n", + " 'relationType': 'IsPartOf'},\n", + " {'relatedIdentifier': 'http://dx.doi.org/10.1038/npjcompumats.2015.10',\n", + " 'relatedIdentifierType': 'DOI',\n", + " 'relationType': 'IsPartOf'}],\n", + " 'resourceType': {'resourceType': 'JSON', 'resourceTypeGeneral': 'Dataset'},\n", + " 'subjects': [{'subject': 'dft'}],\n", + " 'titles': [{'title': 'The Open Quantum Materials Database'}]},\n", + " 'mdf': {'ingest_date': '2018-04-11T18:00:55.808133Z',\n", + " 'mdf_id': '5ace4d5734a2265849f44fba',\n", + " 'resource_type': 'dataset',\n", + " 'scroll_id': 0,\n", + " 'source_name': 'oqmd_v3',\n", + " 'version': 8}}]" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.search()" ] @@ -159,20 +338,76 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 11, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.match_years([\"2015\", 2010])" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 12, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'dc': {'contributors': [{'affiliations': ['Imperial College London'],\n", + " 'contributorName': 'Corsini, Niccolo',\n", + " 'contributorType': 'ContactPerson',\n", + " 'familyName': 'Corsini',\n", + " 'givenName': 'Niccolo'}],\n", + " 'creators': [{'affiliations': ['Imperial College London'],\n", + " 'creatorName': 'Corsini, Niccolo',\n", + " 'familyName': 'Corsini',\n", + " 'givenName': 'Niccolo'}],\n", + " 'dates': [{'date': '2017-08-09T19:44:38.397091Z', 'dateType': 'Collected'}],\n", + " 'descriptions': [{'description': 'Over the last two decades, it has been demonstrated that size effects have significant consequences for the atomic arrangements and phase behavior of matter under extreme pressure. Furthermore, it has been shown that an understanding of how size affects critical pressure–temperature conditions provides vital guidance in the search for materials with novel properties. Here, we report on the remarkable behavior of small (under ∼5 nm) matrix-free Ge nanoparticles under hydrostatic compression that is drastically different from both larger nanoparticles and bulk Ge. We discover that the application of pressure drives surface-induced amorphization leading to Ge–Ge bond overcompression and eventually to a polyamorphic semiconductor-to-metal transformation.',\n", + " 'descriptionType': 'Other'}],\n", + " 'publicationYear': '2015',\n", + " 'publisher': 'MDF (placeholder)',\n", + " 'relatedIdentifiers': [{'relatedIdentifier': 'http://pubs.acs.org/doi/abs/10.1021/acs.nanolett.5b02627',\n", + " 'relatedIdentifierType': 'DOI',\n", + " 'relationType': 'IsPartOf'}],\n", + " 'resourceType': {'resourceType': 'JSON', 'resourceTypeGeneral': 'Dataset'},\n", + " 'rightsList': [{'rights': 'https://creativecommons.org/publicdomain/zero/1.0/',\n", + " 'rightsURI': 'https://creativecommons.org/publicdomain/zero/1.0/'}],\n", + " 'subjects': [{'subject': 'amorphization'},\n", + " {'subject': 'density functional theory calculations'},\n", + " {'subject': 'Ge nanoparticles'},\n", + " {'subject': 'high pressure'},\n", + " {'subject': 'phase transformation'},\n", + " {'subject': 'Raman'},\n", + " {'subject': 'X-ray absorption'},\n", + " {'subject': 'zip'}],\n", + " 'titles': [{'title': 'Pressure-induced amorphisation and a new high density amorphous metallic phase in matrix-free Ge nanoparticles: simulation data'}]},\n", + " 'mdf': {'ingest_date': '2018-03-27T20:11:39.629371Z',\n", + " 'mdf_id': '5abaa57b34a2263dfa3d08ae',\n", + " 'resource_type': 'dataset',\n", + " 'scroll_id': 0,\n", + " 'source_name': 'ge_nanoparticles_v1',\n", + " 'version': 1}}" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res = mdf.search(limit=10)\n", "res[0]" @@ -187,20 +422,76 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 13, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "mdf.match_years(start=2014, stop=2016, inclusive=True)" ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 14, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'dc': {'contributors': [{'affiliations': ['Imperial College London'],\n", + " 'contributorName': 'Corsini, Niccolo',\n", + " 'contributorType': 'ContactPerson',\n", + " 'familyName': 'Corsini',\n", + " 'givenName': 'Niccolo'}],\n", + " 'creators': [{'affiliations': ['Imperial College London'],\n", + " 'creatorName': 'Corsini, Niccolo',\n", + " 'familyName': 'Corsini',\n", + " 'givenName': 'Niccolo'}],\n", + " 'dates': [{'date': '2017-08-09T19:44:38.397091Z', 'dateType': 'Collected'}],\n", + " 'descriptions': [{'description': 'Over the last two decades, it has been demonstrated that size effects have significant consequences for the atomic arrangements and phase behavior of matter under extreme pressure. Furthermore, it has been shown that an understanding of how size affects critical pressure–temperature conditions provides vital guidance in the search for materials with novel properties. Here, we report on the remarkable behavior of small (under ∼5 nm) matrix-free Ge nanoparticles under hydrostatic compression that is drastically different from both larger nanoparticles and bulk Ge. We discover that the application of pressure drives surface-induced amorphization leading to Ge–Ge bond overcompression and eventually to a polyamorphic semiconductor-to-metal transformation.',\n", + " 'descriptionType': 'Other'}],\n", + " 'publicationYear': '2015',\n", + " 'publisher': 'MDF (placeholder)',\n", + " 'relatedIdentifiers': [{'relatedIdentifier': 'http://pubs.acs.org/doi/abs/10.1021/acs.nanolett.5b02627',\n", + " 'relatedIdentifierType': 'DOI',\n", + " 'relationType': 'IsPartOf'}],\n", + " 'resourceType': {'resourceType': 'JSON', 'resourceTypeGeneral': 'Dataset'},\n", + " 'rightsList': [{'rights': 'https://creativecommons.org/publicdomain/zero/1.0/',\n", + " 'rightsURI': 'https://creativecommons.org/publicdomain/zero/1.0/'}],\n", + " 'subjects': [{'subject': 'amorphization'},\n", + " {'subject': 'density functional theory calculations'},\n", + " {'subject': 'Ge nanoparticles'},\n", + " {'subject': 'high pressure'},\n", + " {'subject': 'phase transformation'},\n", + " {'subject': 'Raman'},\n", + " {'subject': 'X-ray absorption'},\n", + " {'subject': 'zip'}],\n", + " 'titles': [{'title': 'Pressure-induced amorphisation and a new high density amorphous metallic phase in matrix-free Ge nanoparticles: simulation data'}]},\n", + " 'mdf': {'ingest_date': '2018-03-27T20:11:39.629371Z',\n", + " 'mdf_id': '5abaa57b34a2263dfa3d08ae',\n", + " 'resource_type': 'dataset',\n", + " 'scroll_id': 0,\n", + " 'source_name': 'ge_nanoparticles_v1',\n", + " 'version': 1}}" + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res = mdf.search(limit=10)\n", "res[0]" @@ -223,11 +514,49 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 15, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'crystal_structure': {'cross_reference': {'icsd': 42517},\n", + " 'number_of_atoms': 6,\n", + " 'space_group_number': 140,\n", + " 'volume': 88.5788},\n", + " 'dft': {'converged': True,\n", + " 'cutoff_energy': 520.0,\n", + " 'exchange_correlation_functional': 'PBE'},\n", + " 'files': [{'data_type': 'ASCII text, with very long lines, with no line terminators',\n", + " 'filename': '5724.json',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/oqmd_v3/metadata-files/5724.json',\n", + " 'length': 11547,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': 'f3e8743e64697ab5c6021b815ca4f780940f7ea4b50e2e31278216c3bd8bec16677d436f3b0e46e1e1cf9ea4a415899ed65dba1b4d4c7420d6d2ff4eca125990',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/oqmd_v3/metadata-files/5724.json'}],\n", + " 'material': {'composition': 'Al2Cu1', 'elements': ['Cu', 'Al']},\n", + " 'mdf': {'ingest_date': '2018-04-11T18:00:55.808133Z',\n", + " 'mdf_id': '5ace4f2334a2265849f63ff7',\n", + " 'parent_id': '5ace4d5734a2265849f44fba',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 127037,\n", + " 'source_name': 'oqmd_v3'},\n", + " 'oqmd_v3': {'band_gap': {'units': 'eV', 'value': 0.0},\n", + " 'configuration': 'static',\n", + " 'delta_e': {'units': 'eV/atom', 'value': -0.155698471666667},\n", + " 'magnetic_moment': {'units': 'bohr/atom'},\n", + " 'stability': {'units': 'eV/atom', 'value': 0.019296661666666},\n", + " 'total_energy': {'units': 'eV/atom', 'value': -3.891511245},\n", + " 'volume_pa': {'units': 'angstrom^3/atom', 'value': 14.7631}}}" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "res = mdf.search_by_elements([\"Al\", \"Cu\"], source_names=[\"oqmd\"])\n", "res[0]" @@ -243,13 +572,61 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 16, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'dc': {'contributors': [{'affiliations': ['University of Wisconsin-Madison'],\n", + " 'contributorName': 'Morgan, Dane',\n", + " 'contributorType': 'ContactPerson',\n", + " 'familyName': 'Morgan',\n", + " 'givenName': 'Dane'}],\n", + " 'creators': [{'affiliations': ['University of Wisconsin-Madison'],\n", + " 'creatorName': 'Morgan, Dane',\n", + " 'familyName': 'Morgan',\n", + " 'givenName': 'Dane'},\n", + " {'affiliations': ['University of Wisconsin-Madison'],\n", + " 'creatorName': 'Mayeshiba, Tam',\n", + " 'familyName': 'Mayeshiba',\n", + " 'givenName': 'Tam'},\n", + " {'affiliations': ['University of Wisconsin-Madison'],\n", + " 'creatorName': 'Henry, Wu',\n", + " 'familyName': 'Henry',\n", + " 'givenName': 'Wu'}],\n", + " 'dates': [{'date': '2017-08-07T16:07:32.938812Z', 'dateType': 'Collected'}],\n", + " 'descriptions': [{'description': 'We demonstrate automated generation of diffusion databases from high-throughput density functional theory (DFT) calculations. A total of more than 230 dilute solute diffusion systems in Mg, Al, Cu, Ni, Pd, and Pt host lattices have been determined using multi-frequency diffusion models. We apply a correction method for solute diffusion in alloys using experimental and simulated values of host self-diffusivity.',\n", + " 'descriptionType': 'Other'}],\n", + " 'publicationYear': '2016',\n", + " 'publisher': 'MDF (placeholder)',\n", + " 'relatedIdentifiers': [{'relatedIdentifier': 'http://dx.doi.org/10.1038/sdata.2016.54',\n", + " 'relatedIdentifierType': 'DOI',\n", + " 'relationType': 'IsPartOf'}],\n", + " 'resourceType': {'resourceType': 'JSON', 'resourceTypeGeneral': 'Dataset'},\n", + " 'subjects': [{'subject': 'dilute'},\n", + " {'subject': 'solute'},\n", + " {'subject': 'DFT'},\n", + " {'subject': 'diffusion'},\n", + " {'subject': 'dataset'}],\n", + " 'titles': [{'title': 'High-throughput Ab-initio Dilute Solute Diffusion Database'}]},\n", + " 'mdf': {'ingest_date': '2018-03-30T00:32:34.081287Z',\n", + " 'mdf_id': '5abd85a234a22620d109ae2b',\n", + " 'resource_type': 'dataset',\n", + " 'scroll_id': 0,\n", + " 'source_name': 'ab_initio_solute_database_v3',\n", + " 'version': 3}}" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "res = mdf.search_by_titles(['\"JANAF Thermochemical Tables\"'])\n", + "res = mdf.search_by_titles(['\"High-throughput Ab-initio Dilute Solute Diffusion Database\"'])\n", "res[0]" ] }, @@ -257,19 +634,46 @@ "cell_type": "markdown", "metadata": {}, "source": [ - "### aggregate_source_names\n", + "### aggregate_sources\n", "`aggregate_source_names()` fetches and returns all the records for a provided `\"mdf.source_name\"` value. Calling `search()` or `aggregate()` is not required, as this helper function does that for you. Please note that it is not possible to use the `limit` argument with this helper function, so you may get back a large number of results." ] }, { "cell_type": "code", - "execution_count": null, + "execution_count": 17, "metadata": { "scrolled": true }, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "{'crystal_structure': {'number_of_atoms': 2,\n", + " 'space_group_number': 227,\n", + " 'volume': 42.060419436652815},\n", + " 'files': [{'data_type': 'ASCII text',\n", + " 'filename': 'ge.castep',\n", + " 'globus': 'globus://e38ee745-6d04-11e5-ba46-22000b92c6ec/MDF/mdf_connect/prod/data/ge_nanoparticles_v1/CASTEP_DFPT/Bulk_diamond/ge.castep',\n", + " 'length': 358076,\n", + " 'mime_type': 'text/plain',\n", + " 'sha512': 'cff4dfe39b1ebe9de2ad3bdf99be4eecfcd3308f8c365567e2c601d1db2f0972c9f9524c01128adca251a81498f69c3992c8105560cb23f72e3ccb818cbef16f',\n", + " 'url': 'https://e38ee745-6d04-11e5-ba46-22000b92c6ec.e.globus.org/MDF/mdf_connect/prod/data/ge_nanoparticles_v1/CASTEP_DFPT/Bulk_diamond/ge.castep'}],\n", + " 'material': {'composition': 'Ge2', 'elements': ['Ge']},\n", + " 'mdf': {'ingest_date': '2018-03-27T20:11:39.629371Z',\n", + " 'mdf_id': '5abaa57b34a2263dfa3d08b0',\n", + " 'parent_id': '5abaa57b34a2263dfa3d08ae',\n", + " 'resource_type': 'record',\n", + " 'scroll_id': 2,\n", + " 'source_name': 'ge_nanoparticles_v1'}}" + ] + }, + "execution_count": 17, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "res = mdf.aggregate_source_names(\"fe_cr_al_oxidation\")\n", + "res = mdf.aggregate_sources(\"ge_nanoparticles\")\n", "res[0]" ] }, diff --git a/docs/tutorials/6 - Data Retrieval Functions.ipynb b/docs/tutorials/6 - Data Retrieval Functions.ipynb index 86f9515..a0a356c 100644 --- a/docs/tutorials/6 - Data Retrieval Functions.ipynb +++ b/docs/tutorials/6 - Data Retrieval Functions.ipynb @@ -2,7 +2,7 @@ "cells": [ { "cell_type": "code", - "execution_count": null, + "execution_count": 1, "metadata": {}, "outputs": [], "source": [ @@ -11,7 +11,7 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 2, "metadata": {}, "outputs": [], "source": [ @@ -58,12 +58,30 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 4, "metadata": {}, - "outputs": [], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Fetching files: 100%|██████████| 1/1 [00:00<00:00, 12087.33it/s]\n" + ] + }, + { + "data": { + "text/plain": [ + "{'success': True}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ "# Running this example will save a file in the current directory.\n", - "res = mdf.search(\"mdf.source_name:janaf AND mdf.resource_type:record\", limit=1)\n", + "res = mdf.search(\"mdf.source_name:oqmd* AND mdf.resource_type:record\", limit=1)\n", "mdf.http_download(res)" ] }, @@ -77,11 +95,22 @@ }, { "cell_type": "code", - "execution_count": null, + "execution_count": 5, "metadata": {}, - "outputs": [], + "outputs": [ + { + "data": { + "text/plain": [ + "'{\"General\": null, \"Element\": \"Al\", \"Formula\": \"Al\", \"XPS Formula\": \"\", \"Name\": \"aluminum\", \"CAS Registry No\": \"7429-90-5\", \"Classes\": \"element\", \"Citation\": null, \"Author Name(s)\": \"McConville C.F., Seymour D.L., Woodruff D.R., Bao S.\", \"Journal\": \"Surf. Sci. 188, 1 (1987)\", \"Data Processing\": null, \"Data Type\": \"Photoelectron Line\", \"Line Designation\": \"2p3/2\", \"Quality of Data\": \"Adequate\", \"Binding Energy (eV)\": \"72.5\", \"Energy Uncertainty\": \"\", \"Background Subtraction Method\": \"\", \"Peak Location Method\": \"data\", \"Full Width at Half-maximum Intensity (eV)\": \"\", \"Gaussian Width (eV)\": \"\", \"Lorentzian Width (eV)\": \"\", \"Measurement Information\": null, \"Use of X-ray Monochromator\": \"Yes\", \"Excitation Energy\": \"other source\", \"X-ray Energy\": \"100\", \"Overal Energy Resolution (eV)\": \"0.18\", \"Calibration\": \"FL = Fermi level\", \"Charge Reference\": \"Conductor\", \"Energy Scale Evalution\": \"Reliable (reported energy within 300 eV of a reference energy)\", \"Specimen Information\": null, \"Specimen\": \"crystal\", \"Method of Determining Specimen Composition\": \"\", \"Method of Determining Specimen Crystallinity\": \"Low-energy Electron Diffraction\", \"Specimen Temperature (K)\": \"300\", \"Sample Quality\": \"Good\", \"Comment\": null, \"Notes\": \"Al(111).\"}'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], "source": [ - "res = mdf.search(\"AlCu\", limit=1)\n", + "res = mdf.search(\"Al\", limit=1)\n", "raw_data = mdf.http_stream(res)\n", "next(raw_data)" ] diff --git a/mdf_forge/forge.py b/mdf_forge/forge.py index 947713b..cffefdd 100644 --- a/mdf_forge/forge.py +++ b/mdf_forge/forge.py @@ -625,7 +625,7 @@ def fetch_datasets_from_results(self, entries=None, query=None, reset_query=True # For records, extract the parent_id # Most entries should be records here if entry["mdf"]["resource_type"] == "record": - ds_ids.add(entry["mdf"]["links"]["parent_id"]) + ds_ids.add(entry["mdf"]["parent_id"]) # For datasets, extract the mdf_id elif entry["mdf"]["resource_type"] == "dataset": ds_ids.add(entry["mdf"]["mdf_id"])