{ "metadata": { "name": "MH370_MC_ConorMyhrvold-V2-NoOutput" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "heading", "level": 1, "metadata": {}, "source": "More on Modeling the Last Flight of MH370 with Monte Carlo" }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": "Conor L. Myhrvold" }, { "cell_type": "markdown", "metadata": {}, "source": "------------------------------------------------------\n\n

Harvard University, SEAS, IACS , Computational Science & Engineering (CSE)

\n

AM207 : Advanced Scientific Computing: Stochastic Optimization Methods. Monte Carlo Methods for Inference and Data Analysis

\n

Final Project, Spring 2014. Current as of March 31.

\n\n------------------------------------------------------\n" }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "For the first version of the model, with runways, see: IPython Notebook Link" }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "For articles about this first work, see Fast Company Labs' :\n\n

\nHow I Narrowed Down The Location Of Malaysia Air Using \"Monte Carlo\" Data Models\n

\n\n

\nMore About Our Methodology: Tracking MH370 With Monte Carlo Data Models \n

" }, { "cell_type": "markdown", "metadata": {}, "source": "------------------------------------------------------\nContact Info:\n\nconor.myhrvold@gmail.com\n\nTwitter: @conormyhrvold\n\nLinkedIn: www.linkedin.com/pub/conor-myhrvold/37/583/a7/ \n\nFast Company Labs Contributor Page \n\n------------------------------------------------------" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Update Explanation: I'm updating from version one, incorporating new info released since I worked on the model. Since the goal is to make this version standalone as well, I've inserted the new material seamlessly without calling too much attention to what came first. I've also eliminated parts which are no longer relevant. For example, I took out plotting all of the runways in the region that a 777 could land on; while cool, the most likely scenario for MH370 now, according to my model and Inmarsat's analysis, is that it crashed and is at the bottom of the Indian Ocean. And, I fixed a few bugs." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Goal: The overall goal of this project is to use publically available information to pinpoint possible locations of flight MH370, a Malaysian Airlines Boeing 777-200ER which went missing in flight on March 8, 2014." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Let's get started. Here are the libraries we need. Note that after installing the Anaconda distribution of Python 2.7, which has IPython, you need to install seaborn and Basemap, which is part of matplotlib but is not included in the default installation. You need Basemap to make the maps -- there's really no other way around it. " }, { "cell_type": "code", "collapsed": false, "input": "#using Anaconda 64 bit distro of Python 2.7, Windows 7 environment (other specs will work though)\n#import libraries\n\n#numpy\nimport numpy as np\n\n#scipy\nimport scipy as sp\nfrom scipy import stats\nfrom scipy.stats import norm\nfrom scipy.stats import expon\n\n#plotting\n%matplotlib inline \n# ^^ make plots appear in IPython notebook instead of separate window\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nfrom IPython import display\nfrom mpl_toolkits.basemap import Basemap # use for plotting lat lon & world maps", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 5 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Overview - MH370" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Malaysia Airlines 370 disappeared. A variety of information sources have been obtained, which can clue us into its possible locations. I have read a ton of articles and also reached out to some of the journalists (which I have a background in) and organizations involved, in an effort to get the best data possible to put into our Monte Carlo (MC) simulation. In particular, the New York Times Hong Kong Bureau has been of great assistance to me. Why Monte Carlo? MC is an ideal approach to model where the airplane could be since unlike other air disasters, we don't know a lot about what happened yet. Several weeks have passed and no definitive wreckage has been found, let alone the airplane crash site or how it got there. This is despite a determined search effort." }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Getting the Data - Flight MH370 Known Flight Coordinates + Inmarsat Coords" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Here are some useful constants we need for converting purposes:" }, { "cell_type": "code", "collapsed": false, "input": "eq_deg_km = 111.32 # number of km/degree at eq Source: http://en.wikipedia.org/wiki/Decimal_degrees\nearth_radius = 6371 #in km, http://en.wikipedia.org/wiki/Earth\n\n#Inmarsat satellite information\nsat_height = 42170 #Inmarsat satellite height off ground, in meters\nelevation_angle = np.radians(40) #elevation angle of satellite; convert degrees to radians. Source: NYT Hong Kong Bureau", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'np' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;31m#Inmarsat satellite information\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0msat_height\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m42170\u001b[0m \u001b[1;31m#Inmarsat satellite height off ground, in meters\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 6\u001b[1;33m \u001b[0melevation_angle\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mradians\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m40\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m#elevation angle of satellite; convert degrees to radians. Source: NYT Hong Kong Bureau\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;31mNameError\u001b[0m: name 'np' is not defined" ] } ], "prompt_number": 1 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Now we'll input the coordinates relevant to us:" }, { "cell_type": "code", "collapsed": false, "input": "# The Inmarsat satellite is at 0,64.5 -- it's geostationary.\ninmarsat = [0, 64.5]\n\n#Now we plot the plane's known positions\n\n#Kuala Lumpur International Airport Coordinates: http://www.distancesfrom.com/my/Kuala-Lumpur-Airport-(KUL)-Malaysia-latitude-longitude-Kuala-Lumpur-Airport-(KUL)-Malaysia-latitude-/LatLongHistory/3308940.aspx\nkualalumpur = [2.7544829, 101.7011363]\n\n#Pulau Perak coordinates: http://tools.wmflabs.org/geohack/geohack.php?pagename=Pulau_Perak¶ms=5_40_50_N_98_56_27_E_type:isle_region:MY\n# http://en.wikipedia.org/wiki/Perak_Island -> Indonesia military radar detected near island\npulauperak = [5.680556, 98.940833]\n\n# Igari Waypoint. Source: # http://www.fallingrain.com/waypoint/SN/IGARI.html Given in hours,minutes,seconds.\nigariwaypoint = [6. + 56./60. + 12./3600., 103. + 35./60. + 6./3600.] \n\nprint \"inmarsat lat/lon:\", inmarsat[0], inmarsat[1]\nprint \"kuala lumpur int'l airport coord lat/lon:\", kualalumpur[0],kualalumpur[1]\nprint \"pulau perak lat/lon:\", pulauperak[0],pulauperak[1]\nprint \"igari waypoint lat/lon:\", igariwaypoint[0],igariwaypoint[1]", "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": "inmarsat lat/lon: 0 64.5\nkuala lumpur int'l airport coord lat/lon: 2.7544829 101.7011363\npulau perak lat/lon: 5.680556 98.940833\nigari waypoint lat/lon: 6.93666666667 103.585\n" } ], "prompt_number": 2 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Note that we don't use the Kuala Lumpur airport coordinates in our actual simulations. We *do* use the Igari Waypoint coordinate, however, in conjunction with the Pulau Perak coordinates to generate our initial heading. (Which was done in a Mathematica notebook, separate to this file, but could be easily replicable given that I provide the coordinates for both.) By changing the distribution see how sensitive this initial heading will be to our final results. However, I'll point out that irrespective of the sensitivity, this *is* our best guess of where the plane was last headed." }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Plotting the Data" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Before we plot the data, let's formally define our latitude and longitude bounds for our map, up front. That way, we can more readily change them across the document without manually editing one by one. These will double duty to make our probabilities as well:" }, { "cell_type": "code", "collapsed": false, "input": "#create lat/long grid of distance\n\nlat_min = -50 #50 S\nlat_max = 50 #50 N\nlon_min = 50 #50 E\nlon_max = 140 #130 E\nlat_space = 5 #spacing for plotting latitudes and longitudes\nlon_space = 5", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 3 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Now we'll make a map with those points on it, using Basemap, an extension of Matplotlib:" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=13000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n# plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='lower left',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('Initial Map & Data', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'plt' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m#Set figure size\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mfig\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfigsize\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m30\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m20\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;31m#Setup Basemap\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mfig\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mBasemap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwidth\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10000000\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mheight\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m13000000\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mprojection\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'lcc'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mresolution\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'c'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlat_0\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlon_0\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m90\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0msuppress_ticks\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'plt' is not defined" ] } ], "prompt_number": 4 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "This map is the basis for more complicated maps showing the plane's possible position at a given point in time, along with its flight path. The middle of the South Indian Ocean in this map is basically the middle of nowhere, but from our results this region of the South Indian Ocean, especially further down, is a very interesting area to search." }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Satellite Ping Data -- the 5th Ping" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Now we plot and incorporate the ping data from the satellite. Basically it's going to be within a big arc from the satellite. We actually don't know to the precision that Malayasia authorities claim to know. That's due to the uncertainty involved in inferring the geolocation from the engine ping. Really, it was never supposed to be used for location -- that data Malaysia Airlines did not subscribe for, so we are left with fairly substantial error in where this places the plane at the last ping mark. The other 4 pings would be critical, but those haven't been publically released, although we are now hearing that the ping time was not every hour but actually got longer over time, which indicates to some extent that MH370 moved away from the satellite (from a radial distance perspective) over time." }, { "cell_type": "code", "collapsed": false, "input": "#To get the satellite calculate we have to solve several equations which were computed on Mathematica\n\"\"\"\nComputes the ping arc distance from the satellite to the plane.\nReturns the angle in degrees.\n\"\"\"\ndef satellite_calc(radius,orbit,angle):\n interim = (np.sqrt(-radius**2+orbit**2*(1./np.cos(angle)**2))-orbit*np.tan(angle))/np.float(orbit+radius)\n return np.degrees(2*np.arctan(interim))\n\nping_arc_dist = satellite_calc(earth_radius,sat_height,elevation_angle)\nprint \"ping arc distance in degrees:\", ping_arc_dist\n\ndist_from_sat = earth_radius*np.radians(satellite_calc(earth_radius,sat_height,elevation_angle))\nprint \"distance from satellite\", dist_from_sat", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'elevation_angle' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 8\u001b[0m \u001b[1;32mreturn\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mdegrees\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m2\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0marctan\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minterim\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 9\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 10\u001b[1;33m \u001b[0mping_arc_dist\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0msatellite_calc\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mearth_radius\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0msat_height\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0melevation_angle\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 11\u001b[0m \u001b[1;32mprint\u001b[0m \u001b[1;34m\"ping arc distance in degrees:\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mping_arc_dist\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 12\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'elevation_angle' is not defined" ] } ], "prompt_number": 5 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "There are two types of approximations we can make, for a given radius of the geostationary satellite or the airplane. The first is a simple circle, which is pretty good. However, Earth is not a sphere, and so at large radii this approximation is not ideal. So I write a more complicated function to reflect the ellipse-like shape the arc will really be like. I don't include the spherical trigonometry / mathematical derivations (done in a Mathematica notebook), since they are not in the scope of finding MH370." }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\nwrite circle function. generates x&y pairs in a circle, 360 degrees\nangle in degrees, number of points to put in circle, satellite location lat/lon\n\"\"\"\ndef make_circle1(radius,pts,lon_loc,lat_loc): \n coords_array = np.zeros((pts, 2))\n for i in xrange(pts):\n coords_array[i][0] = radius*np.cos(np.radians(i)) + lat_loc \n coords_array[i][1] = radius*np.sin(np.radians(i)) + lon_loc \n return coords_array\n\n\"\"\"\nwrite ellipse function\nsince across the earth it's not actually a circle\nderived from spherical trigonometry\n\"\"\"\ndef make_circle(radius,pts,lon_loc,lat_loc):\n coords_array = np.zeros((pts, 2))\n for i in xrange(pts):\n coords_array[i][0] = radius*np.cos(np.radians(i)) + lat_loc \n coords_array[i][1] = radius*np.sin(np.radians(i))/(np.cos(np.cos(np.radians(radius))*(lat_loc+radius*np.cos(np.radians(i)))*(np.pi/180.))) + lon_loc \n return coords_array", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 6 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Now we test the two approximations to better understand how they compare to each other:" }, { "cell_type": "code", "collapsed": false, "input": "#test near the equator, -5 (5 S)\n\ntest = make_circle(8.12971613367,360,90,-5)\n\ntest_lat = []\ntest_lon = []\n\nfor i in xrange(len(test)):\n test_lat.append(test[i][0])\n test_lon.append(test[i][1])\n\ntest1 = make_circle1(8.12971613367,360,90,-5)\n\ntest_lat1 = []\ntest_lon1 = []\n\nfor i in xrange(len(test1)):\n test_lat1.append(test1[i][0])\n test_lon1.append(test1[i][1])\n\n#create figure\nplt.figure()\nplt.plot(test_lon1,test_lat1,color='red',label='simple circle')\nplt.plot(test_lon,test_lat,color='blue',label='ellipsoid')\nlegend = plt.legend(loc='lower left',fontsize=8,frameon=True,markerscale=1,prop={'size':5})\nplt.title('comparing circle approximations to each other')\nplt.legend()\nplt.show()", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "global name 'np' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m#test near the equator, -5 (5 S)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mtest\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmake_circle\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m8.12971613367\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m360\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m90\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mtest_lat\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;32m\u001b[0m in \u001b[0;36mmake_circle\u001b[1;34m(radius, pts, lon_loc, lat_loc)\u001b[0m\n\u001b[0;32m 16\u001b[0m \"\"\"\n\u001b[0;32m 17\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mmake_circle\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mradius\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mpts\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlon_loc\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlat_loc\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 18\u001b[1;33m \u001b[0mcoords_array\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mzeros\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpts\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 19\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mxrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpts\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 20\u001b[0m \u001b[0mcoords_array\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mradius\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcos\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mradians\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mlat_loc\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: global name 'np' is not defined" ] } ], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": "#test at a low latitude, -40 (40 S)\n\ntest = make_circle(8.12971613367,360,90,-40)\n\ntest_lat = []\ntest_lon = []\n\nfor i in xrange(len(test)):\n test_lat.append(test[i][0])\n test_lon.append(test[i][1])\n\ntest1 = make_circle1(8.12971613367,360,90,-40)\n\ntest_lat1 = []\ntest_lon1 = []\n\nfor i in xrange(len(test1)):\n test_lat1.append(test1[i][0])\n test_lon1.append(test1[i][1])\n\n#create figure\nplt.figure()\nplt.plot(test_lon1,test_lat1,color='red',label='simple circle')\nplt.plot(test_lon,test_lat,color='blue',label='ellipsoid')\nlegend = plt.legend(loc='lower left',fontsize=8,frameon=True,markerscale=1,prop={'size':5})\nplt.title('comparing circle approximations to each other')\nplt.legend()\nplt.show()", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "global name 'np' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m#test at a low latitude, -40 (40 S)\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 3\u001b[1;33m \u001b[0mtest\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmake_circle\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m8.12971613367\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m360\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m90\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m-\u001b[0m\u001b[1;36m40\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mtest_lat\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;32m\u001b[0m in \u001b[0;36mmake_circle\u001b[1;34m(radius, pts, lon_loc, lat_loc)\u001b[0m\n\u001b[0;32m 16\u001b[0m \"\"\"\n\u001b[0;32m 17\u001b[0m \u001b[1;32mdef\u001b[0m \u001b[0mmake_circle\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mradius\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mpts\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlon_loc\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlat_loc\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 18\u001b[1;33m \u001b[0mcoords_array\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mzeros\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpts\u001b[0m\u001b[1;33m,\u001b[0m \u001b[1;36m2\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 19\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mxrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mpts\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 20\u001b[0m \u001b[0mcoords_array\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mradius\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mcos\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mradians\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;33m+\u001b[0m \u001b[0mlat_loc\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: global name 'np' is not defined" ] } ], "prompt_number": 8 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Above we see the difference between the two circles. Remember that at the equator, 1 degree of latitude and longitude stay the same, but at the poles, the degrees of latitude contract tremendously. The ellipse we have created is *slightly* better at the equator, but much better at lower latitudes. And that's where it matters most to find our plane, if our first version is any guide (either one -- even the one with bugs, which basically had the lower latitude plot, near the equator, which caused *that* lower latitude plot to be out of line for a small fraction of the make_vector dots.)" }, { "cell_type": "code", "collapsed": false, "input": "circle_pts = make_circle(ping_arc_dist,360,64.5,0)\n#print circle_pts\n\ncircle_lat = []\nfor i in xrange(len(circle_pts)):\n circle_lat.append(circle_pts[i][0])\n\ncircle_lon = []\nfor i in xrange(len(circle_pts)):\n circle_lon.append(circle_pts[i][1])\n\nprint circle_lat[0:10]\nprint \"-------------------\"\nprint circle_lon[0:10]", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'ping_arc_dist' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mcircle_pts\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmake_circle\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mping_arc_dist\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m360\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m64.5\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[1;31m#print circle_pts\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mcircle_lat\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mxrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mcircle_pts\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'ping_arc_dist' is not defined" ] } ], "prompt_number": 9 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Incorporating New Info on Ping Distance Error" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Right after my model was done, on March 24, excellent analysis from the TMF Associates article Understanding the \"satellite ping\" conclusion... was published, pointed out that the ping distance error would be 1 or 2 degrees. Essentially, the biggest uncertainty for the ping arc is the lag time, which is apparently on the order of 300 microseconds, which round trip is 600 microseconds according to the linked calculation (recall that the plane \"saw\" the satellite at a 40 degree angle, which on the graph is 600 microseconds.) It's 1 or 2 degrees because it hasn't been established whether the measurement by the satellite is done one-way or round trip." }, { "cell_type": "code", "collapsed": false, "input": "print \"Percent error 1 way is:\", (1./40)*100\nprint \"Percent error round trip is:\", (2./40)*100", "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": "Percent error 1 way is: 2.5\nPercent error round trip is: 5.0\n" } ], "prompt_number": 10 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Thus, I will use 2.5 and 5% error. (Fortuitously, I'd picked 5% before! So with the advent of this extra information and analysis, that number is spot on, for one ping. Which *also* means 10 and 20% were reasonable if you wanted to cover an area that included multiple pings, instead of just using the 5th ping.) Now what we'll do is vary the distance from the satellite (radius) by 5% and 2.5% to build in error in where the actually was (the geostationary satellite is assumed to essentially have no error in its position, relative to the error in knowing where the plane is)." }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Inmarsat 5% error" }, { "cell_type": "code", "collapsed": false, "input": "err1_5per = 0.95*ping_arc_dist\nerr2_5per = 1.05*ping_arc_dist\n\ncircle_pts_err1_5per = make_circle(err1_5per,360,64.5,0)\ncircle_pts_err2_5per = make_circle(err2_5per,360,64.5,0)\n\ncircle_lon_err1_5per = []\ncircle_lon_err2_5per = []\ncircle_lat_err1_5per = []\ncircle_lat_err2_5per = []\n\nfor i in xrange(len(circle_pts_err1_5per)):\n circle_lon_err1_5per.append(circle_pts_err1_5per[i][1])\n \nfor i in xrange(len(circle_pts_err2_5per)):\n circle_lon_err2_5per.append(circle_pts_err2_5per[i][1])\n \nfor i in xrange(len(circle_pts_err1_5per)):\n circle_lat_err1_5per.append(circle_pts_err1_5per[i][0])\n \nfor i in xrange(len(circle_pts_err2_5per)):\n circle_lat_err2_5per.append(circle_pts_err2_5per[i][0])", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'ping_arc_dist' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0merr1_5per\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m0.95\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mping_arc_dist\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[0merr2_5per\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m1.05\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mping_arc_dist\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mcircle_pts_err1_5per\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmake_circle\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merr1_5per\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m360\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m64.5\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mcircle_pts_err2_5per\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmake_circle\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merr2_5per\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m360\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m64.5\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'ping_arc_dist' is not defined" ] } ], "prompt_number": 11 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Inmarsat 2.5% error" }, { "cell_type": "code", "collapsed": false, "input": "err1_2per = 0.975*ping_arc_dist\nerr2_2per = 1.025*ping_arc_dist\n\ncircle_pts_err1_2per = make_circle(err1_2per,360,64.5,0)\ncircle_pts_err2_2per = make_circle(err2_2per,360,64.5,0)\n\ncircle_lon_err1_2per = []\ncircle_lon_err2_2per = []\ncircle_lat_err1_2per = []\ncircle_lat_err2_2per = []\n\nfor i in xrange(len(circle_pts_err1_2per)):\n circle_lon_err1_2per.append(circle_pts_err1_2per[i][1])\n \nfor i in xrange(len(circle_pts_err2_2per)):\n circle_lon_err2_2per.append(circle_pts_err2_2per[i][1])\n \nfor i in xrange(len(circle_pts_err1_2per)):\n circle_lat_err1_2per.append(circle_pts_err1_2per[i][0])\n \nfor i in xrange(len(circle_pts_err2_2per)):\n circle_lat_err2_2per.append(circle_pts_err2_2per[i][0])", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'ping_arc_dist' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0merr1_2per\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m0.975\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mping_arc_dist\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[0merr2_2per\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m1.025\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mping_arc_dist\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[0mcircle_pts_err1_2per\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmake_circle\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merr1_2per\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m360\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m64.5\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mcircle_pts_err2_2per\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mmake_circle\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0merr2_2per\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m360\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m64.5\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'ping_arc_dist' is not defined" ] } ], "prompt_number": 12 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Now we make a map plot showing these circles. The dashed lines away from the solid red line is the error, 2.5%." }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=13000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 2.5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_2per,circle_lat_err1_2per)\nx7,y7 = fig(circle_lon_err2_2per,circle_lat_err2_2per)\nx8,y8 = fig(circle_lon_err1_5per,circle_lat_err1_5per)\nx9,y9 = fig(circle_lon_err2_5per,circle_lat_err2_5per)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='Inferred MH370 Location from Satellite, 5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 2.5 & 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\nfig.plot(x8,y8,'r--',markersize=5)\nfig.plot(x9,y9,'r--',markersize=5)\n\n# plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='lower left',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('Inmarsat Ping Estimation', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'plt' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m#Set figure size\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mfig\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfigsize\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m30\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m20\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;31m#Setup Basemap\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mfig\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mBasemap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwidth\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10000000\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mheight\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m13000000\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mprojection\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'lcc'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mresolution\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'c'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlat_0\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlon_0\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m90\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0msuppress_ticks\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'plt' is not defined" ] } ], "prompt_number": 13 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "

Now we have the starting plot that we saw in so many newspaper websites all around the world in March. We have gathered an impressive data set which forms the foundation of the second version of our Monte Carlo model." }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": "Making the Monte Carlo Model" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Let's keep our Haversine formula from our airplane runways section of the first version of this model; we need this for computing distances below. Apparently, there's a Python module haversine which has this, but let's write this function ourselves:" }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\nHaversine equation.\nComputes the great circle distance between two pairs of longitude/latitude.\nReturns the distance in m or km depending on input (I use meters.) \n\"\"\"\ndef haversine(r,lat1,lon1,lat2,lon2):\n d = 2.0*r*np.arcsin(np.sqrt(np.sin(np.radians(lat2-lat1)/2.0)**2+np.cos(np.radians(lat1))*np.cos(np.radians(lat2))*np.sin(np.radians(lon2-lon1)/2.0)**2))\n return d ", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 14 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Convert the Inmarsat line location and error bounds into probabilities" }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\nping_prob_normal is specifically the 5th ping probability, which we have.\nwe center a normal probability distribution upon the location of the radius line.\n\nd = dist_from_sat in my case and is more abstractly 'd', a distance\nr = earth_radius in my case and is is more abstractly 'r', a radius\nlat1 = sat latitude in my case\nlon1 = sat longitude in my case\nlat2, lon2 we iterate through for our function\nerr is the 5,10,or 20% error Inmarsat error\n\"\"\"\ndef ping_prob_normal(lat1,lon1,lat2,lon2,err,d,r): \n return np.exp(-0.5*((haversine(r,lat1,lon1,lat2,lon2)-d)/(err*d))**2)/(d*np.sqrt(2*np.pi)) ", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 15 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Next we make a probability grid of where the plane could be located, across our latitudes and longitudes (which we defined at the top of the document). We'll initialize this probability from the 5th ping perspective, since we've already calculated appropriate latitudes and longitudes from that. We'll keep this at a normal distribution, since the standard deviation as a percentange of the radius is small (std dev = 2.5 and 5% of the radius.)" }, { "cell_type": "code", "collapsed": false, "input": "lat_range = np.abs(lat_max)+np.abs(lat_min)\nlon_range = np.abs(lon_max)-np.abs(lon_min)\nprint \"latitude range in degrees:\", lat_range\nprint \"longitude range in degrees:\", lon_range\n", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'np' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mlat_range\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mabs\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlat_max\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m+\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mabs\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlat_min\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[0mlon_range\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mabs\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlon_max\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m-\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mabs\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlon_min\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mprint\u001b[0m \u001b[1;34m\"latitude range in degrees:\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mlat_range\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mprint\u001b[0m \u001b[1;34m\"longitude range in degrees:\"\u001b[0m\u001b[1;33m,\u001b[0m \u001b[0mlon_range\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'np' is not defined" ] } ], "prompt_number": 16 }, { "cell_type": "code", "collapsed": false, "input": "# x coord = longitude\n# y coord = latitude\nmult_fac = 10 #Use to make a finer grid, so 10 per 1 degree lat/lon , and fill with probabilities.\n\nprob_grid = np.zeros((lat_range*mult_fac,lon_range*mult_fac)) #initialize grid as numpy array\n\nfor i in xrange(lat_range*mult_fac): #across all lat grid-lets\n for j in xrange(lon_range*mult_fac): #across all lon grid-lets (so now we're iterating through rows + columns)\n prob_grid[i][j] = ping_prob_normal(inmarsat[0],inmarsat[1],(lat_min+i/np.float(mult_fac)),(lon_min+j/np.float(mult_fac)),0.05,dist_from_sat,earth_radius) \n #assuming 5% error ... 5% == 0.05", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'np' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mmult_fac\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;36m10\u001b[0m \u001b[1;31m#Use to make a finer grid, so 10 per 1 degree lat/lon , and fill with probabilities.\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 5\u001b[1;33m \u001b[0mprob_grid\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mzeros\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlat_range\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mmult_fac\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlon_range\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mmult_fac\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m#initialize grid as numpy array\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 6\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 7\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mxrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlat_range\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mmult_fac\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;31m#across all lat grid-lets\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'np' is not defined" ] } ], "prompt_number": 17 }, { "cell_type": "code", "collapsed": false, "input": "plt.figure()\nplt.plot(prob_grid)\nplt.show()", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'plt' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[1;32m----> 1\u001b[1;33m \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 2\u001b[0m \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mplot\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mprob_grid\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mshow\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'plt' is not defined" ] } ], "prompt_number": 18 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Note that I'm now making a grid with a multiplication factor of 10 instead of 1. This fancier option was not exercised in the first version of the model, as I just kept it to 1 for simplicity's sake (and to show that the \"coarseness\" of the probability grid did not have a large effect on results -- results which initially didn't have independent corroboration, but that right around the time I finished, Inmarsat released their analysis showing the plane to be near where I said it would be. So they looked reasonable to me...and then soon afterward an independent analysis -- the official one, I might add -- confirmed what I came up with, during more or less the same time interval.)" }, { "cell_type": "code", "collapsed": false, "input": "#test out with just longitude at 0 latitude\nprob_grid_lon = np.zeros((lon_range*mult_fac))\n\nfor j in xrange(lon_range*mult_fac): #across all lon grid-lets (so now we're iterating through rows + columns)\n prob_grid_lon[j] = ping_prob_normal(inmarsat[0],inmarsat[1],0,(lon_min+j/np.float(mult_fac)),0.05,dist_from_sat,earth_radius)\n\nplt.figure()\nplt.plot(prob_grid_lon)\nplt.title('longitude ping probability across the equator (0 deg lat)')\nplt.xlabel('array index -- to get longitude need to add 500, which is minimum longitude')\nplt.ylabel('probability')\nplt.show()", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'np' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m#test out with just longitude at 0 latitude\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mprob_grid_lon\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mzeros\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlon_range\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mmult_fac\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mj\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mxrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlon_range\u001b[0m\u001b[1;33m*\u001b[0m\u001b[0mmult_fac\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m \u001b[1;31m#across all lon grid-lets (so now we're iterating through rows + columns)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mprob_grid_lon\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mj\u001b[0m\u001b[1;33m]\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mping_prob_normal\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0minmarsat\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0minmarsat\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlon_min\u001b[0m\u001b[1;33m+\u001b[0m\u001b[0mj\u001b[0m\u001b[1;33m/\u001b[0m\u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfloat\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mmult_fac\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m0.05\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mdist_from_sat\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mearth_radius\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'np' is not defined" ] } ], "prompt_number": 19 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Determining MH370's Final Location -- (up to) The Last Hour" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "After this, I write a function that will make same-heading vectors from the 5th ping, to whereever the plane may finally be located. Note that the largely-offsetting bugs from the first version have been fixed!" }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\nwrite function that plots final destination from plane, from the point of the last ping.\nthis will be some period of time in between 0 minutes and an hour -- or else it would have pinged again.\nmake a point at a distance on a heading to see where the plane would be if it continued on a straight line,\nfrom the 5th ping.\n\"\"\"\ndef make_vector(ang_radius,heading,lon_loc,lat_loc):\n vec_lat = ang_radius*np.cos(np.radians(heading)) + lat_loc\n vec_lon = ang_radius*np.sin(np.radians(heading))/(np.cos(np.cos(np.radians(ang_radius))*(lat_loc+ang_radius*np.cos(np.radians(heading)))*(np.pi/180.))) + lon_loc\n return vec_lat,vec_lon", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 20 }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Initial Location Uncertainty and Randomness" }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\ntakes in a heading, a starting location, and a std dev for picking a new heading\na std dev of 30, for example, with a normal distribution, means that -30 to 30 degrees will be\nwhere most of the new heading draws will come out of (a std dev applies to both sides of the distribution.) \nand the highest probability will be straight ahead. this is of course not including the ping probability.\n\"\"\"\ndef normal_prob_step(old_heading, std_dev, start_lon, start_lat, ang_dist):\n \n angle_list = range(0,360) # ; print angle_list\n \n #we create a radius of 360 points that would be the heading for 360 possible degrees\n circle = make_circle(ang_dist,len(angle_list),start_lon,start_lat)\n \n weights = np.zeros(len(angle_list)) #make 360 array\n for i in xrange(len(weights)):\n weights[i] = np.exp(-(((np.float(angle_list[i])-180.)/std_dev)**2) /2.) / (std_dev*np.sqrt(2*np.pi)) \n #makes array of normally distributed weights as if heading was 180 degrees. Sort of a hack to make it periodic. \n \n #Now we have to translate it back to whatever the heading should be, instead of 180 degrees\n #Fortunately we can use numpy's roll. Implementing our own would be a pain.\n s_weights = np.roll(weights,-180+np.int(old_heading))\n \n #initialize new possible coordinates within an hr's distance, new weights for the odds, and new angles\n #(depending on whether the plane would go off the grid or not)\n new_circle = []\n new_weights = []\n new_angles = []\n \n #make sure lat & lon are in bounds\n for i in xrange(len(circle)):\n if circle[i][0] >= lat_min and circle[i][0] <= lat_max and circle[i][1] >= lon_min and circle[i][1] <= lon_max:\n new_circle.append(circle[i]) \n new_weights.append(s_weights[i])\n new_angles.append(angle_list[i])\n\n return new_circle,new_weights,new_angles\n", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 21 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "We incorporate the above function our 5 step model -- 1 for each hour, since that's when the pings were received. Afterward, the plane went down sometime in an hr, so I plot where the final contact spot could be at 1/4,1/2,3/4, and 59/60 hrs." }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\na function which given a list of discrete probabilities for each destination point, \nit will choose one of those points.\n\nheading_init -- initial direction was headed at last known point\nlon_init,lat_init -- last known point of plane in longitude and latitude\nkm_hop -- how far the plane went in the time interval, 1 hr. So in simplest case, the 777's cruising speed/hr.\nstd_dev -- the standard deviation of the heading, based on a normal distribution from the current heading (0 deg).\nping_percent_err -- what % error you assume in the Inmarsat 5th ping. either 2.5 or 5%.\n\nuses normal distribution for heading\n\n\"\"\"\ndef five_hop_model_normal(heading_init,lon_init,lat_init,km_hop,std_dev,ping_percent_err): \n \n #initialize\n plane_lat = np.zeros(5) #initialize plane location after each hop (assumed to be 1 hr for now)\n plane_lon = np.zeros(5) \n lat = lat_init\n lon = lon_init\n heading = heading_init\n \n for i in xrange(len(plane_lat)):\n new_circle,new_weights,new_angles = normal_prob_step(heading,std_dev,lon,lat,km_hop/eq_deg_km)\n #new_circle gives up possible coords for diff headings\n \n raw_weights = np.zeros(len(new_circle))\n for j in xrange(len(new_circle)):\n raw_weights[j] = new_weights[j]*ping_prob_normal(inmarsat[0],inmarsat[1],new_circle[j][0],new_circle[j][1],ping_percent_err,dist_from_sat,earth_radius) \n \n probs = raw_weights / np.sum(raw_weights) #normalize\n \n index = range(len(new_circle))\n chosen = np.random.choice(index,size=None,p=probs)\n #print \"chosen\",chosen\n \n heading = new_angles[chosen] #update heading\n \n plane_lat[i],plane_lon[i] = new_circle[chosen] #update position\n lat = plane_lat[i]\n lon = plane_lon[i]\n \n #at end of simulation, run the last location & heading for plane for 4 different times\n route1 = make_vector(0.25*km_hop/eq_deg_km,heading,lon,lat)\n route2 = make_vector(0.5*km_hop/eq_deg_km,heading,lon,lat)\n route3 = make_vector(0.75*km_hop/eq_deg_km,heading,lon,lat)\n route4 = make_vector((59./60.)*km_hop/eq_deg_km,heading,lon,lat)\n\n new_plane_lat = np.zeros(9)\n new_plane_lon = np.zeros(9)\n \n for i in xrange(len(plane_lat)):\n new_plane_lat[i] = plane_lat[i]\n new_plane_lon[i] = plane_lon[i]\n \n new_plane_lat[5] = route1[0]\n new_plane_lat[6] = route2[0]\n new_plane_lat[7] = route3[0]\n new_plane_lat[8] = route4[0]\n new_plane_lon[5] = route1[1]\n new_plane_lon[6] = route2[1]\n new_plane_lon[7] = route3[1]\n new_plane_lon[8] = route4[1]\n \n return new_plane_lat,new_plane_lon", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 22 }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": "Modeling Constants (can vary)" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Now we test out using the last known heading, a 777's typical cruising speed, and the last known coordinates, below:" }, { "cell_type": "code", "collapsed": false, "input": "last_known_heading = 255.136 #calculated in Mathematica from MH370's two last publically known locations:\n #when it deviated from its flight path, and when it was last detected by Malyasian military radar\n #0 degrees is due north, so this is basically to the west (270 degrees), but slightly south\n\nkm_hop = 905 #assuming 1 hr intervals, at 905 km/hr which is 777 cruising speed -- use for test case\n # max speed of a Boeing 777 is 950 km/hr FYI\n\nN = 1000 #define number of simulations to run", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 23 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": "5% Inmarsat error" }, { "cell_type": "code", "collapsed": false, "input": "percenterror = 0.05\n\nstd_dev = 30 #the standard deviation is the only arbitrary choice for us, along with the N=1000 simulations.\n #but it fits the notion that the plane is likely to continue on the same course, allowing for\n #some turns / heading change over the course of an hour. I stand by this number, although it's easy\n #to change to 15 or 45 and see what the difference is. The smaller the number the narrower the\n #ability to change heading is. The larger the number the more like a true \"random walk\" the plane's\n #direction and by consequence, location will be, at each time step.", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 24 }, { "cell_type": "code", "collapsed": false, "input": "plane_hops = []\n\nfor i in xrange(N):\n plane_hops.append(five_hop_model_normal(last_known_heading,pulauperak[1],pulauperak[0],km_hop,std_dev,percenterror))", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "global name 'np' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 2\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 3\u001b[0m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mxrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mN\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 4\u001b[1;33m \u001b[0mplane_hops\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfive_hop_model_normal\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlast_known_heading\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mpulauperak\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mpulauperak\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mkm_hop\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mstd_dev\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mpercenterror\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m", "\u001b[1;32m\u001b[0m in \u001b[0;36mfive_hop_model_normal\u001b[1;34m(heading_init, lon_init, lat_init, km_hop, std_dev, ping_percent_err)\u001b[0m\n\u001b[0;32m 15\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 16\u001b[0m \u001b[1;31m#initialize\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 17\u001b[1;33m \u001b[0mplane_lat\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mzeros\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m \u001b[1;31m#initialize plane location after each hop (assumed to be 1 hr for now)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 18\u001b[0m \u001b[0mplane_lon\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mnp\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mzeros\u001b[0m\u001b[1;33m(\u001b[0m\u001b[1;36m5\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 19\u001b[0m \u001b[0mlat\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mlat_init\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: global name 'np' is not defined" ] } ], "prompt_number": 25 }, { "cell_type": "code", "collapsed": false, "input": "first_lat = []\ntwo_lat = []\nthree_lat = []\nfour_lat = []\nfinal_lat = []\n\nfirst_lon = []\ntwo_lon = []\nthree_lon = []\nfour_lon = []\nfinal_lon = []\n\nroute1_lat = []\nroute2_lat = []\nroute3_lat = []\nroute4_lat = []\n\nroute1_lon = []\nroute2_lon = []\nroute3_lon = []\nroute4_lon = []\n\nfor i in xrange(len(plane_hops)):\n first_lat.append(plane_hops[i][0][0])\n first_lon.append(plane_hops[i][1][0])\n two_lat.append(plane_hops[i][0][1])\n two_lon.append(plane_hops[i][1][1])\n three_lat.append(plane_hops[i][0][2])\n three_lon.append(plane_hops[i][1][2])\n four_lat.append(plane_hops[i][0][3])\n four_lon.append(plane_hops[i][1][3])\n final_lat.append(plane_hops[i][0][4])\n final_lon.append(plane_hops[i][1][4])\n \n route1_lat.append(plane_hops[i][0][5])\n route1_lon.append(plane_hops[i][1][5])\n route2_lat.append(plane_hops[i][0][6])\n route2_lon.append(plane_hops[i][1][6])\n route3_lat.append(plane_hops[i][0][7])\n route3_lon.append(plane_hops[i][1][7])\n route4_lat.append(plane_hops[i][0][8])\n route4_lon.append(plane_hops[i][1][8])", "language": "python", "metadata": {}, "outputs": [], "prompt_number": 26 }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=13000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_5per,circle_lat_err1_5per)\nx7,y7 = fig(circle_lon_err2_5per,circle_lat_err2_5per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon,first_lat)\nx10,y10 = fig(two_lon,two_lat)\nx11,y11 = fig(three_lon,three_lat)\nx12,y12 = fig(four_lon,four_lat)\nx13,y13 = fig(final_lon,final_lat)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='lower left',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'plt' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m#Set figure size\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mfig\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfigsize\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m30\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m20\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;31m#Setup Basemap\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mfig\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mBasemap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwidth\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10000000\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mheight\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m13000000\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mprojection\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'lcc'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mresolution\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'c'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlat_0\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlon_0\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m90\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0msuppress_ticks\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'plt' is not defined" ] } ], "prompt_number": 27 }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_5per,circle_lat_err1_5per)\nx7,y7 = fig(circle_lon_err2_5per,circle_lat_err2_5per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon,first_lat)\nx10,y10 = fig(two_lon,two_lat)\nx11,y11 = fig(three_lon,three_lat)\nx12,y12 = fig(four_lon,four_lat)\nx13,y13 = fig(final_lon,final_lat)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon,route1_lat)\nx15,y15 = fig(route2_lon,route2_lat)\nx16,y16 = fig(route3_lon,route3_lat)\nx17,y17 = fig(route4_lon,route4_lat)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'plt' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m#Set figure size\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mfig\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfigsize\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m30\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m20\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;31m#Setup Basemap\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mfig\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mBasemap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwidth\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10000000\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mheight\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m18000000\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mprojection\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'lcc'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mresolution\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'c'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlat_0\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlon_0\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m90\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0msuppress_ticks\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'plt' is not defined" ] } ], "prompt_number": 28 }, { "cell_type": "heading", "level": 1, "metadata": {}, "source": "2.5% Inmarsat error" }, { "cell_type": "code", "collapsed": false, "input": "percenterror = 0.025\n\nstd_dev = 30", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "plane_hops = []\n\nfor i in xrange(N):\n plane_hops.append(five_hop_model_normal(last_known_heading,pulauperak[1],pulauperak[0],km_hop,std_dev,percenterror))", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "first_lat = []\ntwo_lat = []\nthree_lat = []\nfour_lat = []\nfinal_lat = []\n\nfirst_lon = []\ntwo_lon = []\nthree_lon = []\nfour_lon = []\nfinal_lon = []\n\nroute1_lat = []\nroute2_lat = []\nroute3_lat = []\nroute4_lat = []\n\nroute1_lon = []\nroute2_lon = []\nroute3_lon = []\nroute4_lon = []\n\nfor i in xrange(len(plane_hops)):\n first_lat.append(plane_hops[i][0][0])\n first_lon.append(plane_hops[i][1][0])\n two_lat.append(plane_hops[i][0][1])\n two_lon.append(plane_hops[i][1][1])\n three_lat.append(plane_hops[i][0][2])\n three_lon.append(plane_hops[i][1][2])\n four_lat.append(plane_hops[i][0][3])\n four_lon.append(plane_hops[i][1][3])\n final_lat.append(plane_hops[i][0][4])\n final_lon.append(plane_hops[i][1][4])\n \n route1_lat.append(plane_hops[i][0][5])\n route1_lon.append(plane_hops[i][1][5])\n route2_lat.append(plane_hops[i][0][6])\n route2_lon.append(plane_hops[i][1][6])\n route3_lat.append(plane_hops[i][0][7])\n route3_lon.append(plane_hops[i][1][7])\n route4_lat.append(plane_hops[i][0][8])\n route4_lon.append(plane_hops[i][1][8])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=13000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 2.5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_2per,circle_lat_err1_2per)\nx7,y7 = fig(circle_lon_err2_2per,circle_lat_err2_2per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon,first_lat)\nx10,y10 = fig(two_lon,two_lat)\nx11,y11 = fig(three_lon,three_lat)\nx12,y12 = fig(four_lon,four_lat)\nx13,y13 = fig(final_lon,final_lat)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 2.5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='lower left',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 2.5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_2per,circle_lat_err1_2per)\nx7,y7 = fig(circle_lon_err2_2per,circle_lat_err2_2per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon,first_lat)\nx10,y10 = fig(two_lon,two_lat)\nx11,y11 = fig(three_lon,three_lat)\nx12,y12 = fig(four_lon,four_lat)\nx13,y13 = fig(final_lon,final_lat)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon,route1_lat)\nx15,y15 = fig(route2_lon,route2_lat)\nx16,y16 = fig(route3_lon,route3_lat)\nx17,y17 = fig(route4_lon,route4_lat)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 2.5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": "Different Distributions Besides Normal for the Heading -- Von Mises and Wrapped Cauchy" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Our normal heading distribution was great for a lot of reasons (including its ability to act like a uniform distribution if you pump the standard deviation up.) *But*, now it's time to consider a few other distributions as well, ones more exotic than our 'plain vanilla' one (well, the normal one that people use!) I'll pick ones that are popular to do along a unit circle; since our heading choice will be along a circle." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "First, let's try a Von Mises distribution for our heading. Here's a general function that can do that:" }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\ntakes in angle and heading in degrees (note conversion to radians in function)\nk goes from 0 to infinity and is a point at infinity, and a uniform distribution at 0\n\"\"\"\ndef von_mises(angle,heading,k):\n return np.exp(k*np.cos(np.radians(angle)-np.radians(heading)))/(2*np.pi*np.i0(k))", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Let's test this function to see if it works. We'll test in with a heading of 150 degrees (which means that the curves should be centered at 150, i.e. the mean should be 150):" }, { "cell_type": "code", "collapsed": false, "input": "circle_test = []\n\nfor i in xrange(360):\n circle_test.append(von_mises(i,150,0))\n \nplt.figure()\nplt.plot(circle_test)\nplt.title('k=0 -- should be uniform')\nplt.show()\n\ncircle_test2 = []\n\nfor i in xrange(360):\n circle_test2.append(von_mises(i,150,1))\n\nplt.figure()\nplt.plot(circle_test2)\nplt.title('k=1 -- should be bell curve')\nplt.show()\n\ncircle_test3 = []\n\nfor i in xrange(360):\n circle_test3.append(von_mises(i,150,10))\n \nplt.figure()\nplt.plot(circle_test3)\nplt.title('k=10 -- should be contracting/converging toward a point')\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "It works! The other distribution we can try is a Wrapped Cauchy distribution for our heading. It's also a popular one to use on a unit circle (so you can say I used 'circular logic' when deciding to pick these two other distributions!)" }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\ntakes in angle and heading in degrees (note conversion to radians in function)\nk goes from 0-1 and is a point at 1, and a uniform distribution at 0\n\"\"\"\ndef wrapped_cauchy(angle,heading,k):\n return np.float((1-k**2))/(1+k**2-2*k*np.cos(np.radians(angle)-np.radians(heading)))", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "We'll test this function in a similar manner:" }, { "cell_type": "code", "collapsed": false, "input": "circle_test = []\n\nfor i in xrange(360):\n circle_test.append(wrapped_cauchy(i,150,0))\n \nplt.figure()\nplt.plot(circle_test)\nplt.title('k=0 -- should be uniform')\nplt.show()\n\ncircle_test2 = []\n\nfor i in xrange(360):\n circle_test2.append(wrapped_cauchy(i,150,0.5))\n\nplt.figure()\nplt.plot(circle_test2)\nplt.title('k=0.5 -- should be bell curve')\nplt.show()\n\ncircle_test3 = []\n\nfor i in xrange(360):\n circle_test3.append(wrapped_cauchy(i,150,0.99))\n \nplt.figure()\nplt.plot(circle_test3)\nplt.title('k=0.99 -- should be contracting/converging toward a point')\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "It works as well. :0) :0) :0) Right, so now we have to update the prob_step functions to have Von Mises and Wrapped Cauchy for the heading, instead of a normal distribution. Note that k is effectively standard deviation, in that it varies the distribution to be point-like to uniform at the extreme ends:" }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\ntakes in a heading, a starting location, and a k for picking a new heading based on the Von Mises distribution.\nk = 0 -> uniform distribution. jump all over the place, true random walk.\nk = 1,10 -> similar to before. tends to go straight ahead or near-straight ahead.\n 1 is like a normal distribution with a large standard deviation from the mean.\n 10 is like a normal distribution with a small standard deviation from the mean.\n\"\"\"\ndef von_mises_prob_step(heading, k, start_lon, start_lat, ang_dist):\n \n angle_list = range(0,360)\n \n #we create a radius of 360 points that would be the heading for 360 possible degrees\n circle = make_circle(ang_dist,len(angle_list),start_lon,start_lat)\n \n weights = np.zeros(len(angle_list)) #make 360 array\n for i in xrange(len(weights)):\n weights[i] = von_mises(angle_list[i],heading,k)\n #makes array of von mises distributed weights. \n \n #initialize new possible coordinates within an hr's distance, new weights for the odds, and new angles\n new_circle = []\n new_weights = []\n new_angles = []\n \n #make sure lat & lon are in bounds\n for i in xrange(len(circle)):\n if circle[i][0] >= lat_min and circle[i][0] <= lat_max and circle[i][1] >= lon_min and circle[i][1] <= lon_max:\n new_circle.append(circle[i]) \n new_weights.append(weights[i])\n new_angles.append(angle_list[i])\n \n return new_circle,new_weights,new_angles\n", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\ntakes in a heading, a starting location, and a k for picking a new heading based on the Wrapped Cauchy distribution.\nk = 0 -> uniform distribution. jump all over the place, true random walk.\nk = 0.5 -> similar to before. tends to go straight ahead or near-straight ahead.\nk = 0.95 -> plane makes a bee-line for straight ahead. there's just no \"convincing\" it otherwise. \n almost no deviation from 0 degrees relative to previous heading.\n\"\"\"\ndef wrapped_cauchy_prob_step(heading, k, start_lon, start_lat, ang_dist):\n \n angle_list = range(0,360)\n \n #we create a radius of 360 points that would be the heading for 360 possible degrees\n circle = make_circle(ang_dist,len(angle_list),start_lon,start_lat)\n \n weights = np.zeros(len(angle_list)) #make 360 array\n for i in xrange(len(weights)):\n weights[i] = wrapped_cauchy(angle_list[i],heading,k)\n\n #initialize new possible coordinates within an hr's distance, new weights for the odds, and new angles\n new_circle = []\n new_weights = []\n new_angles = []\n \n #make sure lat & lon are in bounds\n for i in xrange(len(circle)):\n if circle[i][0] >= lat_min and circle[i][0] <= lat_max and circle[i][1] >= lon_min and circle[i][1] <= lon_max:\n new_circle.append(circle[i]) \n new_weights.append(weights[i])\n new_angles.append(angle_list[i])\n \n return new_circle,new_weights,new_angles\n", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Finally we update our five hop function with the other distributions. There really isn't any math involved here -- just replacing with the appropriate functions and modifying the names of the inputs to better reflect what's going on in the Wrapped Cauchy and Von Mises distributions for headings:" }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\na function which given a list of discrete probabilities for each destination point, \nit will choose one of those points.\n\nheading_init -- initial direction was headed at last known point\nlon_init,lat_init -- last known point of plane in longitude and latitude\nkm_hop -- how far the plane went in the time interval, 1 hr. So in simplest case, the 777's cruising speed/hr.\nk -- affects the heading distribution, based on a Von Mises distribution from the current heading (0 deg).\nping_percent_err -- what % error you assume in the Inmarsat 5th ping. either 2.5 or 5%.\n\nuses Von Mises distribution for heading\n\n\"\"\"\ndef five_hop_model_von_mises(heading_init,lon_init,lat_init,km_hop,k,ping_percent_err): \n \n #initialize\n plane_lat = np.zeros(5) #initialize plane location after each hop (assumed to be 1 hr for now)\n plane_lon = np.zeros(5) \n lat = lat_init\n lon = lon_init\n heading = heading_init\n \n for i in xrange(len(plane_lat)):\n new_circle,new_weights,new_angles = von_mises_prob_step(heading,k,lon,lat,km_hop/eq_deg_km)\n #new_circle gives up possible coords for diff headings\n \n raw_weights = np.zeros(len(new_circle))\n for j in xrange(len(new_circle)):\n raw_weights[j] = new_weights[j]*ping_prob_normal(inmarsat[0],inmarsat[1],new_circle[j][0],new_circle[j][1],ping_percent_err,dist_from_sat,earth_radius) \n \n probs = raw_weights / np.sum(raw_weights) #normalize\n \n index = range(len(new_circle))\n chosen = np.random.choice(index,size=None,p=probs)\n #print \"chosen\",chosen\n \n heading = new_angles[chosen] #update heading\n \n plane_lat[i],plane_lon[i] = new_circle[chosen] #update position\n lat = plane_lat[i]\n lon = plane_lon[i]\n \n #at end of simulation, run the last location & heading for plane for 4 different times\n route1 = make_vector(0.25*km_hop/eq_deg_km,heading,lon,lat)\n route2 = make_vector(0.5*km_hop/eq_deg_km,heading,lon,lat)\n route3 = make_vector(0.75*km_hop/eq_deg_km,heading,lon,lat)\n route4 = make_vector((59./60.)*km_hop/eq_deg_km,heading,lon,lat)\n\n new_plane_lat = np.zeros(9)\n new_plane_lon = np.zeros(9)\n \n for i in xrange(len(plane_lat)):\n new_plane_lat[i] = plane_lat[i]\n new_plane_lon[i] = plane_lon[i]\n \n new_plane_lat[5] = route1[0]\n new_plane_lat[6] = route2[0]\n new_plane_lat[7] = route3[0]\n new_plane_lat[8] = route4[0]\n new_plane_lon[5] = route1[1]\n new_plane_lon[6] = route2[1]\n new_plane_lon[7] = route3[1]\n new_plane_lon[8] = route4[1]\n \n return new_plane_lat,new_plane_lon", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\na function which given a list of discrete probabilities for each destination point, \nit will choose one of those points.\n\nheading_init -- initial direction was headed at last known point\nlon_init,lat_init -- last known point of plane in longitude and latitude\nkm_hop -- how far the plane went in the time interval, 1 hr. So in simplest case, the 777's cruising speed/hr.\nk -- affects the heading distribution, based on a Wrapped Cauchy distribution from the current heading (0 deg).\nping_percent_err -- what % error you assume in the Inmarsat 5th ping. either 2.5 or 5%.\n\nuses Wrapped Cauchy distribution for heading\n\n\"\"\"\ndef five_hop_model_wrapped_cauchy(heading_init,lon_init,lat_init,km_hop,k,ping_percent_err): \n \n #initialize\n plane_lat = np.zeros(5) #initialize plane location after each hop (assumed to be 1 hr for now)\n plane_lon = np.zeros(5) \n lat = lat_init\n lon = lon_init\n heading = heading_init\n \n for i in xrange(len(plane_lat)):\n new_circle,new_weights,new_angles = wrapped_cauchy_prob_step(heading,k,lon,lat,km_hop/eq_deg_km)\n #new_circle gives up possible coords for diff headings\n \n raw_weights = np.zeros(len(new_circle))\n for j in xrange(len(new_circle)):\n raw_weights[j] = new_weights[j]*ping_prob_normal(inmarsat[0],inmarsat[1],new_circle[j][0],new_circle[j][1],ping_percent_err,dist_from_sat,earth_radius) \n \n probs = raw_weights / np.sum(raw_weights) #normalize\n \n index = range(len(new_circle))\n chosen = np.random.choice(index,size=None,p=probs)\n #print \"chosen\",chosen\n \n heading = new_angles[chosen] #update heading\n \n plane_lat[i],plane_lon[i] = new_circle[chosen] #update position\n lat = plane_lat[i]\n lon = plane_lon[i]\n \n #at end of simulation, run the last location & heading for plane for 4 different times\n route1 = make_vector(0.25*km_hop/eq_deg_km,heading,lon,lat)\n route2 = make_vector(0.5*km_hop/eq_deg_km,heading,lon,lat)\n route3 = make_vector(0.75*km_hop/eq_deg_km,heading,lon,lat)\n route4 = make_vector((59./60.)*km_hop/eq_deg_km,heading,lon,lat)\n\n new_plane_lat = np.zeros(9)\n new_plane_lon = np.zeros(9)\n \n for i in xrange(len(plane_lat)):\n new_plane_lat[i] = plane_lat[i]\n new_plane_lon[i] = plane_lon[i]\n \n new_plane_lat[5] = route1[0]\n new_plane_lat[6] = route2[0]\n new_plane_lat[7] = route3[0]\n new_plane_lat[8] = route4[0]\n new_plane_lon[5] = route1[1]\n new_plane_lon[6] = route2[1]\n new_plane_lon[7] = route3[1]\n new_plane_lon[8] = route4[1]\n \n return new_plane_lat,new_plane_lon", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": "Running Code with New Heading Distributions" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Now we'll run the code with 5% and 2.5% to see if there are any major changes. We've made our probability grid, so all we need now is to rereun the simulations substituting in our different heading distribution. I'll vary these by more than what I got for the normal distribution with a std dev of 30; otherwise, it follows from the above functions that we could pick parameters for all 3 distributions (normal, von mises, wrapped cauchy) that would all result in the similar looking curves." }, { "cell_type": "code", "collapsed": false, "input": "last_known_heading = 255.136\n\nkm_hop = 905 #assuming 1 hr intervals, at 905 km/hr which is 777 cruising speed -- use for test case\n # max speed of a Boeing 777 is 950 km/hr FYI\n\nN = 1000 #define number of simulations to run -- set to 1000, but set low number to make sure it's working first.", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Von Mises" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "To show what a uniform distribution (random walk) to a point (straight ahead scenario), along with the realistic in between (tends to go straight, but can turn), I'll use the same k values that I used to test the Von Mises function. And I'll do these for both the 2.5% std dev error and the 5% std dev error for the ping probability distribution, which remains normal." }, { "cell_type": "code", "collapsed": false, "input": "percenterror1, percenterror2 = 0.05, 0.025\n\nk1, k2, k3 = 0, 1, 10 #Von Mises constants -- uniform, bell, point-like", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "#5 percent error w/ different ks\nplane_hops_5per_k1 = []\nplane_hops_5per_k2 = []\nplane_hops_5per_k3 = []\n\n#2.5 percent error w/ different ks\nplane_hops_2per_k1 = []\nplane_hops_2per_k2 = []\nplane_hops_2per_k3 = []\n\nfor i in xrange(N):\n #5% error runs\n plane_hops_5per_k1.append(five_hop_model_von_mises(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k1,percenterror1))\n plane_hops_5per_k2.append(five_hop_model_von_mises(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k2,percenterror1))\n plane_hops_5per_k3.append(five_hop_model_von_mises(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k3,percenterror1))\n #2.5% error runs\n plane_hops_2per_k1.append(five_hop_model_von_mises(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k1,percenterror2))\n plane_hops_2per_k2.append(five_hop_model_von_mises(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k2,percenterror2))\n plane_hops_2per_k3.append(five_hop_model_von_mises(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k3,percenterror2))", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "The above loop should take a little while to run. Unfortunately, given the way I've written the code by appending to lists, the below will also be a little long (in terms of space); but just run the below cells and it should quickly (in terms of run time) gather all of the data we've generated into lists for plotting purposes:" }, { "cell_type": "code", "collapsed": false, "input": "# 5per_k1 run\n\nfirst_lat_5per_k1 = []\ntwo_lat_5per_k1 = []\nthree_lat_5per_k1 = []\nfour_lat_5per_k1 = []\nfinal_lat_5per_k1 = []\n\nfirst_lon_5per_k1 = []\ntwo_lon_5per_k1 = []\nthree_lon_5per_k1 = []\nfour_lon_5per_k1 = []\nfinal_lon_5per_k1 = []\n\nroute1_lat_5per_k1 = []\nroute2_lat_5per_k1 = []\nroute3_lat_5per_k1 = []\nroute4_lat_5per_k1 = []\n\nroute1_lon_5per_k1 = []\nroute2_lon_5per_k1 = []\nroute3_lon_5per_k1 = []\nroute4_lon_5per_k1 = []\n\nfor i in xrange(len(plane_hops_5per_k1)):\n first_lat_5per_k1.append(plane_hops_5per_k1[i][0][0])\n first_lon_5per_k1.append(plane_hops_5per_k1[i][1][0])\n two_lat_5per_k1.append(plane_hops_5per_k1[i][0][1])\n two_lon_5per_k1.append(plane_hops_5per_k1[i][1][1])\n three_lat_5per_k1.append(plane_hops_5per_k1[i][0][2])\n three_lon_5per_k1.append(plane_hops_5per_k1[i][1][2])\n four_lat_5per_k1.append(plane_hops_5per_k1[i][0][3])\n four_lon_5per_k1.append(plane_hops_5per_k1[i][1][3])\n final_lat_5per_k1.append(plane_hops_5per_k1[i][0][4])\n final_lon_5per_k1.append(plane_hops_5per_k1[i][1][4])\n \n route1_lat_5per_k1.append(plane_hops_5per_k1[i][0][5])\n route1_lon_5per_k1.append(plane_hops_5per_k1[i][1][5])\n route2_lat_5per_k1.append(plane_hops_5per_k1[i][0][6])\n route2_lon_5per_k1.append(plane_hops_5per_k1[i][1][6])\n route3_lat_5per_k1.append(plane_hops_5per_k1[i][0][7])\n route3_lon_5per_k1.append(plane_hops_5per_k1[i][1][7])\n route4_lat_5per_k1.append(plane_hops_5per_k1[i][0][8])\n route4_lon_5per_k1.append(plane_hops_5per_k1[i][1][8])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "# 5per_k2 run\n\nfirst_lat_5per_k2 = []\ntwo_lat_5per_k2 = []\nthree_lat_5per_k2 = []\nfour_lat_5per_k2 = []\nfinal_lat_5per_k2 = []\n\nfirst_lon_5per_k2 = []\ntwo_lon_5per_k2 = []\nthree_lon_5per_k2 = []\nfour_lon_5per_k2 = []\nfinal_lon_5per_k2 = []\n\nroute1_lat_5per_k2 = []\nroute2_lat_5per_k2 = []\nroute3_lat_5per_k2 = []\nroute4_lat_5per_k2 = []\n\nroute1_lon_5per_k2 = []\nroute2_lon_5per_k2 = []\nroute3_lon_5per_k2 = []\nroute4_lon_5per_k2 = []\n\nfor i in xrange(len(plane_hops_5per_k2)):\n first_lat_5per_k2.append(plane_hops_5per_k2[i][0][0])\n first_lon_5per_k2.append(plane_hops_5per_k2[i][1][0])\n two_lat_5per_k2.append(plane_hops_5per_k2[i][0][1])\n two_lon_5per_k2.append(plane_hops_5per_k2[i][1][1])\n three_lat_5per_k2.append(plane_hops_5per_k2[i][0][2])\n three_lon_5per_k2.append(plane_hops_5per_k2[i][1][2])\n four_lat_5per_k2.append(plane_hops_5per_k2[i][0][3])\n four_lon_5per_k2.append(plane_hops_5per_k2[i][1][3])\n final_lat_5per_k2.append(plane_hops_5per_k2[i][0][4])\n final_lon_5per_k2.append(plane_hops_5per_k2[i][1][4])\n \n route1_lat_5per_k2.append(plane_hops_5per_k2[i][0][5])\n route1_lon_5per_k2.append(plane_hops_5per_k2[i][1][5])\n route2_lat_5per_k2.append(plane_hops_5per_k2[i][0][6])\n route2_lon_5per_k2.append(plane_hops_5per_k2[i][1][6])\n route3_lat_5per_k2.append(plane_hops_5per_k2[i][0][7])\n route3_lon_5per_k2.append(plane_hops_5per_k2[i][1][7])\n route4_lat_5per_k2.append(plane_hops_5per_k2[i][0][8])\n route4_lon_5per_k2.append(plane_hops_5per_k2[i][1][8])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "# 5per_k3 run\n\nfirst_lat_5per_k3 = []\ntwo_lat_5per_k3 = []\nthree_lat_5per_k3 = []\nfour_lat_5per_k3 = []\nfinal_lat_5per_k3 = []\n\nfirst_lon_5per_k3 = []\ntwo_lon_5per_k3 = []\nthree_lon_5per_k3 = []\nfour_lon_5per_k3 = []\nfinal_lon_5per_k3 = []\n\nroute1_lat_5per_k3 = []\nroute2_lat_5per_k3 = []\nroute3_lat_5per_k3 = []\nroute4_lat_5per_k3 = []\n\nroute1_lon_5per_k3 = []\nroute2_lon_5per_k3 = []\nroute3_lon_5per_k3 = []\nroute4_lon_5per_k3 = []\n\nfor i in xrange(len(plane_hops_5per_k3)):\n first_lat_5per_k3.append(plane_hops_5per_k3[i][0][0])\n first_lon_5per_k3.append(plane_hops_5per_k3[i][1][0])\n two_lat_5per_k3.append(plane_hops_5per_k3[i][0][1])\n two_lon_5per_k3.append(plane_hops_5per_k3[i][1][1])\n three_lat_5per_k3.append(plane_hops_5per_k3[i][0][2])\n three_lon_5per_k3.append(plane_hops_5per_k3[i][1][2])\n four_lat_5per_k3.append(plane_hops_5per_k3[i][0][3])\n four_lon_5per_k3.append(plane_hops_5per_k3[i][1][3])\n final_lat_5per_k3.append(plane_hops_5per_k3[i][0][4])\n final_lon_5per_k3.append(plane_hops_5per_k3[i][1][4])\n \n route1_lat_5per_k3.append(plane_hops_5per_k3[i][0][5])\n route1_lon_5per_k3.append(plane_hops_5per_k3[i][1][5])\n route2_lat_5per_k3.append(plane_hops_5per_k3[i][0][6])\n route2_lon_5per_k3.append(plane_hops_5per_k3[i][1][6])\n route3_lat_5per_k3.append(plane_hops_5per_k3[i][0][7])\n route3_lon_5per_k3.append(plane_hops_5per_k3[i][1][7])\n route4_lat_5per_k3.append(plane_hops_5per_k3[i][0][8])\n route4_lon_5per_k3.append(plane_hops_5per_k3[i][1][8])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "# 2per_k1 run\n\nfirst_lat_2per_k1 = []\ntwo_lat_2per_k1 = []\nthree_lat_2per_k1 = []\nfour_lat_2per_k1 = []\nfinal_lat_2per_k1 = []\n\nfirst_lon_2per_k1 = []\ntwo_lon_2per_k1 = []\nthree_lon_2per_k1 = []\nfour_lon_2per_k1 = []\nfinal_lon_2per_k1 = []\n\nroute1_lat_2per_k1 = []\nroute2_lat_2per_k1 = []\nroute3_lat_2per_k1 = []\nroute4_lat_2per_k1 = []\n\nroute1_lon_2per_k1 = []\nroute2_lon_2per_k1 = []\nroute3_lon_2per_k1 = []\nroute4_lon_2per_k1 = []\n\nfor i in xrange(len(plane_hops_2per_k1)):\n first_lat_2per_k1.append(plane_hops_2per_k1[i][0][0])\n first_lon_2per_k1.append(plane_hops_2per_k1[i][1][0])\n two_lat_2per_k1.append(plane_hops_2per_k1[i][0][1])\n two_lon_2per_k1.append(plane_hops_2per_k1[i][1][1])\n three_lat_2per_k1.append(plane_hops_2per_k1[i][0][2])\n three_lon_2per_k1.append(plane_hops_2per_k1[i][1][2])\n four_lat_2per_k1.append(plane_hops_2per_k1[i][0][3])\n four_lon_2per_k1.append(plane_hops_2per_k1[i][1][3])\n final_lat_2per_k1.append(plane_hops_2per_k1[i][0][4])\n final_lon_2per_k1.append(plane_hops_2per_k1[i][1][4])\n \n route1_lat_2per_k1.append(plane_hops_2per_k1[i][0][5])\n route1_lon_2per_k1.append(plane_hops_2per_k1[i][1][5])\n route2_lat_2per_k1.append(plane_hops_2per_k1[i][0][6])\n route2_lon_2per_k1.append(plane_hops_2per_k1[i][1][6])\n route3_lat_2per_k1.append(plane_hops_2per_k1[i][0][7])\n route3_lon_2per_k1.append(plane_hops_2per_k1[i][1][7])\n route4_lat_2per_k1.append(plane_hops_2per_k1[i][0][8])\n route4_lon_2per_k1.append(plane_hops_2per_k1[i][1][8])", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'plane_hops_2per_k1' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 23\u001b[0m \u001b[0mroute4_lon_2per_k1\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 24\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 25\u001b[1;33m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mxrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mplane_hops_2per_k1\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 26\u001b[0m \u001b[0mfirst_lat_2per_k1\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mplane_hops_2per_k1\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 27\u001b[0m \u001b[0mfirst_lon_2per_k1\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mplane_hops_2per_k1\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'plane_hops_2per_k1' is not defined" ] } ], "prompt_number": 29 }, { "cell_type": "code", "collapsed": false, "input": "# 2per_k2 run\n\nfirst_lat_2per_k2 = []\ntwo_lat_2per_k2 = []\nthree_lat_2per_k2 = []\nfour_lat_2per_k2 = []\nfinal_lat_2per_k2 = []\n\nfirst_lon_2per_k2 = []\ntwo_lon_2per_k2 = []\nthree_lon_2per_k2 = []\nfour_lon_2per_k2 = []\nfinal_lon_2per_k2 = []\n\nroute1_lat_2per_k2 = []\nroute2_lat_2per_k2 = []\nroute3_lat_2per_k2 = []\nroute4_lat_2per_k2 = []\n\nroute1_lon_2per_k2 = []\nroute2_lon_2per_k2 = []\nroute3_lon_2per_k2 = []\nroute4_lon_2per_k2 = []\n\nfor i in xrange(len(plane_hops_2per_k2)):\n first_lat_2per_k2.append(plane_hops_2per_k2[i][0][0])\n first_lon_2per_k2.append(plane_hops_2per_k2[i][1][0])\n two_lat_2per_k2.append(plane_hops_2per_k2[i][0][1])\n two_lon_2per_k2.append(plane_hops_2per_k2[i][1][1])\n three_lat_2per_k2.append(plane_hops_2per_k2[i][0][2])\n three_lon_2per_k2.append(plane_hops_2per_k2[i][1][2])\n four_lat_2per_k2.append(plane_hops_2per_k2[i][0][3])\n four_lon_2per_k2.append(plane_hops_2per_k2[i][1][3])\n final_lat_2per_k2.append(plane_hops_2per_k2[i][0][4])\n final_lon_2per_k2.append(plane_hops_2per_k2[i][1][4])\n \n route1_lat_2per_k2.append(plane_hops_2per_k2[i][0][5])\n route1_lon_2per_k2.append(plane_hops_2per_k2[i][1][5])\n route2_lat_2per_k2.append(plane_hops_2per_k2[i][0][6])\n route2_lon_2per_k2.append(plane_hops_2per_k2[i][1][6])\n route3_lat_2per_k2.append(plane_hops_2per_k2[i][0][7])\n route3_lon_2per_k2.append(plane_hops_2per_k2[i][1][7])\n route4_lat_2per_k2.append(plane_hops_2per_k2[i][0][8])\n route4_lon_2per_k2.append(plane_hops_2per_k2[i][1][8])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "# 2per_k3 run\n\nfirst_lat_2per_k3 = []\ntwo_lat_2per_k3 = []\nthree_lat_2per_k3 = []\nfour_lat_2per_k3 = []\nfinal_lat_2per_k3 = []\n\nfirst_lon_2per_k3 = []\ntwo_lon_2per_k3 = []\nthree_lon_2per_k3 = []\nfour_lon_2per_k3 = []\nfinal_lon_2per_k3 = []\n\nroute1_lat_2per_k3 = []\nroute2_lat_2per_k3 = []\nroute3_lat_2per_k3 = []\nroute4_lat_2per_k3 = []\n\nroute1_lon_2per_k3 = []\nroute2_lon_2per_k3 = []\nroute3_lon_2per_k3 = []\nroute4_lon_2per_k3 = []\n\nfor i in xrange(len(plane_hops_2per_k3)):\n first_lat_2per_k3.append(plane_hops_2per_k3[i][0][0])\n first_lon_2per_k3.append(plane_hops_2per_k3[i][1][0])\n two_lat_2per_k3.append(plane_hops_2per_k3[i][0][1])\n two_lon_2per_k3.append(plane_hops_2per_k3[i][1][1])\n three_lat_2per_k3.append(plane_hops_2per_k3[i][0][2])\n three_lon_2per_k3.append(plane_hops_2per_k3[i][1][2])\n four_lat_2per_k3.append(plane_hops_2per_k3[i][0][3])\n four_lon_2per_k3.append(plane_hops_2per_k3[i][1][3])\n final_lat_2per_k3.append(plane_hops_2per_k3[i][0][4])\n final_lon_2per_k3.append(plane_hops_2per_k3[i][1][4])\n \n route1_lat_2per_k3.append(plane_hops_2per_k3[i][0][5])\n route1_lon_2per_k3.append(plane_hops_2per_k3[i][1][5])\n route2_lat_2per_k3.append(plane_hops_2per_k3[i][0][6])\n route2_lon_2per_k3.append(plane_hops_2per_k3[i][1][6])\n route3_lat_2per_k3.append(plane_hops_2per_k3[i][0][7])\n route3_lon_2per_k3.append(plane_hops_2per_k3[i][1][7])\n route4_lat_2per_k3.append(plane_hops_2per_k3[i][0][8])\n route4_lon_2per_k3.append(plane_hops_2per_k3[i][1][8])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Now we plot. To conserve space I am plotting all of the points at once. I will not make a separate plot just showing up to the 5th ping:" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "5per_k1 plot - Von Mises Heading, k=0, 5% ping error" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_5per,circle_lat_err1_5per)\nx7,y7 = fig(circle_lon_err2_5per,circle_lat_err2_5per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon_5per_k1,first_lat_5per_k1)\nx10,y10 = fig(two_lon_5per_k1,two_lat_5per_k1)\nx11,y11 = fig(three_lon_5per_k1,three_lat_5per_k1)\nx12,y12 = fig(four_lon_5per_k1,four_lat_5per_k1)\nx13,y13 = fig(final_lon_5per_k1,final_lat_5per_k1)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon_5per_k1,route1_lat_5per_k1)\nx15,y15 = fig(route2_lon_5per_k1,route2_lat_5per_k1)\nx16,y16 = fig(route3_lon_5per_k1,route3_lat_5per_k1)\nx17,y17 = fig(route4_lon_5per_k1,route4_lat_5per_k1)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "5per_k2 plot - Von Mises Heading, k=1, 5% ping error" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_5per,circle_lat_err1_5per)\nx7,y7 = fig(circle_lon_err2_5per,circle_lat_err2_5per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon_5per_k2,first_lat_5per_k2)\nx10,y10 = fig(two_lon_5per_k2,two_lat_5per_k2)\nx11,y11 = fig(three_lon_5per_k2,three_lat_5per_k2)\nx12,y12 = fig(four_lon_5per_k2,four_lat_5per_k2)\nx13,y13 = fig(final_lon_5per_k2,final_lat_5per_k2)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon_5per_k2,route1_lat_5per_k2)\nx15,y15 = fig(route2_lon_5per_k2,route2_lat_5per_k2)\nx16,y16 = fig(route3_lon_5per_k2,route3_lat_5per_k2)\nx17,y17 = fig(route4_lon_5per_k2,route4_lat_5per_k2)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "5per_k3 plot - Von Mises Heading, k=10, 5% ping error" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_5per,circle_lat_err1_5per)\nx7,y7 = fig(circle_lon_err2_5per,circle_lat_err2_5per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon_5per_k3,first_lat_5per_k3)\nx10,y10 = fig(two_lon_5per_k3,two_lat_5per_k3)\nx11,y11 = fig(three_lon_5per_k3,three_lat_5per_k3)\nx12,y12 = fig(four_lon_5per_k3,four_lat_5per_k3)\nx13,y13 = fig(final_lon_5per_k3,final_lat_5per_k3)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon_5per_k3,route1_lat_5per_k3)\nx15,y15 = fig(route2_lon_5per_k3,route2_lat_5per_k3)\nx16,y16 = fig(route3_lon_5per_k3,route3_lat_5per_k3)\nx17,y17 = fig(route4_lon_5per_k3,route4_lat_5per_k3)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "2per_k1 plot - Von Mises Heading, k=0, 2.5% ping error" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 2.5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_2per,circle_lat_err1_2per)\nx7,y7 = fig(circle_lon_err2_2per,circle_lat_err2_2per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon_5per_k1,first_lat_5per_k1)\nx10,y10 = fig(two_lon_5per_k1,two_lat_5per_k1)\nx11,y11 = fig(three_lon_5per_k1,three_lat_5per_k1)\nx12,y12 = fig(four_lon_5per_k1,four_lat_5per_k1)\nx13,y13 = fig(final_lon_5per_k1,final_lat_5per_k1)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon_5per_k1,route1_lat_5per_k1)\nx15,y15 = fig(route2_lon_5per_k1,route2_lat_5per_k1)\nx16,y16 = fig(route3_lon_5per_k1,route3_lat_5per_k1)\nx17,y17 = fig(route4_lon_5per_k1,route4_lat_5per_k1)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "2per_k2 plot - Von Mises Heading, k=1, 2.5% ping error" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 2.5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_2per,circle_lat_err1_2per)\nx7,y7 = fig(circle_lon_err2_2per,circle_lat_err2_2per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon_5per_k2,first_lat_5per_k2)\nx10,y10 = fig(two_lon_5per_k2,two_lat_5per_k2)\nx11,y11 = fig(three_lon_5per_k2,three_lat_5per_k2)\nx12,y12 = fig(four_lon_5per_k2,four_lat_5per_k2)\nx13,y13 = fig(final_lon_5per_k2,final_lat_5per_k2)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon_5per_k2,route1_lat_5per_k2)\nx15,y15 = fig(route2_lon_5per_k2,route2_lat_5per_k2)\nx16,y16 = fig(route3_lon_5per_k2,route3_lat_5per_k2)\nx17,y17 = fig(route4_lon_5per_k2,route4_lat_5per_k2)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "2per_k3 plot - Von Mises Heading, k=10, 2.5% ping error" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 2.5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_2per,circle_lat_err1_2per)\nx7,y7 = fig(circle_lon_err2_2per,circle_lat_err2_2per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon_5per_k3,first_lat_5per_k3)\nx10,y10 = fig(two_lon_5per_k3,two_lat_5per_k3)\nx11,y11 = fig(three_lon_5per_k3,three_lat_5per_k3)\nx12,y12 = fig(four_lon_5per_k3,four_lat_5per_k3)\nx13,y13 = fig(final_lon_5per_k3,final_lat_5per_k3)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon_5per_k3,route1_lat_5per_k3)\nx15,y15 = fig(route2_lon_5per_k3,route2_lat_5per_k3)\nx16,y16 = fig(route3_lon_5per_k3,route3_lat_5per_k3)\nx17,y17 = fig(route4_lon_5per_k3,route4_lat_5per_k3)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Okay, let's take a minute to see what these plots mean!" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "......... ........... ........ ......... ........" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "If you look at the k=0 , it follows that a uniform distribution will be a true random walk; so the plane will tend to move any which way, and influenced by the ping. Unfortunately, this does not tell us much about where along the arc the plane is most likely to be located. On reddit (MH370 subbreddit), me not using a uniform distribution was a criticism which got lots of upvotes; well, I've implemented it now, and the results are not what we're looking for! They're not helpful because they do not constrain the position of MH370; *and* the assumption inherent in a uniform distribution is not an accurate representation of how an airplane moves when it's trying to get somewhere." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "As you increase k, the distribution deviating from the heading becomes narrower. And as that becomes apparent, we do in fact see that the plane tends to the south instead of the north. And from looking at a uniform distribution, this is very likely due to not only the geometry of the arc, but also the plane's last known heading -- 255 degrees, slight south and to the west (due west is 270), as opposed to slightly to the north." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Finally, in theory 2.5% should have stronger results than 5%, in terms of restricting the search area location at the end...but in practice both are relatively small errors; so we're looking at the same patch of ocean west of Australia." }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Wrapped Cauchy" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Similar to the Von Mises runs, I'll use the test k values for Wrapped Cauchy at 2.5 and 5% error for the ping probability distribution." }, { "cell_type": "code", "collapsed": false, "input": "percenterror1, percenterror2 = 0.05, 0.025\n\nk1, k2, k3 = 0, 0.5, 0.99 #Wrapped Cauchy constants -- uniform, bell, point-like", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "#5 percent error w/ different ks\nplane_hops_5per_k1 = []\nplane_hops_5per_k2 = []\nplane_hops_5per_k3 = []\n\n#2.5 percent error w/ different ks\nplane_hops_2per_k1 = []\nplane_hops_2per_k2 = []\nplane_hops_2per_k3 = []\n\nfor i in xrange(N):\n #5% error runs\n plane_hops_5per_k1.append(five_hop_model_wrapped_cauchy(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k1,percenterror1))\n plane_hops_5per_k2.append(five_hop_model_wrapped_cauchy(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k2,percenterror1))\n plane_hops_5per_k3.append(five_hop_model_wrapped_cauchy(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k3,percenterror1))\n #2.5% error runs\n plane_hops_2per_k1.append(five_hop_model_wrapped_cauchy(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k1,percenterror2))\n plane_hops_2per_k2.append(five_hop_model_wrapped_cauchy(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k2,percenterror2))\n plane_hops_2per_k3.append(five_hop_model_wrapped_cauchy(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k3,percenterror2))", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "As they would say in Ye Olde English, \"the loops runneth over.\" Once that's done, proceed with the below:" }, { "cell_type": "code", "collapsed": false, "input": "# 5per_k1 run\n\nfirst_lat_5per_k1 = []\ntwo_lat_5per_k1 = []\nthree_lat_5per_k1 = []\nfour_lat_5per_k1 = []\nfinal_lat_5per_k1 = []\n\nfirst_lon_5per_k1 = []\ntwo_lon_5per_k1 = []\nthree_lon_5per_k1 = []\nfour_lon_5per_k1 = []\nfinal_lon_5per_k1 = []\n\nroute1_lat_5per_k1 = []\nroute2_lat_5per_k1 = []\nroute3_lat_5per_k1 = []\nroute4_lat_5per_k1 = []\n\nroute1_lon_5per_k1 = []\nroute2_lon_5per_k1 = []\nroute3_lon_5per_k1 = []\nroute4_lon_5per_k1 = []\n\nfor i in xrange(len(plane_hops_5per_k1)):\n first_lat_5per_k1.append(plane_hops_5per_k1[i][0][0])\n first_lon_5per_k1.append(plane_hops_5per_k1[i][1][0])\n two_lat_5per_k1.append(plane_hops_5per_k1[i][0][1])\n two_lon_5per_k1.append(plane_hops_5per_k1[i][1][1])\n three_lat_5per_k1.append(plane_hops_5per_k1[i][0][2])\n three_lon_5per_k1.append(plane_hops_5per_k1[i][1][2])\n four_lat_5per_k1.append(plane_hops_5per_k1[i][0][3])\n four_lon_5per_k1.append(plane_hops_5per_k1[i][1][3])\n final_lat_5per_k1.append(plane_hops_5per_k1[i][0][4])\n final_lon_5per_k1.append(plane_hops_5per_k1[i][1][4])\n \n route1_lat_5per_k1.append(plane_hops_5per_k1[i][0][5])\n route1_lon_5per_k1.append(plane_hops_5per_k1[i][1][5])\n route2_lat_5per_k1.append(plane_hops_5per_k1[i][0][6])\n route2_lon_5per_k1.append(plane_hops_5per_k1[i][1][6])\n route3_lat_5per_k1.append(plane_hops_5per_k1[i][0][7])\n route3_lon_5per_k1.append(plane_hops_5per_k1[i][1][7])\n route4_lat_5per_k1.append(plane_hops_5per_k1[i][0][8])\n route4_lon_5per_k1.append(plane_hops_5per_k1[i][1][8])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "# 5per_k2 run\n\nfirst_lat_5per_k2 = []\ntwo_lat_5per_k2 = []\nthree_lat_5per_k2 = []\nfour_lat_5per_k2 = []\nfinal_lat_5per_k2 = []\n\nfirst_lon_5per_k2 = []\ntwo_lon_5per_k2 = []\nthree_lon_5per_k2 = []\nfour_lon_5per_k2 = []\nfinal_lon_5per_k2 = []\n\nroute1_lat_5per_k2 = []\nroute2_lat_5per_k2 = []\nroute3_lat_5per_k2 = []\nroute4_lat_5per_k2 = []\n\nroute1_lon_5per_k2 = []\nroute2_lon_5per_k2 = []\nroute3_lon_5per_k2 = []\nroute4_lon_5per_k2 = []\n\nfor i in xrange(len(plane_hops_5per_k2)):\n first_lat_5per_k2.append(plane_hops_5per_k2[i][0][0])\n first_lon_5per_k2.append(plane_hops_5per_k2[i][1][0])\n two_lat_5per_k2.append(plane_hops_5per_k2[i][0][1])\n two_lon_5per_k2.append(plane_hops_5per_k2[i][1][1])\n three_lat_5per_k2.append(plane_hops_5per_k2[i][0][2])\n three_lon_5per_k2.append(plane_hops_5per_k2[i][1][2])\n four_lat_5per_k2.append(plane_hops_5per_k2[i][0][3])\n four_lon_5per_k2.append(plane_hops_5per_k2[i][1][3])\n final_lat_5per_k2.append(plane_hops_5per_k2[i][0][4])\n final_lon_5per_k2.append(plane_hops_5per_k2[i][1][4])\n \n route1_lat_5per_k2.append(plane_hops_5per_k2[i][0][5])\n route1_lon_5per_k2.append(plane_hops_5per_k2[i][1][5])\n route2_lat_5per_k2.append(plane_hops_5per_k2[i][0][6])\n route2_lon_5per_k2.append(plane_hops_5per_k2[i][1][6])\n route3_lat_5per_k2.append(plane_hops_5per_k2[i][0][7])\n route3_lon_5per_k2.append(plane_hops_5per_k2[i][1][7])\n route4_lat_5per_k2.append(plane_hops_5per_k2[i][0][8])\n route4_lon_5per_k2.append(plane_hops_5per_k2[i][1][8])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "# 5per_k3 run\n\nfirst_lat_5per_k3 = []\ntwo_lat_5per_k3 = []\nthree_lat_5per_k3 = []\nfour_lat_5per_k3 = []\nfinal_lat_5per_k3 = []\n\nfirst_lon_5per_k3 = []\ntwo_lon_5per_k3 = []\nthree_lon_5per_k3 = []\nfour_lon_5per_k3 = []\nfinal_lon_5per_k3 = []\n\nroute1_lat_5per_k3 = []\nroute2_lat_5per_k3 = []\nroute3_lat_5per_k3 = []\nroute4_lat_5per_k3 = []\n\nroute1_lon_5per_k3 = []\nroute2_lon_5per_k3 = []\nroute3_lon_5per_k3 = []\nroute4_lon_5per_k3 = []\n\nfor i in xrange(len(plane_hops_5per_k3)):\n first_lat_5per_k3.append(plane_hops_5per_k3[i][0][0])\n first_lon_5per_k3.append(plane_hops_5per_k3[i][1][0])\n two_lat_5per_k3.append(plane_hops_5per_k3[i][0][1])\n two_lon_5per_k3.append(plane_hops_5per_k3[i][1][1])\n three_lat_5per_k3.append(plane_hops_5per_k3[i][0][2])\n three_lon_5per_k3.append(plane_hops_5per_k3[i][1][2])\n four_lat_5per_k3.append(plane_hops_5per_k3[i][0][3])\n four_lon_5per_k3.append(plane_hops_5per_k3[i][1][3])\n final_lat_5per_k3.append(plane_hops_5per_k3[i][0][4])\n final_lon_5per_k3.append(plane_hops_5per_k3[i][1][4])\n \n route1_lat_5per_k3.append(plane_hops_5per_k3[i][0][5])\n route1_lon_5per_k3.append(plane_hops_5per_k3[i][1][5])\n route2_lat_5per_k3.append(plane_hops_5per_k3[i][0][6])\n route2_lon_5per_k3.append(plane_hops_5per_k3[i][1][6])\n route3_lat_5per_k3.append(plane_hops_5per_k3[i][0][7])\n route3_lon_5per_k3.append(plane_hops_5per_k3[i][1][7])\n route4_lat_5per_k3.append(plane_hops_5per_k3[i][0][8])\n route4_lon_5per_k3.append(plane_hops_5per_k3[i][1][8])", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'plane_hops_5per_k3' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 23\u001b[0m \u001b[0mroute4_lon_5per_k3\u001b[0m \u001b[1;33m=\u001b[0m \u001b[1;33m[\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 24\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m---> 25\u001b[1;33m \u001b[1;32mfor\u001b[0m \u001b[0mi\u001b[0m \u001b[1;32min\u001b[0m \u001b[0mxrange\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mlen\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mplane_hops_5per_k3\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m:\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 26\u001b[0m \u001b[0mfirst_lat_5per_k3\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mplane_hops_5per_k3\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 27\u001b[0m \u001b[0mfirst_lon_5per_k3\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mappend\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mplane_hops_5per_k3\u001b[0m\u001b[1;33m[\u001b[0m\u001b[0mi\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m1\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'plane_hops_5per_k3' is not defined" ] } ], "prompt_number": 30 }, { "cell_type": "code", "collapsed": false, "input": "# 2per_k1 run\n\nfirst_lat_2per_k1 = []\ntwo_lat_2per_k1 = []\nthree_lat_2per_k1 = []\nfour_lat_2per_k1 = []\nfinal_lat_2per_k1 = []\n\nfirst_lon_2per_k1 = []\ntwo_lon_2per_k1 = []\nthree_lon_2per_k1 = []\nfour_lon_2per_k1 = []\nfinal_lon_2per_k1 = []\n\nroute1_lat_2per_k1 = []\nroute2_lat_2per_k1 = []\nroute3_lat_2per_k1 = []\nroute4_lat_2per_k1 = []\n\nroute1_lon_2per_k1 = []\nroute2_lon_2per_k1 = []\nroute3_lon_2per_k1 = []\nroute4_lon_2per_k1 = []\n\nfor i in xrange(len(plane_hops_2per_k1)):\n first_lat_2per_k1.append(plane_hops_2per_k1[i][0][0])\n first_lon_2per_k1.append(plane_hops_2per_k1[i][1][0])\n two_lat_2per_k1.append(plane_hops_2per_k1[i][0][1])\n two_lon_2per_k1.append(plane_hops_2per_k1[i][1][1])\n three_lat_2per_k1.append(plane_hops_2per_k1[i][0][2])\n three_lon_2per_k1.append(plane_hops_2per_k1[i][1][2])\n four_lat_2per_k1.append(plane_hops_2per_k1[i][0][3])\n four_lon_2per_k1.append(plane_hops_2per_k1[i][1][3])\n final_lat_2per_k1.append(plane_hops_2per_k1[i][0][4])\n final_lon_2per_k1.append(plane_hops_2per_k1[i][1][4])\n \n route1_lat_2per_k1.append(plane_hops_2per_k1[i][0][5])\n route1_lon_2per_k1.append(plane_hops_2per_k1[i][1][5])\n route2_lat_2per_k1.append(plane_hops_2per_k1[i][0][6])\n route2_lon_2per_k1.append(plane_hops_2per_k1[i][1][6])\n route3_lat_2per_k1.append(plane_hops_2per_k1[i][0][7])\n route3_lon_2per_k1.append(plane_hops_2per_k1[i][1][7])\n route4_lat_2per_k1.append(plane_hops_2per_k1[i][0][8])\n route4_lon_2per_k1.append(plane_hops_2per_k1[i][1][8])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "# 2per_k2 run\n\nfirst_lat_2per_k2 = []\ntwo_lat_2per_k2 = []\nthree_lat_2per_k2 = []\nfour_lat_2per_k2 = []\nfinal_lat_2per_k2 = []\n\nfirst_lon_2per_k2 = []\ntwo_lon_2per_k2 = []\nthree_lon_2per_k2 = []\nfour_lon_2per_k2 = []\nfinal_lon_2per_k2 = []\n\nroute1_lat_2per_k2 = []\nroute2_lat_2per_k2 = []\nroute3_lat_2per_k2 = []\nroute4_lat_2per_k2 = []\n\nroute1_lon_2per_k2 = []\nroute2_lon_2per_k2 = []\nroute3_lon_2per_k2 = []\nroute4_lon_2per_k2 = []\n\nfor i in xrange(len(plane_hops_2per_k2)):\n first_lat_2per_k2.append(plane_hops_2per_k2[i][0][0])\n first_lon_2per_k2.append(plane_hops_2per_k2[i][1][0])\n two_lat_2per_k2.append(plane_hops_2per_k2[i][0][1])\n two_lon_2per_k2.append(plane_hops_2per_k2[i][1][1])\n three_lat_2per_k2.append(plane_hops_2per_k2[i][0][2])\n three_lon_2per_k2.append(plane_hops_2per_k2[i][1][2])\n four_lat_2per_k2.append(plane_hops_2per_k2[i][0][3])\n four_lon_2per_k2.append(plane_hops_2per_k2[i][1][3])\n final_lat_2per_k2.append(plane_hops_2per_k2[i][0][4])\n final_lon_2per_k2.append(plane_hops_2per_k2[i][1][4])\n \n route1_lat_2per_k2.append(plane_hops_2per_k2[i][0][5])\n route1_lon_2per_k2.append(plane_hops_2per_k2[i][1][5])\n route2_lat_2per_k2.append(plane_hops_2per_k2[i][0][6])\n route2_lon_2per_k2.append(plane_hops_2per_k2[i][1][6])\n route3_lat_2per_k2.append(plane_hops_2per_k2[i][0][7])\n route3_lon_2per_k2.append(plane_hops_2per_k2[i][1][7])\n route4_lat_2per_k2.append(plane_hops_2per_k2[i][0][8])\n route4_lon_2per_k2.append(plane_hops_2per_k2[i][1][8])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "# 2per_k3 run\n\nfirst_lat_2per_k3 = []\ntwo_lat_2per_k3 = []\nthree_lat_2per_k3 = []\nfour_lat_2per_k3 = []\nfinal_lat_2per_k3 = []\n\nfirst_lon_2per_k3 = []\ntwo_lon_2per_k3 = []\nthree_lon_2per_k3 = []\nfour_lon_2per_k3 = []\nfinal_lon_2per_k3 = []\n\nroute1_lat_2per_k3 = []\nroute2_lat_2per_k3 = []\nroute3_lat_2per_k3 = []\nroute4_lat_2per_k3 = []\n\nroute1_lon_2per_k3 = []\nroute2_lon_2per_k3 = []\nroute3_lon_2per_k3 = []\nroute4_lon_2per_k3 = []\n\nfor i in xrange(len(plane_hops_2per_k3)):\n first_lat_2per_k3.append(plane_hops_2per_k3[i][0][0])\n first_lon_2per_k3.append(plane_hops_2per_k3[i][1][0])\n two_lat_2per_k3.append(plane_hops_2per_k3[i][0][1])\n two_lon_2per_k3.append(plane_hops_2per_k3[i][1][1])\n three_lat_2per_k3.append(plane_hops_2per_k3[i][0][2])\n three_lon_2per_k3.append(plane_hops_2per_k3[i][1][2])\n four_lat_2per_k3.append(plane_hops_2per_k3[i][0][3])\n four_lon_2per_k3.append(plane_hops_2per_k3[i][1][3])\n final_lat_2per_k3.append(plane_hops_2per_k3[i][0][4])\n final_lon_2per_k3.append(plane_hops_2per_k3[i][1][4])\n \n route1_lat_2per_k3.append(plane_hops_2per_k3[i][0][5])\n route1_lon_2per_k3.append(plane_hops_2per_k3[i][1][5])\n route2_lat_2per_k3.append(plane_hops_2per_k3[i][0][6])\n route2_lon_2per_k3.append(plane_hops_2per_k3[i][1][6])\n route3_lat_2per_k3.append(plane_hops_2per_k3[i][0][7])\n route3_lon_2per_k3.append(plane_hops_2per_k3[i][1][7])\n route4_lat_2per_k3.append(plane_hops_2per_k3[i][0][8])\n route4_lon_2per_k3.append(plane_hops_2per_k3[i][1][8])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Now we plot once again:" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "5per_k1 plot - Wrapped Cauchy Heading, k=0, 5% ping error" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_5per,circle_lat_err1_5per)\nx7,y7 = fig(circle_lon_err2_5per,circle_lat_err2_5per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon_5per_k1,first_lat_5per_k1)\nx10,y10 = fig(two_lon_5per_k1,two_lat_5per_k1)\nx11,y11 = fig(three_lon_5per_k1,three_lat_5per_k1)\nx12,y12 = fig(four_lon_5per_k1,four_lat_5per_k1)\nx13,y13 = fig(final_lon_5per_k1,final_lat_5per_k1)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon_5per_k1,route1_lat_5per_k1)\nx15,y15 = fig(route2_lon_5per_k1,route2_lat_5per_k1)\nx16,y16 = fig(route3_lon_5per_k1,route3_lat_5per_k1)\nx17,y17 = fig(route4_lon_5per_k1,route4_lat_5per_k1)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "5per_k2 plot - Wrapped Cauchy Heading, k=0.5, 5% ping error" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_5per,circle_lat_err1_5per)\nx7,y7 = fig(circle_lon_err2_5per,circle_lat_err2_5per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon_5per_k2,first_lat_5per_k2)\nx10,y10 = fig(two_lon_5per_k2,two_lat_5per_k2)\nx11,y11 = fig(three_lon_5per_k2,three_lat_5per_k2)\nx12,y12 = fig(four_lon_5per_k2,four_lat_5per_k2)\nx13,y13 = fig(final_lon_5per_k2,final_lat_5per_k2)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon_5per_k2,route1_lat_5per_k2)\nx15,y15 = fig(route2_lon_5per_k2,route2_lat_5per_k2)\nx16,y16 = fig(route3_lon_5per_k2,route3_lat_5per_k2)\nx17,y17 = fig(route4_lon_5per_k2,route4_lat_5per_k2)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "5per_k3 plot - Wrapped Cauchy Heading, k=0.99, 5% ping error" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_5per,circle_lat_err1_5per)\nx7,y7 = fig(circle_lon_err2_5per,circle_lat_err2_5per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon_5per_k3,first_lat_5per_k3)\nx10,y10 = fig(two_lon_5per_k3,two_lat_5per_k3)\nx11,y11 = fig(three_lon_5per_k3,three_lat_5per_k3)\nx12,y12 = fig(four_lon_5per_k3,four_lat_5per_k3)\nx13,y13 = fig(final_lon_5per_k3,final_lat_5per_k3)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon_5per_k3,route1_lat_5per_k3)\nx15,y15 = fig(route2_lon_5per_k3,route2_lat_5per_k3)\nx16,y16 = fig(route3_lon_5per_k3,route3_lat_5per_k3)\nx17,y17 = fig(route4_lon_5per_k3,route4_lat_5per_k3)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "2per_k1 plot - Wrapped Cauchy Heading, k=0, 2.5% ping error" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n\n#Add circle coords -- 2.5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_2per,circle_lat_err1_2per)\nx7,y7 = fig(circle_lon_err2_2per,circle_lat_err2_2per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon_5per_k1,first_lat_5per_k1)\nx10,y10 = fig(two_lon_5per_k1,two_lat_5per_k1)\nx11,y11 = fig(three_lon_5per_k1,three_lat_5per_k1)\nx12,y12 = fig(four_lon_5per_k1,four_lat_5per_k1)\nx13,y13 = fig(final_lon_5per_k1,final_lat_5per_k1)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon_5per_k1,route1_lat_5per_k1)\nx15,y15 = fig(route2_lon_5per_k1,route2_lat_5per_k1)\nx16,y16 = fig(route3_lon_5per_k1,route3_lat_5per_k1)\nx17,y17 = fig(route4_lon_5per_k1,route4_lat_5per_k1)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "2per_k2 plot - Wrapped Cauchy Heading, k=0.5, 2.5% ping error" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 2.5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_2per,circle_lat_err1_2per)\nx7,y7 = fig(circle_lon_err2_2per,circle_lat_err2_2per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon_5per_k2,first_lat_5per_k2)\nx10,y10 = fig(two_lon_5per_k2,two_lat_5per_k2)\nx11,y11 = fig(three_lon_5per_k2,three_lat_5per_k2)\nx12,y12 = fig(four_lon_5per_k2,four_lat_5per_k2)\nx13,y13 = fig(final_lon_5per_k2,final_lat_5per_k2)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon_5per_k2,route1_lat_5per_k2)\nx15,y15 = fig(route2_lon_5per_k2,route2_lat_5per_k2)\nx16,y16 = fig(route3_lon_5per_k2,route3_lat_5per_k2)\nx17,y17 = fig(route4_lon_5per_k2,route4_lat_5per_k2)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "2per_k3 plot - Wrapped Cauchy Heading, k=0.99, 2.5% ping error" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- 2.5% error\nx5,y5 = fig(circle_lon,circle_lat)\nx6,y6 = fig(circle_lon_err1_2per,circle_lat_err1_2per)\nx7,y7 = fig(circle_lon_err2_2per,circle_lat_err2_2per)\n\n#Add points after each hr\nx9,y9 = fig(first_lon_5per_k3,first_lat_5per_k3)\nx10,y10 = fig(two_lon_5per_k3,two_lat_5per_k3)\nx11,y11 = fig(three_lon_5per_k3,three_lat_5per_k3)\nx12,y12 = fig(four_lon_5per_k3,four_lat_5per_k3)\nx13,y13 = fig(final_lon_5per_k3,final_lat_5per_k3)\n\n#Add ultimate locations of MH370\nx14,y14 = fig(route1_lon_5per_k3,route1_lat_5per_k3)\nx15,y15 = fig(route2_lon_5per_k3,route2_lat_5per_k3)\nx16,y16 = fig(route3_lon_5per_k3,route3_lat_5per_k3)\nx17,y17 = fig(route4_lon_5per_k3,route4_lat_5per_k3)\n\n#Draw circle showing extent of Inmarsat sat radar detection\nfig.plot(x5,y5,'r-',markersize=5,label='5th Ping')\nfig.plot(x6,y6,'r--',markersize=5,label='with 5% error')\nfig.plot(x7,y7,'r--',markersize=5)\n\n#Plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Add monte carlo points\nfig.plot(x9,y9,'yo',markersize=5,label='after 1 hr')\nfig.plot(x10,y10,'co',markersize=5,label='after 2 hrs')\nfig.plot(x11,y11,'mo',markersize=5,label= 'after 3 hrs')\nfig.plot(x12,y12,'wo',markersize=5,label='after 4 hrs')\nfig.plot(x13,y13,'ro',markersize=7,label='after 5 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x14,y14,'bo',markersize=5,label='in final hr')\nfig.plot(x15,y15,'bo',markersize=5)\nfig.plot(x16,y16,'bo',markersize=5)\nfig.plot(x17,y17,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('MH370 Position Progression Over Time', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Intriguingly, even with an extremely narrow distribution the Wrapped Cauchy is of little use in determining where plane is. We'll try it again with all of the pings. With this heading distribution we can now say, \"it's a wrap!\"" }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": "Conclusions and Comparisons to First Version of the Monte Carlo Model:" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "I cleaned up the code, fixed a few (minor to the results) bugs, used more realistic Inmarsat ping error values based on new information (reducing the error), and used two different distributions for picking the heading besides normal. Remember, the heading is my main state, so changing how the heading is chosen *can* affect the model outcome, as we saw from the plots." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "The most realistic intermediary k value cases for Von Mises show the same results as the normal distribution option -- MH370 ends up off the coast of Australia in most cases. The Wrapped Cauchy, only just using the 5th ping arc, does not make meaningful inferences about where the plane is." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "So, what we see here is accurate for the final location of where MH370 is most likely to be located. *But*, one of the advantages of having a 10% standard deviation error (or even 20%) is that with our normal probability distribution established from a grid with that amount of ping arc error, we encompassed many pings. So, the plane didn't just travel along the arc. The smaller the error, the more the plane will travel along the arc. Now, we know it was on the arc at the 5th ping, so this is not the end of the world. But even better would be to try to recreate the overall trajectory of the aircraft at all points in time. In that way, if we looked at varying the speed, we could just look further to the north along the southern corridor instead of varying the speed (in other words, we'd do the calculation by hand, and say, at a high speed, the plane would just go down where it was at the 5th ping -- and would run out of fuel almost immediately thereafter.)" }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": "Next Step - Adding the Other Pings" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "We've now incorporated the reasonable amount of error Inmarsat would expect from their ping estimate -- just 2.5 or 5% -- but we haven't incorporated some idea of where the other pings have been located. So, let's do that." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Unfortunately we don't have the actual numbers. *But*, from scrutinizing infographics, some of which *may* have had that information, in addition to graphics produced by people \"in the know\" with that info (such as the NTSB, National Transporatation Safety Board), we can infer a pretty good estimate of where the other pings are. These estimates ultimately can't vary by much, as \"what you see is what you get\" on an accurate map, which most major media organizations have with multiple pings. Let's do that and see how it affects the trajectory of MH370." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "These were actually determined in a separate Mathematica 9 notebook (like the spherical trig derivations, as well as the double-checking of the Python implementation of this model. Same results and output, by the way.) However, I'll grab the radius values of the other pings and plot them, and them include links to infographic maps showing the ping locations, so you can see for yourself that these are close to what the actual ping values must be:" }, { "cell_type": "code", "collapsed": false, "input": "#add other ping distances, and then replot\n\nping_distances = np.array([4036.99, 4194.65, 4352.32, 4509.99, 4667.65, 4825.32])\nping_times = np.array([0.9333, 1, 1, 1, 1, 1]) #make 1st hop slightly smaller owing to time difference\nping_arcs = np.array([34.8485, 36.2649, 37.6812, 39.0976, 40.5139, 41.9303, 43.3466])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "WHAT?! You say. What about the fact that you've repeatedly said there were *5* pings afterward. Now there are 6?! Well, this is one of many contradictory pieces of information which has emerged both to the media at large, and to myself as I continue to search for the best sources of information. If you look at the times, apparently, 6 out of the 7 pings happened after the plane disappeared, not 5. A Wall Street Journal article which was picked up in numerous other newspapers and media outlets, such as Yahoo News and several in Malaysia (who you'd think be close to the matter with easier access to officials speaking off the record, for instance), said: \"Malaysia Airlines' missing jet transmitted its location repeatedly to satellites over the course of five hours after it disappeared from radar, people briefed on the matter said...\". This has never been corrected or further addressed, even though other corrections have been run for facts that *are* in dispute (such as whether the Rolls Royce engine communication system was responsible for the signal routing through Inmarsat, versus the \"the idling satellite communications system\" which now appears to be the case, for example.) (Of course, here's a 4 hour claim to further complicate the matter.)" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Here's an article, published right after the first version of my model finished, with a recap of what we know MH370's location over time -- essentially that the first ping was at 2:11 am -- which was before MH370's disappearance from radar -- and that the last was at 8:11 am." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Nevertheless, the last ping that was plotted originally *was* the last ping. It's just that the timing must have been off, somehow, given the current timeline:" }, { "cell_type": "raw", "metadata": {}, "source": "[2:11 am], 3:11 am, 4:11 am, 5:11 am, 6:11 am, 7:11 am, 8:11 am, [plus a \"partial handshake\" which isn't understood]" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "That's 6 after disappearance, and that's the final count that I'll deal with in my model; the previous iterations of the model used the best information known at the time. So I'll leave those alone as is -- because effectively what I am doing over the course of 5 hrs, instead of 6 hours, is using 5/6 of the cruising speed which is possible. The last ping's location, and the ping arc, remains the same. None of that changes. But in being in the air longer to achieve that arc, the plane can fly further south." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "An inconsistency this leaves us with, by the way, is that the search is now taken place further north, because the \"airplane was going faster and ran out of fuel earlier\" -- but that does not reconcile with amount of time it would be in the air for (6+ hrs instead of 5+ hrs.) So I still do not understand the reasoning behind that argument." }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": "Replotting the Ping on the Map" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "We'll use the ping distances from the array and Mathematica above, to confirm that they look sensible compared to the infographics out there. We could use a 'for' loop but there are only 6, so I'll do them one-by-one:" }, { "cell_type": "code", "collapsed": false, "input": "#make points for 6 circles -- opt not to use for loop\nping_circle_211am = make_circle(ping_arcs[0],360,64.5,0)\nping_circle_311am = make_circle(ping_arcs[1],360,64.5,0)\nping_circle_411am = make_circle(ping_arcs[2],360,64.5,0)\nping_circle_511am = make_circle(ping_arcs[3],360,64.5,0)\nping_circle_611am = make_circle(ping_arcs[4],360,64.5,0)\nping_circle_711am = make_circle(ping_arcs[5],360,64.5,0)\nping_circle_811am = make_circle(ping_arcs[6],360,64.5,0)\n\n#initialize lat & lon lists\ncircle_lon_211am = []\ncircle_lat_211am = []\ncircle_lat_311am = []\ncircle_lon_311am = []\ncircle_lat_411am = []\ncircle_lon_411am = []\ncircle_lat_511am = []\ncircle_lon_511am = []\ncircle_lat_611am = []\ncircle_lon_611am = []\ncircle_lat_711am = []\ncircle_lon_711am = []\ncircle_lat_811am = []\ncircle_lon_811am = []\n\nfor i in xrange(len(ping_circle_211am)): #they're all the same length so just do it once\n circle_lat_211am.append(ping_circle_211am[i][0])\n circle_lon_211am.append(ping_circle_211am[i][1])\n \n circle_lat_311am.append(ping_circle_311am[i][0])\n circle_lon_311am.append(ping_circle_311am[i][1])\n\n circle_lat_411am.append(ping_circle_411am[i][0])\n circle_lon_411am.append(ping_circle_411am[i][1])\n\n circle_lat_511am.append(ping_circle_511am[i][0])\n circle_lon_511am.append(ping_circle_511am[i][1])\n\n circle_lat_611am.append(ping_circle_611am[i][0])\n circle_lon_611am.append(ping_circle_611am[i][1])\n\n circle_lat_711am.append(ping_circle_711am[i][0])\n circle_lon_711am.append(ping_circle_711am[i][1])\n\n circle_lat_811am.append(ping_circle_811am[i][0])\n circle_lon_811am.append(ping_circle_811am[i][1])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw great circle to show path autopilot would have taken\nfig.drawgreatcircle(pulauperak[1],pulauperak[0],85,-40,linewidth=3,color='black',label='Great Circle Path')\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- these are for each ping. will not plot the 2.5 and 5% error\nx5,y5 = fig(circle_lon_211am,circle_lat_211am)\nx6,y6 = fig(circle_lon_311am,circle_lat_311am)\nx7,y7 = fig(circle_lon_411am,circle_lat_411am)\nx8,y8 = fig(circle_lon_511am,circle_lat_511am)\nx9,y9 = fig(circle_lon_611am,circle_lat_611am)\nx10,y10 = fig(circle_lon_711am,circle_lat_711am)\nx11,y11 = fig(circle_lon_811am,circle_lat_811am)\n\n#Draw circle showing extent of Inmarsat sat radar detection for each of the pings\nfig.plot(x5,y5,'r--',markersize=5,label='1st Ping Arc')\nfig.plot(x6,y6,'r-',markersize=5, label='Ping Arcs After Disappearance')\nfig.plot(x7,y7,'r-',markersize=5)\nfig.plot(x8,y8,'r-',markersize=5)\nfig.plot(x9,y9,'r-',markersize=5)\nfig.plot(x10,y10,'r-',markersize=5)\nfig.plot(x11,y11,'r-',markersize=5)\n\n# plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('Inmarsat Ping Estimation -- Individual Pings', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'plt' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m#Set figure size\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mfig\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfigsize\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m30\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m20\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;31m#Setup Basemap\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mfig\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mBasemap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwidth\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10000000\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mheight\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m18000000\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mprojection\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'lcc'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mresolution\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'c'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlat_0\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlon_0\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m90\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0msuppress_ticks\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'plt' is not defined" ] } ], "prompt_number": 31 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Notice how the very first one goes through the last point. Technically it's ~59 miles before -- but we can't see at that resolution. The first ping is dashed since it's before the plane disappeared, and it's right where we saw the last ping. For the remaining plots I've plotted a great circle line from the plane's last known location, to 40 S 85 E. The fact that it does not quite meet the last ping is not relevant to the conlusions from the below analysis (I reran the notebook to be able to type comments such as this.)" }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": "Running All of the Above with 5 -- (No Wait is it 6?!) -- Individual Satellite Pings" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "The Ping Probability Grid is kept at a 10x multiplication factor. I re-run all of the heading options with the most likely standard deviation or k value that represents a plane that is trying to get somewhere, but can change direction to some degree. (Again, if you take issue with this, this code is downloadable and re-runnable with different parameters. It's easy to plug and play. You only might have to wait a while for the simulations to finish running.)" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "I will run a normal heading distribution with std dev 30 (wide), von mises distribution with k=10 (medium, but narrower allowance for turns), and finally wrapped cauchy distribution with k=0.99 (almost a point; exceedingly small probability of turning from its previous heading) to capture a range of flying behaviors for our missing airplane, MH370. This is the final analysis undertaken for this model, with the most complete information as of March 30, 2014." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Note that one *assumption* I make which is a slight oversimplification, is that I assume 2.5-5% error for *each* of the pings even though *technically* there should be less standard deviation error for the earlier pings because they are closer to the satellite. I do not believe this is significant to the results (or else I would rectify it), but is worth stating. [Update: after running the results, it's actually a stronger argument for them. For my assumption introduces a sligthly wider range of paths MH370 could travel over; and there is still no way it can take a Great Circle route or travel by magnetic bearing -- which the 777 autopilot does by default in between set waypoints -- to locations off the coast of Australia which my model and Inmarsat believe it to be near.)" }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\na function which given a list of discrete probabilities for each destination point, \nit will choose one of those points.\n\nheading_init -- initial direction was headed at last known point\nlon_init,lat_init -- last known point of plane in longitude and latitude\nkm_hop -- how far the plane went in the time interval, 1 hr. So in simplest case, the 777's cruising speed/hr.\nstd_dev -- the standard deviation of the heading, based on a normal distribution from the current heading (0 deg).\nping_percent_err -- what % error you assume in the Inmarsat 5th ping. either 2.5 or 5%.\n\nuses normal distribution for heading\n\nreplace \"dist_from_sat\" with \"ping_distance\" since that's changing. run 6 times.\n\n\"\"\"\ndef six_hop_model_normal(heading_init,lon_init,lat_init,km_hop,std_dev,ping_percent_err,ping_distances,ping_times): \n \n #initialize\n plane_lat = np.zeros(6) #initialize plane location after each hop (assumed to be 1 hr for now)\n plane_lon = np.zeros(6) \n lat = lat_init\n lon = lon_init\n heading = heading_init\n \n for i in xrange(len(plane_lat)):\n new_circle,new_weights,new_angles = normal_prob_step(heading,std_dev,lon,lat,(km_hop/eq_deg_km)*ping_times[i])\n #new_circle gives up possible coords for diff headings\n \n raw_weights = np.zeros(len(new_circle))\n for j in xrange(len(new_circle)):\n raw_weights[j] = new_weights[j]*ping_prob_normal(inmarsat[0],inmarsat[1],new_circle[j][0],new_circle[j][1],ping_percent_err,ping_distances[i],earth_radius) \n \n probs = raw_weights / np.sum(raw_weights) #normalize \n \n index = range(len(new_circle))\n chosen = np.random.choice(index,size=None,p=probs)\n #print \"chosen\",chosen\n \n heading = new_angles[chosen] #update heading\n \n plane_lat[i],plane_lon[i] = new_circle[chosen] #update position\n lat = plane_lat[i]\n lon = plane_lon[i]\n \n #at end of simulation, run the last location & heading for plane for 4 different times\n route1 = make_vector(0.25*km_hop/eq_deg_km,heading,lon,lat)\n route2 = make_vector(0.5*km_hop/eq_deg_km,heading,lon,lat)\n route3 = make_vector(0.75*km_hop/eq_deg_km,heading,lon,lat)\n route4 = make_vector((59./60.)*km_hop/eq_deg_km,heading,lon,lat)\n\n new_plane_lat = np.zeros(10)\n new_plane_lon = np.zeros(10)\n \n for i in xrange(len(plane_lat)):\n new_plane_lat[i] = plane_lat[i]\n new_plane_lon[i] = plane_lon[i]\n \n new_plane_lat[6] = route1[0] # add 1 for 6 hops instead of 5\n new_plane_lat[7] = route2[0] # add 1 for 6 hops instead of 5\n new_plane_lat[8] = route3[0] # add 1 for 6 hops instead of 5\n new_plane_lat[9] = route4[0] # add 1 for 6 hops instead of 5\n new_plane_lon[6] = route1[1] # add 1 for 6 hops instead of 5\n new_plane_lon[7] = route2[1] # add 1 for 6 hops instead of 5\n new_plane_lon[8] = route3[1] # add 1 for 6 hops instead of 5\n new_plane_lon[9] = route4[1] # add 1 for 6 hops instead of 5\n \n return new_plane_lat,new_plane_lon", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\na function which given a list of discrete probabilities for each destination point, \nit will choose one of those points.\n\nheading_init -- initial direction was headed at last known point\nlon_init,lat_init -- last known point of plane in longitude and latitude\nkm_hop -- how far the plane went in the time interval, 1 hr. So in simplest case, the 777's cruising speed/hr.\nk -- affects the heading distribution, based on a Von Mises distribution from the current heading (0 deg).\nping_percent_err -- what % error you assume in the Inmarsat 5th ping. either 2.5 or 5%.\n\nuses Von Mises distribution for heading\n\nreplace \"dist_from_sat\" with \"ping_distance\" since that's changing. run 6 times.\n\n\"\"\"\ndef six_hop_model_von_mises(heading_init,lon_init,lat_init,km_hop,k,ping_percent_err,ping_distances,ping_times): \n \n #initialize\n plane_lat = np.zeros(6) #initialize plane location after each hop (assumed to be 1 hr for now)\n plane_lon = np.zeros(6) \n lat = lat_init\n lon = lon_init\n heading = heading_init\n \n for i in xrange(len(plane_lat)):\n new_circle,new_weights,new_angles = von_mises_prob_step(heading,k,lon,lat,(km_hop/eq_deg_km)*ping_times[i])\n #new_circle gives up possible coords for diff headings\n \n raw_weights = np.zeros(len(new_circle))\n for j in xrange(len(new_circle)):\n raw_weights[j] = new_weights[j]*ping_prob_normal(inmarsat[0],inmarsat[1],new_circle[j][0],new_circle[j][1],ping_percent_err,ping_distances[i],earth_radius) \n \n probs = raw_weights / np.sum(raw_weights) #normalize \n \n index = range(len(new_circle))\n chosen = np.random.choice(index,size=None,p=probs)\n #print \"chosen\",chosen\n \n heading = new_angles[chosen] #update heading\n \n plane_lat[i],plane_lon[i] = new_circle[chosen] #update position\n lat = plane_lat[i]\n lon = plane_lon[i]\n \n #at end of simulation, run the last location & heading for plane for 4 different times\n route1 = make_vector(0.25*km_hop/eq_deg_km,heading,lon,lat)\n route2 = make_vector(0.5*km_hop/eq_deg_km,heading,lon,lat)\n route3 = make_vector(0.75*km_hop/eq_deg_km,heading,lon,lat)\n route4 = make_vector((59./60.)*km_hop/eq_deg_km,heading,lon,lat)\n\n new_plane_lat = np.zeros(10)\n new_plane_lon = np.zeros(10)\n \n for i in xrange(len(plane_lat)):\n new_plane_lat[i] = plane_lat[i]\n new_plane_lon[i] = plane_lon[i]\n \n new_plane_lat[6] = route1[0] # add 1 for 6 hops instead of 5\n new_plane_lat[7] = route2[0] # add 1 for 6 hops instead of 5\n new_plane_lat[8] = route3[0] # add 1 for 6 hops instead of 5\n new_plane_lat[9] = route4[0] # add 1 for 6 hops instead of 5\n new_plane_lon[6] = route1[1] # add 1 for 6 hops instead of 5\n new_plane_lon[7] = route2[1] # add 1 for 6 hops instead of 5\n new_plane_lon[8] = route3[1] # add 1 for 6 hops instead of 5\n new_plane_lon[9] = route4[1] # add 1 for 6 hops instead of 5\n \n return new_plane_lat,new_plane_lon", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "\"\"\"\na function which given a list of discrete probabilities for each destination point, \nit will choose one of those points.\n\nheading_init -- initial direction was headed at last known point\nlon_init,lat_init -- last known point of plane in longitude and latitude\nkm_hop -- how far the plane went in the time interval, 1 hr. So in simplest case, the 777's cruising speed/hr.\nk -- affects the heading distribution, based on a Wrapped Cauchy distribution from the current heading (0 deg).\nping_percent_err -- what % error you assume in the Inmarsat 5th ping. either 2.5 or 5%.\n\nuses Wrapped Cauchy distribution for heading\n\nreplace \"dist_from_sat\" with \"ping_distance\" since that's changing. run 6 times.\n\n\"\"\"\ndef six_hop_model_wrapped_cauchy(heading_init,lon_init,lat_init,km_hop,k,ping_percent_err,ping_distances,ping_times): \n \n #initialize\n plane_lat = np.zeros(6) #initialize plane location after each hop (assumed to be 1 hr for now)\n plane_lon = np.zeros(6) \n lat = lat_init\n lon = lon_init\n heading = heading_init\n \n for i in xrange(len(plane_lat)):\n new_circle,new_weights,new_angles = wrapped_cauchy_prob_step(heading,k,lon,lat,(km_hop/eq_deg_km)*ping_times[i])\n #new_circle gives up possible coords for diff headings\n \n raw_weights = np.zeros(len(new_circle))\n for j in xrange(len(new_circle)):\n raw_weights[j] = new_weights[j]*ping_prob_normal(inmarsat[0],inmarsat[1],new_circle[j][0],new_circle[j][1],ping_percent_err,ping_distances[i],earth_radius) \n \n probs = raw_weights / np.sum(raw_weights) #normalize \n \n index = range(len(new_circle))\n chosen = np.random.choice(index,size=None,p=probs)\n #print \"chosen\",chosen\n \n heading = new_angles[chosen] #update heading\n \n plane_lat[i],plane_lon[i] = new_circle[chosen] #update position\n lat = plane_lat[i]\n lon = plane_lon[i]\n \n #at end of simulation, run the last location & heading for plane for 4 different times\n route1 = make_vector(0.25*km_hop/eq_deg_km,heading,lon,lat)\n route2 = make_vector(0.5*km_hop/eq_deg_km,heading,lon,lat)\n route3 = make_vector(0.75*km_hop/eq_deg_km,heading,lon,lat)\n route4 = make_vector((59./60.)*km_hop/eq_deg_km,heading,lon,lat)\n\n new_plane_lat = np.zeros(10)\n new_plane_lon = np.zeros(10)\n \n for i in xrange(len(plane_lat)):\n new_plane_lat[i] = plane_lat[i]\n new_plane_lon[i] = plane_lon[i]\n \n new_plane_lat[6] = route1[0] # add 1 for 6 hops instead of 5\n new_plane_lat[7] = route2[0] # add 1 for 6 hops instead of 5\n new_plane_lat[8] = route3[0] # add 1 for 6 hops instead of 5\n new_plane_lat[9] = route4[0] # add 1 for 6 hops instead of 5\n new_plane_lon[6] = route1[1] # add 1 for 6 hops instead of 5\n new_plane_lon[7] = route2[1] # add 1 for 6 hops instead of 5\n new_plane_lon[8] = route3[1] # add 1 for 6 hops instead of 5\n new_plane_lon[9] = route4[1] # add 1 for 6 hops instead of 5\n \n return new_plane_lat,new_plane_lon", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "last_known_heading = 255.136 #calculated in Mathematica from MH370's two last publically known locations:\n #when it deviated from its flight path, and when it was last detected by Malyasian military radar\n #0 degrees is due north, so this is basically to the west (270 degrees), but slightly south\n\nkm_hop = 905 #assuming 1 hr intervals, at 905 km/hr which is 777 cruising speed -- use for test case\n # max speed of a Boeing 777 is 950 km/hr FYI\n\nN = 1000 #define number of simulations to run", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Normal Distribution Heading" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Standard Deviation of 30 degrees (allows for some turning each time)" }, { "cell_type": "code", "collapsed": false, "input": "percenterror1,percenterror2 = 0.05, 0.025\n\nstd_dev = 30", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "plane_hops_5per = []\nplane_hops_2per = []\n\nfor i in xrange(N):\n plane_hops_5per.append(six_hop_model_normal(last_known_heading,pulauperak[1],pulauperak[0],km_hop,std_dev,percenterror1,ping_distances,ping_times))\n plane_hops_2per.append(six_hop_model_normal(last_known_heading,pulauperak[1],pulauperak[0],km_hop,std_dev,percenterror2,ping_distances,ping_times))", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "first_lat_5per = []\ntwo_lat_5per = []\nthree_lat_5per = []\nfour_lat_5per = []\nfive_lat_5per = []\nfinal_lat_5per = []\n\nfirst_lon_5per = []\ntwo_lon_5per = []\nthree_lon_5per = []\nfour_lon_5per = []\nfive_lon_5per = []\nfinal_lon_5per = []\n\nroute1_lat_5per = []\nroute2_lat_5per = []\nroute3_lat_5per = []\nroute4_lat_5per = []\n\nroute1_lon_5per = []\nroute2_lon_5per = []\nroute3_lon_5per = []\nroute4_lon_5per = []\n\nfor i in xrange(len(plane_hops_5per)):\n first_lat_5per.append(plane_hops_5per[i][0][0])\n first_lon_5per.append(plane_hops_5per[i][1][0])\n two_lat_5per.append(plane_hops_5per[i][0][1])\n two_lon_5per.append(plane_hops_5per[i][1][1])\n three_lat_5per.append(plane_hops_5per[i][0][2])\n three_lon_5per.append(plane_hops_5per[i][1][2])\n four_lat_5per.append(plane_hops_5per[i][0][3])\n four_lon_5per.append(plane_hops_5per[i][1][3])\n five_lat_5per.append(plane_hops_5per[i][0][4])\n five_lon_5per.append(plane_hops_5per[i][1][4])\n final_lat_5per.append(plane_hops_5per[i][0][5])\n final_lon_5per.append(plane_hops_5per[i][1][5])\n \n route1_lat_5per.append(plane_hops_5per[i][0][6])\n route1_lon_5per.append(plane_hops_5per[i][1][6])\n route2_lat_5per.append(plane_hops_5per[i][0][7])\n route2_lon_5per.append(plane_hops_5per[i][1][7])\n route3_lat_5per.append(plane_hops_5per[i][0][8])\n route3_lon_5per.append(plane_hops_5per[i][1][8])\n route4_lat_5per.append(plane_hops_5per[i][0][9])\n route4_lon_5per.append(plane_hops_5per[i][1][9])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "first_lat_2per = []\ntwo_lat_2per = []\nthree_lat_2per = []\nfour_lat_2per = []\nfive_lat_2per = []\nfinal_lat_2per = []\n\nfirst_lon_2per = []\ntwo_lon_2per = []\nthree_lon_2per = []\nfour_lon_2per = []\nfive_lon_2per = []\nfinal_lon_2per = []\n\nroute1_lat_2per = []\nroute2_lat_2per = []\nroute3_lat_2per = []\nroute4_lat_2per = []\n\nroute1_lon_2per = []\nroute2_lon_2per = []\nroute3_lon_2per = []\nroute4_lon_2per = []\n\nfor i in xrange(len(plane_hops_2per)):\n first_lat_2per.append(plane_hops_2per[i][0][0])\n first_lon_2per.append(plane_hops_2per[i][1][0])\n two_lat_2per.append(plane_hops_2per[i][0][1])\n two_lon_2per.append(plane_hops_2per[i][1][1])\n three_lat_2per.append(plane_hops_2per[i][0][2])\n three_lon_2per.append(plane_hops_2per[i][1][2])\n four_lat_2per.append(plane_hops_2per[i][0][3])\n four_lon_2per.append(plane_hops_2per[i][1][3])\n five_lat_2per.append(plane_hops_2per[i][0][4])\n five_lon_2per.append(plane_hops_2per[i][1][4])\n final_lat_2per.append(plane_hops_2per[i][0][5])\n final_lon_2per.append(plane_hops_2per[i][1][5])\n \n route1_lat_2per.append(plane_hops_2per[i][0][6])\n route1_lon_2per.append(plane_hops_2per[i][1][6])\n route2_lat_2per.append(plane_hops_2per[i][0][7])\n route2_lon_2per.append(plane_hops_2per[i][1][7])\n route3_lat_2per.append(plane_hops_2per[i][0][8])\n route3_lon_2per.append(plane_hops_2per[i][1][8])\n route4_lat_2per.append(plane_hops_2per[i][0][9])\n route4_lon_2per.append(plane_hops_2per[i][1][9])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "5% results:" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw great circle to show path autopilot would have taken\nfig.drawgreatcircle(pulauperak[1],pulauperak[0],85,-40,linewidth=3,color='black',label='Great Circle Path')\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- these are for each ping. will not plot the 2.5 and 5% error\nx5,y5 = fig(circle_lon_211am,circle_lat_211am)\nx6,y6 = fig(circle_lon_311am,circle_lat_311am)\nx7,y7 = fig(circle_lon_411am,circle_lat_411am)\nx8,y8 = fig(circle_lon_511am,circle_lat_511am)\nx9,y9 = fig(circle_lon_611am,circle_lat_611am)\nx10,y10 = fig(circle_lon_711am,circle_lat_711am)\nx11,y11 = fig(circle_lon_811am,circle_lat_811am)\n\n#Add points after each hr\nx12,y12 = fig(first_lon_5per,first_lat_5per)\nx13,y13 = fig(two_lon_5per,two_lat_5per)\nx14,y14 = fig(three_lon_5per,three_lat_5per)\nx15,y15 = fig(four_lon_5per,four_lat_5per)\nx16,y16 = fig(five_lon_5per,five_lat_5per)\nx17,y17 = fig(final_lon_5per,final_lat_5per)\n\n#Add ultimate locations of MH370\nx18,y18 = fig(route1_lon_5per,route1_lat_5per)\nx19,y19 = fig(route2_lon_5per,route2_lat_5per)\nx20,y20 = fig(route3_lon_5per,route3_lat_5per)\nx21,y21 = fig(route4_lon_5per,route4_lat_5per)\n\n# plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Draw circle showing extent of Inmarsat sat radar detection for each of the pings\nfig.plot(x5,y5,'r--',markersize=5,label='1st Ping Arc')\nfig.plot(x6,y6,'r-',markersize=5, label='Ping Arcs After Disappearance')\nfig.plot(x7,y7,'r-',markersize=5)\nfig.plot(x8,y8,'r-',markersize=5)\nfig.plot(x9,y9,'r-',markersize=5)\nfig.plot(x10,y10,'r-',markersize=5)\nfig.plot(x11,y11,'r-',markersize=5)\n\n#Add monte carlo points\nfig.plot(x12,y12,'yo',markersize=5,label='after 1 hrs')\nfig.plot(x13,y13,'mo',markersize=5,label= 'after 2 hrs')\nfig.plot(x14,y14,'wo',markersize=5,label='after 3 hrs')\nfig.plot(x15,y15,'bo',markersize=5,label='after 4 hrs')\nfig.plot(x16,y16,'go',markersize=5,label='after 5 hrs')\nfig.plot(x17,y17,'ro',markersize=7,label='after 6 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x18,y18,'bo',markersize=5,label='in final hr')\nfig.plot(x19,y19,'bo',markersize=5)\nfig.plot(x20,y20,'bo',markersize=5)\nfig.plot(x21,y21,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('Inmarsat Ping Estimation -- Individual Pings', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "2.5% results:" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw great circle to show path autopilot would have taken\nfig.drawgreatcircle(pulauperak[1],pulauperak[0],85,-40,linewidth=3,color='black',label='Great Circle Path')\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- these are for each ping. will not plot the 2.5 and 5% error\nx5,y5 = fig(circle_lon_211am,circle_lat_211am)\nx6,y6 = fig(circle_lon_311am,circle_lat_311am)\nx7,y7 = fig(circle_lon_411am,circle_lat_411am)\nx8,y8 = fig(circle_lon_511am,circle_lat_511am)\nx9,y9 = fig(circle_lon_611am,circle_lat_611am)\nx10,y10 = fig(circle_lon_711am,circle_lat_711am)\nx11,y11 = fig(circle_lon_811am,circle_lat_811am)\n\n#Add points after each hr\nx12,y12 = fig(first_lon_2per,first_lat_2per)\nx13,y13 = fig(two_lon_2per,two_lat_2per)\nx14,y14 = fig(three_lon_2per,three_lat_2per)\nx15,y15 = fig(four_lon_2per,four_lat_2per)\nx16,y16 = fig(five_lon_2per,five_lat_2per)\nx17,y17 = fig(final_lon_2per,final_lat_2per)\n\n#Add ultimate locations of MH370\nx18,y18 = fig(route1_lon_2per,route1_lat_2per)\nx19,y19 = fig(route2_lon_2per,route2_lat_2per)\nx20,y20 = fig(route3_lon_2per,route3_lat_2per)\nx21,y21 = fig(route4_lon_2per,route4_lat_2per)\n\n# plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Draw circle showing extent of Inmarsat sat radar detection for each of the pings\nfig.plot(x5,y5,'r--',markersize=5,label='1st Ping Arc')\nfig.plot(x6,y6,'r-',markersize=5, label='Ping Arcs After Disappearance')\nfig.plot(x7,y7,'r-',markersize=5)\nfig.plot(x8,y8,'r-',markersize=5)\nfig.plot(x9,y9,'r-',markersize=5)\nfig.plot(x10,y10,'r-',markersize=5)\nfig.plot(x11,y11,'r-',markersize=5)\n\n#Add monte carlo points\nfig.plot(x12,y12,'yo',markersize=5,label='after 1 hrs')\nfig.plot(x13,y13,'mo',markersize=5,label= 'after 2 hrs')\nfig.plot(x14,y14,'wo',markersize=5,label='after 3 hrs')\nfig.plot(x15,y15,'bo',markersize=5,label='after 4 hrs')\nfig.plot(x16,y16,'go',markersize=5,label='after 5 hrs')\nfig.plot(x17,y17,'ro',markersize=7,label='after 6 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x18,y18,'bo',markersize=5,label='in final hr')\nfig.plot(x19,y19,'bo',markersize=5)\nfig.plot(x20,y20,'bo',markersize=5)\nfig.plot(x21,y21,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('Inmarsat Ping Estimation -- Individual Pings', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "The normal distribution, with individual pings and 2.5-5% std dev error for each ping, demonstrates a narrow range of possible flight paths to an eventual endpoint in the Southern Ocean, roughly 40-45 degrees south and between 75-90 E. These results are consistent, but further refined, than Inmarsat's best guess (as it incorporates much more than two possibilities -- the benefit of using a Monte Carlo model), fitting to the constraints of the pings and their errors. Note that a speed variance would merely move the plane to the red dots, which would be the plane's location at the last ping, *or* of the plane was super slow, perhaps toward the green dots along the same arc. So they would not change this plot per se; just how you would interpret it. Also note the preferential movement of the plane to the south." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "An important condition for later, is that the plane needs to progressively get farther away at each ping (which we have been told is the case). This means that the plane cannot continue in a straight line down south, which would rule out autopilot (which on a 777 defaults to a Great Circle path). None of the existing infographics show all of the pings, which is why they haven't noticed this." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "And note that with the error margins already built in, you have no room on the map to move the pings between the first and the last one around with each other, and have the plane go in a straight line. Note that there *are* a *few* possibilities for a Great Circle arc flight path in the 5% error case...but this would mean that ping locations are substantially greater than what has been reported. So this is extremely unlikely." }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Von Mises Distribution Heading" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "k = 10 (make pointed)" }, { "cell_type": "code", "collapsed": false, "input": "percenterror1,percenterror2 = 0.05, 0.025\n\nk = 10", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "plane_hops_5per = []\nplane_hops_2per = []\n\nfor i in xrange(N):\n plane_hops_5per.append(six_hop_model_von_mises(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k,percenterror1,ping_distances,ping_times))\n plane_hops_2per.append(six_hop_model_von_mises(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k,percenterror2,ping_distances,ping_times))", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "first_lat_5per = []\ntwo_lat_5per = []\nthree_lat_5per = []\nfour_lat_5per = []\nfive_lat_5per = []\nfinal_lat_5per = []\n\nfirst_lon_5per = []\ntwo_lon_5per = []\nthree_lon_5per = []\nfour_lon_5per = []\nfive_lon_5per = []\nfinal_lon_5per = []\n\nroute1_lat_5per = []\nroute2_lat_5per = []\nroute3_lat_5per = []\nroute4_lat_5per = []\n\nroute1_lon_5per = []\nroute2_lon_5per = []\nroute3_lon_5per = []\nroute4_lon_5per = []\n\nfor i in xrange(len(plane_hops_5per)):\n first_lat_5per.append(plane_hops_5per[i][0][0])\n first_lon_5per.append(plane_hops_5per[i][1][0])\n two_lat_5per.append(plane_hops_5per[i][0][1])\n two_lon_5per.append(plane_hops_5per[i][1][1])\n three_lat_5per.append(plane_hops_5per[i][0][2])\n three_lon_5per.append(plane_hops_5per[i][1][2])\n four_lat_5per.append(plane_hops_5per[i][0][3])\n four_lon_5per.append(plane_hops_5per[i][1][3])\n five_lat_5per.append(plane_hops_5per[i][0][4])\n five_lon_5per.append(plane_hops_5per[i][1][4])\n final_lat_5per.append(plane_hops_5per[i][0][5])\n final_lon_5per.append(plane_hops_5per[i][1][5])\n \n route1_lat_5per.append(plane_hops_5per[i][0][6])\n route1_lon_5per.append(plane_hops_5per[i][1][6])\n route2_lat_5per.append(plane_hops_5per[i][0][7])\n route2_lon_5per.append(plane_hops_5per[i][1][7])\n route3_lat_5per.append(plane_hops_5per[i][0][8])\n route3_lon_5per.append(plane_hops_5per[i][1][8])\n route4_lat_5per.append(plane_hops_5per[i][0][9])\n route4_lon_5per.append(plane_hops_5per[i][1][9])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "first_lat_2per = []\ntwo_lat_2per = []\nthree_lat_2per = []\nfour_lat_2per = []\nfive_lat_2per = []\nfinal_lat_2per = []\n\nfirst_lon_2per = []\ntwo_lon_2per = []\nthree_lon_2per = []\nfour_lon_2per = []\nfive_lon_2per = []\nfinal_lon_2per = []\n\nroute1_lat_2per = []\nroute2_lat_2per = []\nroute3_lat_2per = []\nroute4_lat_2per = []\n\nroute1_lon_2per = []\nroute2_lon_2per = []\nroute3_lon_2per = []\nroute4_lon_2per = []\n\nfor i in xrange(len(plane_hops_2per)):\n first_lat_2per.append(plane_hops_2per[i][0][0])\n first_lon_2per.append(plane_hops_2per[i][1][0])\n two_lat_2per.append(plane_hops_2per[i][0][1])\n two_lon_2per.append(plane_hops_2per[i][1][1])\n three_lat_2per.append(plane_hops_2per[i][0][2])\n three_lon_2per.append(plane_hops_2per[i][1][2])\n four_lat_2per.append(plane_hops_2per[i][0][3])\n four_lon_2per.append(plane_hops_2per[i][1][3])\n five_lat_2per.append(plane_hops_2per[i][0][4])\n five_lon_2per.append(plane_hops_2per[i][1][4])\n final_lat_2per.append(plane_hops_2per[i][0][5])\n final_lon_2per.append(plane_hops_2per[i][1][5])\n \n route1_lat_2per.append(plane_hops_2per[i][0][6])\n route1_lon_2per.append(plane_hops_2per[i][1][6])\n route2_lat_2per.append(plane_hops_2per[i][0][7])\n route2_lon_2per.append(plane_hops_2per[i][1][7])\n route3_lat_2per.append(plane_hops_2per[i][0][8])\n route3_lon_2per.append(plane_hops_2per[i][1][8])\n route4_lat_2per.append(plane_hops_2per[i][0][9])\n route4_lon_2per.append(plane_hops_2per[i][1][9])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "5% results:" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw great circle to show path autopilot would have taken\nfig.drawgreatcircle(pulauperak[1],pulauperak[0],85,-40,linewidth=3,color='black',label='Great Circle Path')\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- these are for each ping. will not plot the 2.5 and 5% error\nx5,y5 = fig(circle_lon_211am,circle_lat_211am)\nx6,y6 = fig(circle_lon_311am,circle_lat_311am)\nx7,y7 = fig(circle_lon_411am,circle_lat_411am)\nx8,y8 = fig(circle_lon_511am,circle_lat_511am)\nx9,y9 = fig(circle_lon_611am,circle_lat_611am)\nx10,y10 = fig(circle_lon_711am,circle_lat_711am)\nx11,y11 = fig(circle_lon_811am,circle_lat_811am)\n\n#Add points after each hr\nx12,y12 = fig(first_lon_5per,first_lat_5per)\nx13,y13 = fig(two_lon_5per,two_lat_5per)\nx14,y14 = fig(three_lon_5per,three_lat_5per)\nx15,y15 = fig(four_lon_5per,four_lat_5per)\nx16,y16 = fig(five_lon_5per,five_lat_5per)\nx17,y17 = fig(final_lon_5per,final_lat_5per)\n\n#Add ultimate locations of MH370\nx18,y18 = fig(route1_lon_5per,route1_lat_5per)\nx19,y19 = fig(route2_lon_5per,route2_lat_5per)\nx20,y20 = fig(route3_lon_5per,route3_lat_5per)\nx21,y21 = fig(route4_lon_5per,route4_lat_5per)\n\n# plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Draw circle showing extent of Inmarsat sat radar detection for each of the pings\nfig.plot(x5,y5,'r--',markersize=5,label='1st Ping Arc')\nfig.plot(x6,y6,'r-',markersize=5, label='Ping Arcs After Disappearance')\nfig.plot(x7,y7,'r-',markersize=5)\nfig.plot(x8,y8,'r-',markersize=5)\nfig.plot(x9,y9,'r-',markersize=5)\nfig.plot(x10,y10,'r-',markersize=5)\nfig.plot(x11,y11,'r-',markersize=5)\n\n#Add monte carlo points\nfig.plot(x12,y12,'yo',markersize=5,label='after 1 hrs')\nfig.plot(x13,y13,'mo',markersize=5,label= 'after 2 hrs')\nfig.plot(x14,y14,'wo',markersize=5,label='after 3 hrs')\nfig.plot(x15,y15,'bo',markersize=5,label='after 4 hrs')\nfig.plot(x16,y16,'go',markersize=5,label='after 5 hrs')\nfig.plot(x17,y17,'ro',markersize=7,label='after 6 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x18,y18,'bo',markersize=5,label='in final hr')\nfig.plot(x19,y19,'bo',markersize=5)\nfig.plot(x20,y20,'bo',markersize=5)\nfig.plot(x21,y21,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('Inmarsat Ping Estimation -- Individual Pings', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [ { "ename": "NameError", "evalue": "name 'plt' is not defined", "output_type": "pyerr", "traceback": [ "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m\n\u001b[1;31mNameError\u001b[0m Traceback (most recent call last)", "\u001b[1;32m\u001b[0m in \u001b[0;36m\u001b[1;34m()\u001b[0m\n\u001b[0;32m 1\u001b[0m \u001b[1;31m#Set figure size\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mfig\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mplt\u001b[0m\u001b[1;33m.\u001b[0m\u001b[0mfigure\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mfigsize\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m30\u001b[0m\u001b[1;33m,\u001b[0m\u001b[1;36m20\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m\u001b[0;32m 3\u001b[0m \u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 4\u001b[0m \u001b[1;31m#Setup Basemap\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0;32m 5\u001b[0m \u001b[0mfig\u001b[0m \u001b[1;33m=\u001b[0m \u001b[0mBasemap\u001b[0m\u001b[1;33m(\u001b[0m\u001b[0mwidth\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10000000\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mheight\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m18000000\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mprojection\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'lcc'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mresolution\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;34m'c'\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlat_0\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m10\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0mlon_0\u001b[0m\u001b[1;33m=\u001b[0m\u001b[1;36m90\u001b[0m\u001b[1;33m,\u001b[0m\u001b[0msuppress_ticks\u001b[0m\u001b[1;33m=\u001b[0m\u001b[0mTrue\u001b[0m\u001b[1;33m)\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n", "\u001b[1;31mNameError\u001b[0m: name 'plt' is not defined" ] } ], "prompt_number": 32 }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "2.5% results:" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw great circle to show path autopilot would have taken\nfig.drawgreatcircle(pulauperak[1],pulauperak[0],85,-40,linewidth=3,color='black',label='Great Circle Path')\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- these are for each ping. will not plot the 2.5 and 5% error\nx5,y5 = fig(circle_lon_211am,circle_lat_211am)\nx6,y6 = fig(circle_lon_311am,circle_lat_311am)\nx7,y7 = fig(circle_lon_411am,circle_lat_411am)\nx8,y8 = fig(circle_lon_511am,circle_lat_511am)\nx9,y9 = fig(circle_lon_611am,circle_lat_611am)\nx10,y10 = fig(circle_lon_711am,circle_lat_711am)\nx11,y11 = fig(circle_lon_811am,circle_lat_811am)\n\n#Add points after each hr\nx12,y12 = fig(first_lon_2per,first_lat_2per)\nx13,y13 = fig(two_lon_2per,two_lat_2per)\nx14,y14 = fig(three_lon_2per,three_lat_2per)\nx15,y15 = fig(four_lon_2per,four_lat_2per)\nx16,y16 = fig(five_lon_2per,five_lat_2per)\nx17,y17 = fig(final_lon_2per,final_lat_2per)\n\n#Add ultimate locations of MH370\nx18,y18 = fig(route1_lon_2per,route1_lat_2per)\nx19,y19 = fig(route2_lon_2per,route2_lat_2per)\nx20,y20 = fig(route3_lon_2per,route3_lat_2per)\nx21,y21 = fig(route4_lon_2per,route4_lat_2per)\n\n# plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Draw circle showing extent of Inmarsat sat radar detection for each of the pings\nfig.plot(x5,y5,'r--',markersize=5,label='1st Ping Arc')\nfig.plot(x6,y6,'r-',markersize=5, label='Ping Arcs After Disappearance')\nfig.plot(x7,y7,'r-',markersize=5)\nfig.plot(x8,y8,'r-',markersize=5)\nfig.plot(x9,y9,'r-',markersize=5)\nfig.plot(x10,y10,'r-',markersize=5)\nfig.plot(x11,y11,'r-',markersize=5)\n\n#Add monte carlo points\nfig.plot(x12,y12,'yo',markersize=5,label='after 1 hrs')\nfig.plot(x13,y13,'mo',markersize=5,label= 'after 2 hrs')\nfig.plot(x14,y14,'wo',markersize=5,label='after 3 hrs')\nfig.plot(x15,y15,'bo',markersize=5,label='after 4 hrs')\nfig.plot(x16,y16,'go',markersize=5,label='after 5 hrs')\nfig.plot(x17,y17,'ro',markersize=7,label='after 6 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x18,y18,'bo',markersize=5,label='in final hr')\nfig.plot(x19,y19,'bo',markersize=5)\nfig.plot(x20,y20,'bo',markersize=5)\nfig.plot(x21,y21,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('Inmarsat Ping Estimation -- Individual Pings', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Wrapped Cauchy Distribution Heading" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "k = 0.99 (make pointed if it was going straight ahead)" }, { "cell_type": "code", "collapsed": false, "input": "percenterror1,percenterror2 = 0.05, 0.025\n\nk = 0.99", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "plane_hops_5per = []\nplane_hops_2per = []\n\nfor i in xrange(N):\n plane_hops_5per.append(six_hop_model_wrapped_cauchy(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k,percenterror1,ping_distances,ping_times))\n plane_hops_2per.append(six_hop_model_wrapped_cauchy(last_known_heading,pulauperak[1],pulauperak[0],km_hop,k,percenterror2,ping_distances,ping_times))", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "first_lat_5per = []\ntwo_lat_5per = []\nthree_lat_5per = []\nfour_lat_5per = []\nfive_lat_5per = []\nfinal_lat_5per = []\n\nfirst_lon_5per = []\ntwo_lon_5per = []\nthree_lon_5per = []\nfour_lon_5per = []\nfive_lon_5per = []\nfinal_lon_5per = []\n\nroute1_lat_5per = []\nroute2_lat_5per = []\nroute3_lat_5per = []\nroute4_lat_5per = []\n\nroute1_lon_5per = []\nroute2_lon_5per = []\nroute3_lon_5per = []\nroute4_lon_5per = []\n\nfor i in xrange(len(plane_hops_5per)):\n first_lat_5per.append(plane_hops_5per[i][0][0])\n first_lon_5per.append(plane_hops_5per[i][1][0])\n two_lat_5per.append(plane_hops_5per[i][0][1])\n two_lon_5per.append(plane_hops_5per[i][1][1])\n three_lat_5per.append(plane_hops_5per[i][0][2])\n three_lon_5per.append(plane_hops_5per[i][1][2])\n four_lat_5per.append(plane_hops_5per[i][0][3])\n four_lon_5per.append(plane_hops_5per[i][1][3])\n five_lat_5per.append(plane_hops_5per[i][0][4])\n five_lon_5per.append(plane_hops_5per[i][1][4])\n final_lat_5per.append(plane_hops_5per[i][0][5])\n final_lon_5per.append(plane_hops_5per[i][1][5])\n \n route1_lat_5per.append(plane_hops_5per[i][0][6])\n route1_lon_5per.append(plane_hops_5per[i][1][6])\n route2_lat_5per.append(plane_hops_5per[i][0][7])\n route2_lon_5per.append(plane_hops_5per[i][1][7])\n route3_lat_5per.append(plane_hops_5per[i][0][8])\n route3_lon_5per.append(plane_hops_5per[i][1][8])\n route4_lat_5per.append(plane_hops_5per[i][0][9])\n route4_lon_5per.append(plane_hops_5per[i][1][9])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": "first_lat_2per = []\ntwo_lat_2per = []\nthree_lat_2per = []\nfour_lat_2per = []\nfive_lat_2per = []\nfinal_lat_2per = []\n\nfirst_lon_2per = []\ntwo_lon_2per = []\nthree_lon_2per = []\nfour_lon_2per = []\nfive_lon_2per = []\nfinal_lon_2per = []\n\nroute1_lat_2per = []\nroute2_lat_2per = []\nroute3_lat_2per = []\nroute4_lat_2per = []\n\nroute1_lon_2per = []\nroute2_lon_2per = []\nroute3_lon_2per = []\nroute4_lon_2per = []\n\nfor i in xrange(len(plane_hops_2per)):\n first_lat_2per.append(plane_hops_2per[i][0][0])\n first_lon_2per.append(plane_hops_2per[i][1][0])\n two_lat_2per.append(plane_hops_2per[i][0][1])\n two_lon_2per.append(plane_hops_2per[i][1][1])\n three_lat_2per.append(plane_hops_2per[i][0][2])\n three_lon_2per.append(plane_hops_2per[i][1][2])\n four_lat_2per.append(plane_hops_2per[i][0][3])\n four_lon_2per.append(plane_hops_2per[i][1][3])\n five_lat_2per.append(plane_hops_2per[i][0][4])\n five_lon_2per.append(plane_hops_2per[i][1][4])\n final_lat_2per.append(plane_hops_2per[i][0][5])\n final_lon_2per.append(plane_hops_2per[i][1][5])\n \n route1_lat_2per.append(plane_hops_2per[i][0][6])\n route1_lon_2per.append(plane_hops_2per[i][1][6])\n route2_lat_2per.append(plane_hops_2per[i][0][7])\n route2_lon_2per.append(plane_hops_2per[i][1][7])\n route3_lat_2per.append(plane_hops_2per[i][0][8])\n route3_lon_2per.append(plane_hops_2per[i][1][8])\n route4_lat_2per.append(plane_hops_2per[i][0][9])\n route4_lon_2per.append(plane_hops_2per[i][1][9])", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "5% results:" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw great circle to show path autopilot would have taken\nfig.drawgreatcircle(pulauperak[1],pulauperak[0],85,-40,linewidth=3,color='black',label='Great Circle Path')\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- these are for each ping. will not plot the 2.5 and 5% error\nx5,y5 = fig(circle_lon_211am,circle_lat_211am)\nx6,y6 = fig(circle_lon_311am,circle_lat_311am)\nx7,y7 = fig(circle_lon_411am,circle_lat_411am)\nx8,y8 = fig(circle_lon_511am,circle_lat_511am)\nx9,y9 = fig(circle_lon_611am,circle_lat_611am)\nx10,y10 = fig(circle_lon_711am,circle_lat_711am)\nx11,y11 = fig(circle_lon_811am,circle_lat_811am)\n\n#Add points after each hr\nx12,y12 = fig(first_lon_5per,first_lat_5per)\nx13,y13 = fig(two_lon_5per,two_lat_5per)\nx14,y14 = fig(three_lon_5per,three_lat_5per)\nx15,y15 = fig(four_lon_5per,four_lat_5per)\nx16,y16 = fig(five_lon_5per,five_lat_5per)\nx17,y17 = fig(final_lon_5per,final_lat_5per)\n\n#Add ultimate locations of MH370\nx18,y18 = fig(route1_lon_5per,route1_lat_5per)\nx19,y19 = fig(route2_lon_5per,route2_lat_5per)\nx20,y20 = fig(route3_lon_5per,route3_lat_5per)\nx21,y21 = fig(route4_lon_5per,route4_lat_5per)\n\n# plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Draw circle showing extent of Inmarsat sat radar detection for each of the pings\nfig.plot(x5,y5,'r--',markersize=5,label='1st Ping Arc')\nfig.plot(x6,y6,'r-',markersize=5, label='Ping Arcs After Disappearance')\nfig.plot(x7,y7,'r-',markersize=5)\nfig.plot(x8,y8,'r-',markersize=5)\nfig.plot(x9,y9,'r-',markersize=5)\nfig.plot(x10,y10,'r-',markersize=5)\nfig.plot(x11,y11,'r-',markersize=5)\n\n#Add monte carlo points\nfig.plot(x12,y12,'yo',markersize=5,label='after 1 hrs')\nfig.plot(x13,y13,'mo',markersize=5,label= 'after 2 hrs')\nfig.plot(x14,y14,'wo',markersize=5,label='after 3 hrs')\nfig.plot(x15,y15,'bo',markersize=5,label='after 4 hrs')\nfig.plot(x16,y16,'go',markersize=5,label='after 5 hrs')\nfig.plot(x17,y17,'ro',markersize=7,label='after 6 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x18,y18,'bo',markersize=5,label='in final hr')\nfig.plot(x19,y19,'bo',markersize=5)\nfig.plot(x20,y20,'bo',markersize=5)\nfig.plot(x21,y21,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('Inmarsat Ping Estimation -- Individual Pings', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "2.5% results:" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw great circle to show path autopilot would have taken\nfig.drawgreatcircle(pulauperak[1],pulauperak[0],85,-40,linewidth=3,color='black',label='Great Circle Path')\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- these are for each ping. will not plot the 2.5 and 5% error\nx5,y5 = fig(circle_lon_211am,circle_lat_211am)\nx6,y6 = fig(circle_lon_311am,circle_lat_311am)\nx7,y7 = fig(circle_lon_411am,circle_lat_411am)\nx8,y8 = fig(circle_lon_511am,circle_lat_511am)\nx9,y9 = fig(circle_lon_611am,circle_lat_611am)\nx10,y10 = fig(circle_lon_711am,circle_lat_711am)\nx11,y11 = fig(circle_lon_811am,circle_lat_811am)\n\n#Add points after each hr\nx12,y12 = fig(first_lon_2per,first_lat_2per)\nx13,y13 = fig(two_lon_2per,two_lat_2per)\nx14,y14 = fig(three_lon_2per,three_lat_2per)\nx15,y15 = fig(four_lon_2per,four_lat_2per)\nx16,y16 = fig(five_lon_2per,five_lat_2per)\nx17,y17 = fig(final_lon_2per,final_lat_2per)\n\n#Add ultimate locations of MH370\nx18,y18 = fig(route1_lon_2per,route1_lat_2per)\nx19,y19 = fig(route2_lon_2per,route2_lat_2per)\nx20,y20 = fig(route3_lon_2per,route3_lat_2per)\nx21,y21 = fig(route4_lon_2per,route4_lat_2per)\n\n# plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Draw circle showing extent of Inmarsat sat radar detection for each of the pings\nfig.plot(x5,y5,'r--',markersize=5,label='1st Ping Arc')\nfig.plot(x6,y6,'r-',markersize=5, label='Ping Arcs After Disappearance')\nfig.plot(x7,y7,'r-',markersize=5)\nfig.plot(x8,y8,'r-',markersize=5)\nfig.plot(x9,y9,'r-',markersize=5)\nfig.plot(x10,y10,'r-',markersize=5)\nfig.plot(x11,y11,'r-',markersize=5)\n\n#Add monte carlo points\nfig.plot(x12,y12,'yo',markersize=5,label='after 1 hrs')\nfig.plot(x13,y13,'mo',markersize=5,label= 'after 2 hrs')\nfig.plot(x14,y14,'wo',markersize=5,label='after 3 hrs')\nfig.plot(x15,y15,'bo',markersize=5,label='after 4 hrs')\nfig.plot(x16,y16,'go',markersize=5,label='after 5 hrs')\nfig.plot(x17,y17,'ro',markersize=7,label='after 6 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x18,y18,'bo',markersize=5,label='in final hr')\nfig.plot(x19,y19,'bo',markersize=5)\nfig.plot(x20,y20,'bo',markersize=5)\nfig.plot(x21,y21,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('Inmarsat Ping Estimation -- Individual Pings', fontsize=30)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Okay, so the wrapped cauchy results are worth an addition comment here: with all of the pings we do see some propensity for the MH370 to switch directions midway, and go back to the north when it goes to the south; so the plane does wind up in a variety of places on the last ping arc (what used to be called the 5th ping, and is now the 6th ping.) *However*, note that in the slight majority of cases, MH370 winds up to the south instead of the north (you can judge this by the blue dots, and the red dots to some extent.) So even under whacky unit circle heading distribution choices the plane still winds up to the south more than the nort.h" }, { "cell_type": "heading", "level": 2, "metadata": {}, "source": "Overall Conclusions from Monte Carlo Modeling MH370's Last Flight" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "What I've also plotted in these final versions of the model is a Great Circle line (using Basemap's built-in function, with a default of 100 pts created to make the line) of the Palau Perak coordinates -- MH370's final location -- to 40 S, 85 E, which in all of my 6 hop simulations was the arc location where the plane wound up near." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Arguably the most stringent scenario for the plane moving west, is the wrapped cauchy at k=0.99 distribution, with a 2.5% standard deviation error for the ping probability distributions. We see that the plane only *really* starts to move to the west when the last heading dictates up to 1 hr's flight after the last ping; which after the wrapped cauchy condition ends. (Recall the last step takes the last heading and projects it out up to 1 hr, in increments of 1/4, 1/2, 3/4, and 59/60 hrs.)" }, { "cell_type": "code", "collapsed": false, "input": "#Set figure size\nfig = plt.figure(figsize=[30,20])\n\n#Setup Basemap\nfig = Basemap(width=10000000,height=18000000,projection='lcc',resolution='c',lat_0=10,lon_0=90,suppress_ticks=True)\n\n#Draw coasts\nfig.drawcoastlines()\n\n#Draw boundary\nfig.drawmapboundary(fill_color='lightblue')\n\n#Fill background\nfig.fillcontinents(color='#FFD39B',lake_color='lightblue')\n\n#Draw parallels\nparallels = np.arange(lat_min,lat_max,lat_space)\nfig.drawparallels(np.arange(lat_min,lat_max,lat_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw meridians\nmeridians = np.arange(lon_min,lon_max,lon_space)\nfig.drawmeridians(np.arange(lon_min,lon_max,lon_space),labels=[1,1,0,1], fontsize=15)\n\n#Draw great circle to show path autopilot would have taken\nfig.drawgreatcircle(pulauperak[1],pulauperak[0],85,-40,linewidth=3,color='black',label='Great Circle Path')\n\n#Translate coords into map coord system to plot\n\n#Known 777 Locs\nx,y = fig(kualalumpur[1],kualalumpur[0]) #plotted as lon,lat NOT lat,lon -- watch out!!\nx2,y2 = fig(igariwaypoint[1],igariwaypoint[0])\nx3,y3 = fig(pulauperak[1],pulauperak[0])\n\n#Inmarsat Satellite Loc\nx4,y4 = fig(inmarsat[1],inmarsat[0])\n\n#Add circle coords -- these are for each ping. will not plot the 2.5 and 5% error\nx5,y5 = fig(circle_lon_211am,circle_lat_211am)\nx6,y6 = fig(circle_lon_311am,circle_lat_311am)\nx7,y7 = fig(circle_lon_411am,circle_lat_411am)\nx8,y8 = fig(circle_lon_511am,circle_lat_511am)\nx9,y9 = fig(circle_lon_611am,circle_lat_611am)\nx10,y10 = fig(circle_lon_711am,circle_lat_711am)\nx11,y11 = fig(circle_lon_811am,circle_lat_811am)\n\n#Add points after each hr\nx12,y12 = fig(first_lon_2per,first_lat_2per)\nx13,y13 = fig(two_lon_2per,two_lat_2per)\nx14,y14 = fig(three_lon_2per,three_lat_2per)\nx15,y15 = fig(four_lon_2per,four_lat_2per)\nx16,y16 = fig(five_lon_2per,five_lat_2per)\nx17,y17 = fig(final_lon_2per,final_lat_2per)\n\n#Add ultimate locations of MH370\nx18,y18 = fig(route1_lon_2per,route1_lat_2per)\nx19,y19 = fig(route2_lon_2per,route2_lat_2per)\nx20,y20 = fig(route3_lon_2per,route3_lat_2per)\nx21,y21 = fig(route4_lon_2per,route4_lat_2per)\n\n# plot coords w/ filled circles\nfig.plot(x,y,'bo',markersize=10,label='MH370 Flight Path')\nfig.plot(x2,y2,'bo',markersize=10)\nfig.plot(x3,y3,'go',markersize=10,label='MH370 Last Known Coords')\nfig.plot(x4,y4,'ro',markersize=10,label='Inmarsat 3-F1')\n\n#Draw circle showing extent of Inmarsat sat radar detection for each of the pings\nfig.plot(x5,y5,'r--',markersize=5,label='1st Ping Arc')\nfig.plot(x6,y6,'r-',markersize=5, label='Ping Arcs After Disappearance')\nfig.plot(x7,y7,'r-',markersize=5)\nfig.plot(x8,y8,'r-',markersize=5)\nfig.plot(x9,y9,'r-',markersize=5)\nfig.plot(x10,y10,'r-',markersize=5)\nfig.plot(x11,y11,'r-',markersize=5)\n\n#Add monte carlo points\nfig.plot(x12,y12,'yo',markersize=5,label='after 1 hrs')\nfig.plot(x13,y13,'mo',markersize=5,label= 'after 2 hrs')\nfig.plot(x14,y14,'wo',markersize=5,label='after 3 hrs')\nfig.plot(x15,y15,'bo',markersize=5,label='after 4 hrs')\nfig.plot(x16,y16,'go',markersize=5,label='after 5 hrs')\nfig.plot(x17,y17,'ro',markersize=7,label='after 6 hrs')\n\n#Plot ultimate locations of MH370\nfig.plot(x18,y18,'bo',markersize=5,label='in final hr')\nfig.plot(x19,y19,'bo',markersize=5)\nfig.plot(x20,y20,'bo',markersize=5)\nfig.plot(x21,y21,'bo',markersize=5)\n\n#Draw arrows showing flight path\narrow1 = plt.arrow(x,y,x2-x,y2-y,linewidth=3,color='blue',linestyle='dashed',label='flight path')\narrow2 = plt.arrow(x2,y2,x3-x2,y3-y2,linewidth=3,color='blue',linestyle='dashed',label='flight path')\n\n#Make legend\nlegend = plt.legend(loc='upper right',fontsize=10,frameon=True,title='Legend',markerscale=1,prop={'size':15})\nlegend.get_title().set_fontsize('20')\n\n#Add title\nplt.title('Great Circle Path on Most Stringent Scenario to Constrain Moving West', fontsize=15)\n\n#Show below\nplt.show()", "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Monte Carlo with Constraints and \"Priors\" is Better Than Cherry-Picking Flight Paths" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Here's an important point which hasn't been brought up by the media much -- at the present time of this writing, NTSB has provided 2 possible paths. Here are those same 2, and then 2 by Malayia. Why 2? Surely, putting your eggs in 2 baskets is better than 1, to resurrect this cliche. But what a Monte Carlo model can do is put your eggs in thousands of baskets (I have run 1000 for now, but could reduce the dot size on the plot and increase to 10000 trials, which would take an overnight to run given the number of permutations and the fact that I haven't vectorized my code and the main functions have double 'for' loops which is O(n^2) complexity). Then, from there, you can establish from this data what you think the most likely scenarios are -- either by taking an average if you think error is normally distributed (like Galton's Ox), *or* by making assumptions (\"priors\", but from an informal sense as opposed to a strict Bayesian calculation included in the simulation, which I have not had time to implement) which would rule out a good fraction of the plotted locations. So you get a much better idea of where the plane is most likely to be, instead of trying to cherry pick what you think is possible in advance. It's a more scientific approach for how you go about searching for the plane." }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "MH370 Location *Is* Sensitive to Heading" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "I show this through picking uniform like distributions, and Wrapped Cauchy at k=0.99 which is almost a point; yet we see scattered results. However, the ~255 degree heading is, to the best of my knowledge, the last known heading we have for MH370." }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "MH370 is Likely Off Australia, Still, 5 or 6 Pings Regardless" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "MH370 is likely off the coast of Australia, in the general vicinity of where searches have been taken place over the past week (and starting right around the time when I finished the first version of my model, without that information). I initially thought it was further north -- when I assumed 5 pings (or, equivalently, 6 pings with a 5/6 cruising speed, or ~750 km/hr instead of 905 km/hr cruising speed). Those simulations are all still valid, but would involve a lower speed for the plane than a 777's cruising speed (which *is* possible, but I haven't seen evidence suggesting this is the case.) " }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "The blue dot locations in the scenarios that involve a limited standard devation or high k value is where additional search effort (particularly trolling with ships with a black box ping detector) should be concentrated for the next two weeks. And even after this, scanning the seafloor for MH370. 777s *are* big, so although the ocean is big they should see it with the proper equipment if they're in the vicinity at the sea surface." }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "Disagree? Choose-Your-Own-Adventure Features Enabled" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "This code is written such that if better speed parameters, or more accurate ping information in released or uncovered, the prediction of where MH370 is most likely to be, can be updated accordingly with minimal effort. I've documented the code and made it available for precisely this purpose. And I *will* point out bugs and errors I find, etc., whether or not they affect the analysis. As I have done in the past." }, { "cell_type": "heading", "level": 3, "metadata": {}, "source": "MH370 Could Not Have Flown a Great Circle Route or via Magnetic Bearing -- Autopilot Ruled Out?" }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "Finally, based on the most charitable scenario of the many simulations I ran, with the ping locations inherently constrained by the 1st and last ping, I show almost no possible route to the south that MH370 takes, satisfies a Great Circle requirement for auto pilot (it could appear to, up to 4 hours, which might be accomplished if MH370 is going *really* slow, but there are 2+ unexplained hours left). If you look closely at the above paths, if I ran 10k or 100k trials there's a chance some *might* work but this is an exceedingly low probability. So, from a Monte Carlo standpoint, is not a likely conclusion." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "If the plane continued to fly southwest, and then deviated -- then the Great Circle path seems even more unlikely to reconcile with the pings, with the most likely locations of MH370 according to my model results. Furthermore, autopilot and a \"ghost flight\" scenario like Helios Airways Flight 522 from Cyprus to Greece in 2005, would be unlikely to vary the speed in between pings if on autopilot. And so far it seems like regardless of whether you move the pings in irregular time intervals, there isn't enough variance from that to account for straight Great Circle path scenarios." }, { "cell_type": "heading", "level": 4, "metadata": {}, "source": "MH370's drifting with the pings over time seems to be an inevitable consequence of the geometry of the ping arc constraints. I am not sure how to reconcile this, except that it would mean that one of the points along that route was programmed into the flight management system, or the plane was flown manually. Therefore, I conclude based on my Monte Carlo modeling and analysis that whereever MH370 may be...*someone* wanted it there." } ], "metadata": {} } ] }