{ "cells": [ { "cell_type": "markdown", "metadata": { "pycharm": {} }, "source": [ "\n", "*This notebook contains course material from [CBE40455](https://jckantor.github.io/CBE40455) by\n", "Jeffrey Kantor (jeff at nd.edu); the content is available [on Github](https://github.com/jckantor/CBE40455.git).\n", "The text is released under the [CC-BY-NC-ND-4.0 license](https://creativecommons.org/licenses/by-nc-nd/4.0/legalcode),\n", "and code is released under the [MIT license](https://opensource.org/licenses/MIT).*" ] }, { "cell_type": "markdown", "metadata": { "pycharm": {} }, "source": [ "\n", "< [Transportation Networks](http://nbviewer.jupyter.org/github/jckantor/CBE40455/blob/master/notebooks/03.02-Transportation-Networks.ipynb) | [Contents](toc.ipynb) | [Scheduling](http://nbviewer.jupyter.org/github/jckantor/CBE40455/blob/master/notebooks/04.00-Scheduling.ipynb) >

\"Open

\"Download\"" ] }, { "cell_type": "markdown", "metadata": { "pycharm": {} }, "source": [ "# Data Reconciliation" ] }, { "cell_type": "markdown", "metadata": { "pycharm": {} }, "source": [ "This notebook demonstrates use of linear programming using GLPK/Mathprog for reconciliation of process measurements." ] }, { "cell_type": "markdown", "metadata": { "pycharm": {} }, "source": [ "## Data Reconciliation and Gross Error Detection" ] }, { "cell_type": "markdown", "metadata": { "pycharm": {} }, "source": [ "The following demonstration was motivated by a former student Matt N. who was exploring methods for assessing measurement information in a refinery application. The illustration was adapted from Chapter 1 of \"Reconciliation & Gross Error Detection: An Intelligent Use of Process Data\" by Shankar Narasimhan and Cornelius Jordache (Gulf Publishing, 2000)." ] }, { "cell_type": "markdown", "metadata": { "pycharm": {} }, "source": [ "### Heat Exchanger with Bypass\n", "

\n",
    "           1/1          2/2         4/3         6/5\n",
    "        -------- SPLIT ----- HTEXG ----- MIXER --------\n",
    "                   |                       ^ \n",
    "                   |                       |\n",
    "                   |    3            5/4   |\n",
    "                   +-------> VALVE --------+\n",
    "
\n", "\n", "The flow sheet is labeled by `s/k` pairs which refer to stream `s` and measurement `k`. Streams are numbered `s` in `1..S` and sensors are numbered `k` in `1..K`. Parameter `s[k]` denotes the stream associated with measurement `k`. Note that not all of the streams are measured, and the redundancy in measurements due to material balances." ] }, { "cell_type": "code", "execution_count": 45, "metadata": { "collapsed": false, "pycharm": {} }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting tmp/DataRecon.dat\n" ] } ], "source": [ "%%writefile tmp/DataRecon.dat\n", "\n", "/* All of the relevant sensor information is given in the data section. The\n", "relevant information includes the number of sensors, and a table indexed by \n", "sensor number k with information on which stream is measured (s[k]), the \n", "measurement (y[k]), and 'no-penalty' range for measurement errors (emax[k]). \n", "*/\n", "\n", "set UNITS := SPLIT HTEXG VALVE MIXER;\n", "set STREAMS := 1 2 3 4 5 6;\n", "\n", "/* Mass Balance Coefficients */\n", "param A :\n", " 1 2 3 4 5 6 :=\n", " SPLIT -1 1 1 . . .\n", " HTEXG . -1 . 1 . .\n", " VALVE . . -1 . 1 .\n", " MIXER . . . 1 1 -1 ;\n", "\n", "/* Sensors and Measurement Data*/\n", "param: SENSORS: s y emax := \n", " 1 1 101.91 1.75\n", " 2 2 68.45 1.75\n", " 3 4 64.20 1.75\n", " 4 5 36.44 1.75\n", " 5 6 98.88 1.75 ;\n", "\n", "end;" ] }, { "cell_type": "markdown", "metadata": { "pycharm": {} }, "source": [ "Given sensor measurements $y_k$, the task is to infer values for the flowrates $x_{s_k}$ using mass balance equations and a sensor model\n", "\n", "$$\\begin{align*}\n", " |y_k-x_{s_k}| & \\leq e_k + M g_k \\\\\n", " |e_k| & \\leq e^{max}_k\n", "\\end{align*}$$\n", "\n", "$g_k$ is a binary variable indicating the presence of a gross error in sensor $k$. $M$ is a big number. A gross error occurs if the measured data is not consistent with sensor model and mass balances. The optimization objective is to find an estimate of mass flows minimizing the number of gross sensor errors." ] }, { "cell_type": "code", "execution_count": 46, "metadata": { "collapsed": false, "pycharm": {} }, "outputs": [], "source": [ "%%script glpsol -m /dev/stdin -d tmp/DataRecon.dat -y tmp/DataRecon.txt --out output\n", "\n", "# Example: DataReconciliation.mod\n", "\n", "/* Sets */\n", "set STREAMS;\n", "set SENSORS;\n", "set UNITS;\n", "\n", "/* Mass Balances Coefficients */\n", "param A{UNITS,STREAMS} default 0;\n", "\n", "/* Sensors Parameters */\n", "param y{SENSORS} >= 0; # Measurement Data\n", "param s{SENSORS} > 0; # Stream measured by each sensor\n", "param emax{SENSORS} >= 0; # Bound on error for each sensor\n", "param bigM := 100; # Big M\n", "\n", "/* Stream Variables */\n", "var x{STREAMS} >= 0;\n", "\n", "/* Sensor Variables */\n", "var epos{SENSORS} >= 0;\n", "var eneg{SENSORS} >= 0;\n", "var gerr{SENSORS} binary; # Gross Errors\n", "\n", "/* Optimization Criterion */\n", "minimize L1: sum {k in SENSORS} (epos[k]+eneg[k] + bigM*gerr[k]);\n", "\n", "/* Mass Balances */\n", "s.t. MASSBAL {i in UNITS}: sum{j in STREAMS} A[i,j]*x[j] = 0;\n", "\n", "/* Error Model */\n", "s.t. s_err {k in SENSORS}: y[k] = x[s[k]] + epos[k] - eneg[k];\n", "s.t. e_pos {k in SENSORS}: epos[k] <= emax[k] + bigM*gerr[k];\n", "s.t. e_neg {k in SENSORS}: eneg[k] <= emax[k] + bigM*gerr[k];\n", "\n", "/* Solve and Display Solution */\n", "solve;\n", "\n", "printf \"Measurement Reconciliation\";\n", "printf \"\\n\\n Sensor Measured Reconciled Difference GrossError\";\n", "for {k in SENSORS}{\n", " printf \"\\n %s %7.2f %7.2f %7.2f\",\n", " k,y[k],x[s[k]],(epos[k]-eneg[k]),gerr[k];\n", " printf \" %3s\", if gerr[k]=1 then \"X\" else \" \";\n", "}\n", "printf \"\\n\\n\\nStream Estimates\";\n", "printf \"\\n\\n Stream Estimate\";\n", "printf {i in STREAMS} \"\\n %s %7.2f\",i,x[i];\n", "\n", "table tab1 {k in SENSORS} OUT \"CSV\" \"tmp/MeasurementError.csv\":\n", " k~Sensor,\n", " y[k]~Measurement,\n", " x[s[k]]~Reconciled,\n", " (epos[k]-eneg[k])~Error,\n", " gerr[k]~GrossError;\n", "\n", "data;\n", "\n", "end;\n" ] }, { "cell_type": "code", "execution_count": 47, "metadata": { "collapsed": false, "pycharm": {} }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Measurement Reconciliation\n", "\n", " Sensor Measured Reconciled Difference GrossError\n", " 1 101.91 100.63 1.28 \n", " 2 68.45 64.20 4.25 X\n", " 3 64.20 64.20 0.00 \n", " 4 36.44 36.43 0.01 \n", " 5 98.88 100.63 -1.75 \n", "\n", "\n", "Stream Estimates\n", "\n", " Stream Estimate\n", " 1 100.63\n", " 2 64.20\n", " 3 36.43\n", " 4 64.20\n", " 5 36.43\n", " 6 100.63\n" ] } ], "source": [ "f = open('tmp/DataRecon.txt')\n", "print(f.read())\n", "f.close()" ] }, { "cell_type": "markdown", "metadata": { "pycharm": {} }, "source": [ "## Visualization" ] }, { "cell_type": "code", "execution_count": 48, "metadata": { "collapsed": false, "pycharm": {} }, "outputs": [ { "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", "
MeasurementReconciledErrorGrossError
Sensor
1101.91100.631.280
268.4564.204.251
364.2064.200.000
436.4436.430.010
598.88100.63-1.750
\n", "
" ], "text/plain": [ " Measurement Reconciled Error GrossError\n", "Sensor \n", "1 101.91 100.63 1.28 0\n", "2 68.45 64.20 4.25 1\n", "3 64.20 64.20 0.00 0\n", "4 36.44 36.43 0.01 0\n", "5 98.88 100.63 -1.75 0" ] }, "metadata": {}, "output_type": "display_data" }, { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAAAswAAAFRCAYAAABgwfsaAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XmYVOW17/HfakBs5kkQEGhwiBqTNIqKUaQlYpALajSD\nGtDminmOZlLiuXFKbI2JxoNDYm7MiUNUUDTEGIREAomUkhujouCIx6A0ICAg4AACIr3uH1VdFk13\n0dOut6r29/M8+6Heql17v/Vrunv1rlV7m7sLAAAAQP1KQk8AAAAAyGcUzAAAAEAWFMwAAABAFhTM\nAAAAQBYUzAAAAEAWFMwAAABAFhTMAAAAQBYUzAAKnplVm9kOM+tZ5/7FZlZjZgNDzS2fpXIbleXx\nilR+H9ZZjs3lPAEgNApmAMXAJb0l6ZzaO8zsc5JKU4/lBUsJPY8MLmlv81nt7p3rLM/UXam+12Zm\nbZsymaauDwC5QsEMoFhMl3Rexvh8SfcroyA0s/ZmNtXMVpjZO2Z2h5ntm3qsm5nNMbP1ZrbJzGab\nWf+M51aa2Ztm9oGZvWVm56burzKzaRnrlaWOypakxgkzu97M/p+krZIGm9mhZjbfzDaa2etm9rWM\n599rZr82s7+kjub+w8z6mNltqXktNbPyjPX7mdkjqXm/ZWbfzXisysx+b2b3peb9ipkdlXpsmqSB\nkman9nNZUwOv89q2SBqSeu0Xm9m/Jf1Par0Lzezfqdc7y8z6ZmyjvvVvNbN1Zva+mb1kZp9t6twA\noDVRMAMoFv+S1CVVjLaR9A0li+hMN0o6SNIXUv/2l/Tj1GMlku5WsogcKGmbpF9Jkpl1lPQLSWPc\nvYuk4yQtST2vMUewJ0iaLKmTpI2S5qfmtp+ksyX92swOy1j/a5KuktRL0g5JT0taJKmnpD9IuiU1\nrxJJsyUtltRP0pckXWJmp2Rsa7ykGZK6Snqs9jW5+0RJKyWNSx01ntqI15HttXVObU+STpd0tKTD\nUy0fP0u9pr6SVkh6qM42Mtf/sqQRkg52966p521s5twAoFVQMAMoJtOUPMo8WtJrklbXPpBqF7hQ\n0hR3f8/dt0i6QcmCVe6+yd0fdfftqcd+JmlkxrZrJH3OzErdfZ27v1a76b3MySXd6+5L3b1G0hhJ\ny939Pnevcfclkv6oZGFY64/uvtjdd0h6VNI2d5/u7i7p95KGptY7WlIvd7/e3T9x9+WS7qp9TSkL\n3X1u6rnTlfxjoSn6mdnmjGWTmZXW99rcfWfq/htSGe+Q9E1Jd7v7Enf/WNIVko6r01eeuf7HShbf\nh5lZibv/j7u/08Q5A0Crol8MQLFwJQvmhZIGq047hpJHcztIej6j1daUOnBgZh0k3Srpy5K6px7v\nZGbm7lvN7BuSLpN0d6oF4Qfu/j+NnNuqjNuDJB1rZpsz7mubmm/t61if8dj2OuNtSh6prt1Wvzrb\naiPpqYzxuozbH0naN1WI1jRy7mvcfUCWx1ft5b6+Sh4dlySlstyo5NH9lXXXd/cFZvYrSf9X0iAz\n+6Oky9z9w0bOFwBaHUeYARQNd1+p5If/TlXyqG2md5UsNg939+6ppVuqxUKSfiDpEEnHpFoBRipZ\nUFtq2/Pc/RRJ+0t6XdKdqedtVbIQr7V/fVPLuL1S0pMZc+ieaon4djNe8iolj1ZnbquLu4+rZ7/1\naY0PRNa3jcz71kgqqx2k2lt6KuPof91tuPvt7j5M0uFKfk3+sxXmCQDNRsEMoNhcIGmUu2/LvDN1\nRPVOSbeZ2X6SZGb9M/p9OylZUL9vZj0kXVP7XDPrbWanp4q9nUoWybtSDy+RdKKZDTCzrkq2HNSV\neaR7jqRDzGyCmbVLLUeb2aH1rLs3z0r60Mz+j5mVmlkbMzvCzIY1clvrJB3YhP3VZ2/7mCFpkpl9\nwczaK9nq8q/UHzd7bsxsmJkda2btlDwivl2fZg0AQVAwAygq7v6Wu7+QeVfG7R9KWibpX2b2vpIf\nvjsk9dhtSp6G7l1J/5T0eMZzSyRdquRR0Y1KfijtotT+5kt6WNJLkp5T8kN4dY+6psep/uhTlOwz\nXi1prZK91PtkrOt1nlvv9tx9l6RxksqVPLK+QdJvJXXZ23NTbpB0dao3eYr25Eq2fNQ9D/NXGtje\nHmN3/7ukH0l6RMmjzYO1e4913ed3Sb2GTZKqlfx6/Fc9cwOAnLHk50AAAAAA1IcjzAAAAEAWFMwA\nAABAFhTMAAAAQBYUzAAAAEAWQS9cYmZ84hAAAAA54e5NOXVnWvAjzO7OEmi55pprgs8hzgv5k31c\nF/In/7guZB92aYngBTPCqa6uDj2FWCP/cMg+LPIPi/zDIfvCRcEMAAAAZEHBHGOVlZWhpxBr5B8O\n2YdF/mGRfzhkX7iCXunPzDzk/gEAABAPZiYv1A/9IZxEIhF6CrFG/uGQfVjkHxb5h0P2hYuCGQAA\n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\nrJF/OGQfFvmHRf61PMKlccxMQ4YM0YwZM9L3vfzyy9q2bVvenAovyjNPNEeofnQKZgAAgEAmTJig\n+++/Pz2+7777dN5556WLwh07duiyyy7ToEGDtP/+++uiiy7S9u3bJUnvvfeexo0bp969e6tHjx4a\nP368Vq9end7WvffeqwMPPFBdunTRkCFD9OCDD0qSqqqqNHHixPR61dXVKikpUU1NjaTkH1VXX321\njj/+eHXs2FHLly/X66+/rtGjR6tnz5469NBDNXPmzPTzKysrdfHFF2vs2LHq3LmzTjjhBK1bt06X\nXHKJevToocMOO0xLlixJr79mzRqdddZZ6t27t4YMGaLbb789/VhVVZW+/vWv6/zzz1eXLl10xBFH\n6Pnnn5ckTZw4UStXrtT48ePVuXNnTZ06tdW+DntDwRxj9LGFRf7hkH1Y5B8W+eeX4cOH64MPPtDr\nr7+uXbt26eGHH9aECRMkJY/uXn755Vq2bJlefPFFLVu2TKtXr9Z1110nSaqpqdEFF1yglStXauXK\nlSotLdV3vvMdSdLWrVv1/e9/X3PnztUHH3ygp59+WuXl5ZIadyGX6dOn66677tKWLVvUs2dPjR49\nWhMmTNCGDRv00EMP6eKLL9bSpUvT68+cOVM//elP9e6776p9+/Y67rjjNGzYMG3cuFFf/epXNWXK\nlPScx48fr6FDh2rNmjX6+9//rttuu03z5s1Lb2v27Nk655xz9P777+u0005Lv6Zp06Zp4MCBmjNn\njj788ENddtllrfAVaBwKZgAAgIAmTpyo+++/X/Pnz9fhhx+u/v37S0oWzHfeeaduueUWdevWTZ06\nddIVV1yhhx56SJLUo0cPfeUrX9G+++6rTp066corr9STTz6Z3m5JSUm6xaNPnz46/PDD09vNxsxU\nWVmpww47TCUlJZo7d64GDx6s888/XyUlJSovL9eZZ56521HmM888U0OHDlX79u31la98RaWlpZow\nYYLMTF//+te1ePFiSdJzzz2nd999V1dffbXatm2rwYMHa/LkyenXJEkjRozQmDFjZGaaMGGCXnzx\nxdYJugW4NHaM0ccWFvmHQ/ZhkX9Y5J9fzEwTJ07UiBEjtHz58t3aMTZs2KCPPvpIRx11VHp9d0+3\nTnz00Ue69NJL9de//lWbN2+WJG3ZskXuro4dO+rhhx/W1KlTdcEFF+j444/XzTffrM985jONmteA\nAQPSt1esWKFnnnlG3bt3T9/3ySef6Lzzzku/ht69e6cf23fffXcbl5aWasuWLeltrVmzZrdt7dq1\nSyeeeGJ63KdPn/TtDh06aPv27aqpqVFJSbjjvBTMAAAAAQ0cOFBDhgzR448/rnvuuSd9f69evVRa\nWqrXXntNffv23eN5N998s9544w09++yz6t27t5YsWaIjjzxS7i4z0ymnnKJTTjlFO3bs0FVXXaUL\nL7xQTz31lDp27KiPPvoovZ133nlnj21ntm0MHDhQI0eO3K1torkGDBigwYMH64033qj38b21i4T6\nMCQtGTFGH1tY5B8O2YdF/mGRf366++679cQTT6i0tDR9X0lJiS688EJdcskl2rBhgyRp9erV6cJ1\ny5YtKi0tVdeuXbVp0yZde+216eeuX79es2bN0tatW9WuXTt17NhRbdq0kSSVl5frqaee0qpVq/T+\n++/rhhtu2GM+mW0b48aN0xtvvKHp06dr586d2rlzp5577jm9/vrre6y7N8ccc4w6d+6sm266Sdu2\nbdOuXbv0yiuvaNGiRY3aVp8+ffTmm282en+tJWvBbEkDsq0DAACAlhkyZIiOPPLI9Lj2fM4///nP\nddBBB2n48OHq2rWrRo8enT46e8kll2jbtm3q1auXvvjFL+rUU09NH4GtqanRrbfeqv79+6tnz55a\nuHCh7rjjDknS6NGj9Y1vfEOf//zndfTRR2v8+PF7HLnNHHfq1Enz5s3TQw89pP79+6tv37664oor\n9PHHH+8217pzr297bdq00Zw5c7RkyRINGTJE++23n771rW/pgw8+2OtzJemKK67Q9ddfr+7du+uW\nW25pRtLNY9kqeUvO8GV3PyKSnZt5Pp3bDwAAFJ+65+7Nxdv61DfhNHSu5tT9zfriZz3CnKpmnzez\nY5qzceS3qqqq0FMAACDnai/GEeWC4tKYHubhkp42s7fM7OXU8lLUE0P0MnudkHv0EYZD9mGRf1jk\nDzRdY86S8eXUv7V/LuXHtRoBAACAHMjaw5xeyaxc0ggli+aF7t4qZ5CmhzmsUNdjBwAgl/h9Fy85\n72FObfz7kqZL2k9SH0nTzex7zdkZAAAAUGga08M8WdKx7v5jd/+Rkj3NF0Y7LaD40UcYDtmHRf5h\nkT/QdI29cElNA7cBAACAorbXHmYzmyKpUtIflfzA3xmS7nX3W1u8c3qYg6KnCwAQB/y+i5cgPczu\n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\n0FEMITsK5ngJ8qE/M9vfzO42s7mp8eFmdkFzdgYgUyL0BGIsEXoCMZcIPYFYo4cZaLrGfOjvXknz\nJPVLjf8t6dKoJgQAAADkk8b0MC9y92Fmttjdh6buW+Lu5S3eOS0ZQdGSAaA48HY7sqMlI15CnYd5\ni5n1zNjZcEnvN2dnAAAAQKFpTMH8A0mzJQ0xs39Kul/SnpeBAdBEidATiLFE6AnEXCL0BGKNHmag\n6RosmM3sGDPr6+7PSxop6UpJ2yXNl5SbC4EDAAAAgTXYw2xmiyV9yd03mdmJkh6W9B1JQyUd6u5f\nbfHO6WEOih5mAMWB/lRkRw9zvETRw9w2y2Ml7r4pdfsbkv7b3R+R9EjqUtcoCly8BAAQL/lypb+y\nsjKtX79ebdq0Sd83adKk9KWukT+yFcxtzKydu++UdLKkbzXyeSgQCxYsiN3lUfNJHC9Pmy/IPizy\nD4v8k6I83tzYctzMNGfOHI0aNSrrert27dqtqJakmpoalZQ05qNozVsfu8uW3AxJT5rZY5I+krRQ\nkszsYEnv5WBuAAAAsXPvvffq+OOP15QpU9SrVy9VVVVp0qRJuuiiizR27Fh16tRJiURCS5cuVUVF\nhbp3764jjjhCs2fPTm+jsrJyj/XRfA0eKXb3n5rZE5L2lzTP3WtSD5mk7+ZicogWRxjCIv9wyD4s\n8g+L/PNLQ60bzz77rM4991ytX79eH3/8sf7jP/5DM2bM0OOPP67jjjtOH374oYYOHarJkyfrb3/7\nmxYuXKjTTz9dixYt0iGHHCJJu62/Y8eOXL6sopP12Ly7P+3uj7r71oz73nD3F6KfGgAAQPFyd51x\nxhnq3r17ernrrrskSf369dO3v/1tlZSUaN9995WZ6YwzztBxxx0nSVqyZIm2bt2qyy+/XG3bttVJ\nJ52kcePGacaMGentZ67fvn373L/AIkIzS4zx9kxY5B8O2YdF/mGRf/4wM82aNUubN29OL5MnT5Yk\nDRgwYI/1DzjggPTtNWvW7LHOoEGDtGbNmvS269sGmoeCGQAAIM/UdyaPzPv69eunVatW7dbSsWLF\nCvXv3z8n84sbCuYYo48tLPIPh+zDIv+wyD+/NPb80HXXGz58uDp06KCbbrpJO3fuVCKR0Jw5c3T2\n2Wc3abtoHApmAACAQMaPH6/OnTunlzPPPFNmtscR5rr3tWvXTrNnz9bjjz+u/fbbT9/5znc0bdq0\n9Af+6tsGmq/BK/3lZOdc6S8ozsUZFvmHQ/ZhkX9Yccy/7pXf8uXCJYhGrq/0BwAAUHQoZtFUHGEG\nAABFraFZBgtaAAANTElEQVQjjihOURxhpocZAAAAyIKCOcY4F2dY5B8O2YdF/mGRP9B0FMwAAABA\nFvQwAwCAokYPc7zQwwwAAADkGAVzjNHHFhb5h0P2YZF/WHHNv/ZCHizFv0SB8zADAICili/tGHG8\naEyxoIcZAAAARY8eZgAAACAiFMwxFtc+tnxB/uGQfVjkHxb5h0P2hYuCGQAAAMiCHmYAAAAUPXqY\nAQAAgIhQMMcYvVRhkX84ZB8W+YdF/uGQfeGiYAYAAACyoIcZAAAARa8lPcxc6S/Gorh8JH8AAQCA\nYkNLRsx5Ky5oGnrZwiH7sMg/LPIPh+wLFwUzAAAAkAU9zDFmZq16ZNhESwYAAMhPnIcZAAAAiAgF\nMxAIvWzhkH1Y5B8W+YdD9oWLghkAAADIgh7mGKOHGQAAxAU9zAAAAEBEIr1wiZkNkHS/pN5Knqr3\nt+7+yyj3iaZp7UuXRHExFADYG97darxEIqGKiorQ04glsi9cUV/pb6ekS919iZl1kvS8mc1396UR\n7xeNVRV6AjG2XNLg0JOIKbIPq7Xzr2rFbQFAPXLaw2xmf5J0u7v/PTWmhzkgM+MXDYDCV8URZgB7\nVxA9zGZWJmmopGdytU8AAACgpXJSMKfaMf4g6fvuviUX+wTy3vLQE4gxsg+L/IPiXMDhkH3hirqH\nWWbWTtIjkqa7+5/qPl5ZWamysjJJUrdu3VReXp5uiK/9j8U4mrGk3XsJa3+JMc7N+J08mw9jxgU8\nDv3zlDHjxoxr5ct8in1ce7u6ulotFWkPsyVPmXCfpI3ufmk9j9PDHBA9zACKQhU9zAD2Lp97mI+X\nNEHSSWa2OLWMiXifAAAAQKuJtGB293+4e4m7l7v70NQyN8p9AgWDPs5wyD4s8g+qbnsAcofsCxdX\n+gMAAACyyOl5mPfYOT3MQXFVPgBoGL+fgOLSkh7myM+SgXzHLwQA2BMHFAB8ipYMIJhE6AnEWCL0\nBGIuEXoCsUYfbThkX7gomAEAAIAs6GGOsWQPM/kDwJ6MHmagyOTzeZgBAACAgkbBDASTCD2BGEuE\nnkDMJUJPINboow2H7AsXBTMAAACQBT3MMUYPMwA0hB5moNhwHma0AOcaBQAAyIaWjBhbsGCB3J0l\n0EL+ZB/XpVDyL1b00YZD9oWLghkAAADIgh5mAAAAFD3OwwwAAABEhII5xuilCov8wyH7sMg/LPIP\nh+wLFwUzAAAAkAU9zAAAACh69DADAAAAEaFgjjF6qcIi/3DIPizyD4v8wyH7wkXBDAAAAGRBDzMA\nAACKHj3MAAAAQEQomGOMXqqwyD8csg+L/MMi/3DIvnBRMAMAAABZ0MMMAACAokcPMwAAABARCuYY\no5cqLPIPh+zDIv+wyD8csi9cFMwAAABAFvQwAwAAoOjRwwwAAABEhII5xuilCov8wyH7sMg/LPIP\nh+wLFwUzAAAAkAU9zAAAACh69DADAAAAEaFgjjF6qcIi/3DIPizyD4v8wyH7wkXBDAAAAGRBDzMA\nAACKXkt6mNu29mRQOMwa/j/DHzIAAABJtGTEnNezIDfoZQuH7MMi/7DIPxyyL1wUzAAAAEAW9DDH\nmJnVe0TZREsGAAAoLpyHGQAAAIgIBTMQCL1s4ZB9WOQfFvmHQ/aFi4IZAAAAyIIe5hijhxkAAMQF\nPcwAAABARCK9cImZ3SPpf0la7+6fi3JfaJ6G/szKdlETAADQcrybWzgibckwsxGStki6v76CmZaM\nsMxMqgo9ixhbLmlw6EnEFNmHRf5hkX84mdlXUTDnWt62ZLj7Qkmbo9wHULD4hRUO2YdF/mGRfzhk\nX7DoYQYAAACyoGAGQlkeegIxRvZhkX9Y5B8O2ResSD/01xiVlZUqKyuTJHXr1k3l5eWqqKiQ9OkJ\nvhlHM5a0ez9V7Tcy49yM38mz+TBmzJgx42jHqn8cuh4o1nHt7erqarVU5OdhNrMySbP50F/+4UN/\nAAAEUsWH/nItbz/0Z2YzJP1T0iFmtsrMJkW5PwAAAKC1RdqS4e7nRLl9oKBltsMgt8g+LPIPi/zD\nIfuCxYf+AAAAgCwi72HOunN6mIPian4AAOQn6qPW15Ie5uBnyUBofEMCAJBfOKCVb2jJAIJJhJ5A\njCVCTyDmEqEnEHOJ0BOIsUToCaCZKJgBAACALOhhjrFkDzP5AwCQX4we5gjk7XmYAQAAgEJHwQwE\nkwg9gRhLhJ5AzCVCTyDmEqEnEGOJ0BNAM1EwAwAAAFnQwxxj9DADAJCP6GGOAudhRgtwrkcAAIBs\nKJhjbMGCBaqoqAg9jdhKJBLkHwjZh0X+YZF/OGRfuOhhBgAAALKghxkAAABFj/MwAwAAABGhYI6x\nRCIRegqxRv7hkH1Y5B8W+YdD9oWLghkAAADIgh5mAAAAFD16mAEAAICIUDDHGL1UYZF/OGQfFvmH\nRf7hkH3homCOsSVLloSeQqyRfzhkHxb5h0X+4ZB94aJgjrH33nsv9BRijfzDIfuwyD8s8g+H7AsX\nBTMAAACQBQVzjFVXV4eeQqyRfzhkHxb5h0X+4ZB94Qp+WrlgOwcAAECsNPe0ckELZgAAACDf0ZIB\nAAAAZEHBDAAAAGQRpGA2s/8ys6Vm9qKZ/dHMumY8doWZ/dvMXjezU0LMLw7MbEwq43+b2Q9Dz6eY\nmdkAM1tgZq+a2Stm9r3U/T3MbL6ZvWFm88ysW+i5FjMza2Nmi81sdmpM/jliZt3M7A+pn/uvmdmx\n5J8bZnZp6ufOy2b2oJm1J/vomNk9ZrbOzF7OuK/BvKl5Wk8D2bdavRnqCPM8SZ919y9IekPSFZJk\nZodL+oakwyWNkfRrM+MoeCszszaSfqVkxodLOsfMDgs7q6K2U9Kl7v5ZScMlfTuV9+WS5rv7IZL+\nnhojOt+X9Jqk2g9ukH/u/ELSX9z9MEmfl/S6yD9yZtZf0nclHeXun5PURtLZIvso/U7J362Z6s2b\nmqfV1Zd9q9WbQb4w7j7f3WtSw2ckHZC6fbqkGe6+092rJS2TdEyAKRa7YyQtc/dqd98p6SEls0cE\n3P0dd1+Sur1F0lJJ/SWdJum+1Gr3STojzAyLn5kdIGmspLsk1X5CmvxzIHVEZ4S73yNJ7v6Ju78v\n8s+VtpI6mFlbSR0krRHZR8bdF0raXOfuhvKm5mlF9WXfmvVmPvwl878l/SV1u5+ktzMee1vJwgKt\nq7+kVRljcs4RMyuTNFTJb9w+7r4u9dA6SX0CTSsObpX0n5JqMu4j/9wYLGmDmf3OzF4wszvNrKPI\nP3LuvlrSzZJWKlkov+fu80X2udZQ3tQ8udWiejOygjnVr/NyPcv4jHWukvSxuz+YZVOc9671kWkA\nZtZJ0iOSvu/uH2Y+5snzO/J1iYCZjZO03t0X69Ojy7sh/0i1lXSkpF+7+5GStqpOCwD5R8PMuit5\ndLNMyQKhk5lNyFyH7HOrEXnztYhAa9SbbVt3Shl7dR+d7XEzq1TyLdIvZdy9WtKAjPEBqfvQuurm\nPEC7/6WFVmZm7ZQslqe5+59Sd68zs/3d/R0z6ytpfbgZFrUvSjrNzMZK2ldSFzObJvLPlbclve3u\nz6XGf1Cyj/Ad8o/cyZKWu/tGSTKzP0o6TmSfaw39rKHmyYHWqjdDnSVjjJJvj57u7tszHnpM0tlm\nto+ZDZZ0sKRnQ8yxyC2SdLCZlZnZPko2vj8WeE5Fy8xM0t2SXnP32zIeekzS+anb50v6U93nouXc\n/Up3H+Dug5X8wNMT7j5R5J8T7v6OpFVmdkjqrpMlvSpptsg/aiskDTez0tTPoZOV/OAr2edWQz9r\nqHki1pr1ZpAr/ZnZvyXtI2lT6q6n3f3i1GNXKtln8omSb13/NecTjAEzO1XSbUp+avpud78h8JSK\nlpmdIOkpSS/p07d8rlDym/P3kgZKqpb0dXd/L8Qc48LMRkr6gbufZmY9RP45YWZfUPIDl/tIelPS\nJCV/9pB/xMysSsmDIp9IekHSZEmdRfaRMLMZkkZK6qVkv/KPJc1SA3lT87SeerK/Rsnfta1Sb3Jp\nbAAAACCLfDhLBgAAAJC3KJgBAACALCiYAQAAgCwomAEAAIAsKJgBAACALCiYAQAAgCwiu9IfAKDx\nzGyXkufqrjXD3W8KNR8AwKc4DzMA5AEz+9DdO+9lnRJ3r2lo3NjnAQCahpYMAMhjZlZtZjea2fOS\nvlbP+Bwze8nMXjazGzOet8XMpprZEknDg70AACgCFMwAkB9KzWxxxvK11P0u6V13P8rdH84cS1oo\n6UZJJ0kql3S0mZ2eel4HSf9y93J3/2eOXwsAFBV6mAEgP2xz96ENPPZwA+OjJS1w942SZGYPSDpR\n0ixJuyQ9EsVEASBuOMIMAPlvawNjl2QZ91vqPkna7nxIBQBaBQUzABSu5ySNNLOeZtZG0tmSngw8\nJwAoOrRkAEB+KDWzxRnjx939ynrWSx81dve1Zna5pAVKHl2e4+6z664HAGgZTisHAAAAZEFLBgAA\nAJAFBTMAAACQBQUzAAAAkAUFMwAAAJAFBTMAAACQBQUzAAAAkAUFMwAAAJAFBTMAAACQxf8Hx+BE\nGabA2aEAAAAASUVORK5CYII=\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import pandas as pd\n", "from IPython.display import display\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "\n", "me = pd.read_csv(\"tmp/MeasurementError.csv\", index_col = 0)\n", "display(me)\n", "me[['Measurement','Reconciled','Error']].plot(kind=\"barh\",figsize=(12,5))\n", "\n", "plt.title('Measurement Errors')\n", "plt.xlabel('Error')\n", "plt.grid()" ] }, { "cell_type": "code", "execution_count": null, "metadata": { "collapsed": false, "pycharm": {} }, "outputs": [], "source": [] }, { "cell_type": "markdown", "metadata": { "pycharm": {} }, "source": [ "\n", "< [Transportation Networks](http://nbviewer.jupyter.org/github/jckantor/CBE40455/blob/master/notebooks/03.02-Transportation-Networks.ipynb) | [Contents](toc.ipynb) | [Scheduling](http://nbviewer.jupyter.org/github/jckantor/CBE40455/blob/master/notebooks/04.00-Scheduling.ipynb) >

\"Open

\"Download\"" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.10" } }, "nbformat": 4, "nbformat_minor": 0 }