{"action":"created","comment":{"url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/pulls/comments/69483579","id":69483579,"diff_hunk":"@@ -0,0 +1,768 @@\n+:author: Ben Lasscock\n+:email: blasscoc@gmail.com\n+:institution: Geotrace Technologies\n+\n+-------------------------------------\n+Generalized earthquake classification\n+-------------------------------------\n+\n+.. class:: abstract\n+\n+\t   \n+   The problem we tackle in the is paper is one of characterizing the\n+   source of an earthquake based on identifying the nodal lines of\n+   the radiation pattern it produces. These characteristics are the\n+   mode of failure of the rock (shear or tensile), the orientation of\n+   the fault plane and direction of slip. We will also extend the\n+   derive a correlation coefficient that can be used to compare the\n+   source mechanisms of different earthquakes.  This information is\n+   relevant to both hazard and commercial seismic monitoring.  We will\n+   formulate this problem in terms of a simple binary classification\n+   on the surface of the sphere, where the classes are the polarity of\n+   the first motion at observed various seismic stations, and the\n+   separating hyper-plane is the solution for nodal lines of the\n+   radiation pattern. Our design goal was to derive an algorithm that\n+   would be both robust to misclassification of the polarity data and\n+   suitable for online processing. We will then go on to derive a\n+   mapping which translates the learned solution for the separating\n+   hyper-plane back to the physics of the problem, that is, the\n+   probable source type and orientation. For reproducibility, we will\n+   demonstrate our algorithm using the example data provided with the\n+   HASH earthquake classification software, which is available online.\n+\n+.. class:: keywords\n+\n+   machine learning, earthquake, hazard, classification.\n+\n+Introduction\n+------------\n+\n+In this paper we are going to explain how to classify earthquake data\n+using a support vector classifier (SVC) and then how to interpret the\n+result physically. We will be drawing on the scikits-learn [sklearn]_\n+project for the SVC, the Obspy seismological Python package for some\n+utility routines and mplstereonet [#]_, which is a matplotlib [mpl]_\n+plugin for visualization.\n+\n+.. [#] https://pypi.python.org/pypi/mplstereonet\n+\n+Much of the discussion will center around deriving a mapping from the\n+solution of the SVC to the spectral content of the earthquake source\n+mechanism. The key concept we will be elaborating on is understanding\n+the relationship between what we call input and feature spaces of the\n+SVC. The results of the classification are curves separating points on\n+the surface of the focal sphere (the input space), which is the domain\n+of the input data.  However, the physics and understanding of the\n+result lies in the representation of the solution in the feature\n+space, which is the higher dimensional space where the classifier\n+solves the classification problem.\n+\n+For the sake of reproducibility, the demonstration will use the same\n+dataset provided with the the US Geological Survey (USGS) HASH\n+software [#]_. HASH [HASH]_ is an earthquake classification code\n+provided by the USGS, it is built upon an earlier package called\n+FPFIT, which implements a least squares classifier. For each case we\n+will be comparing, and contrasting our solutions with those generated\n+by HASH which we generally expect to be very similar.  This will also\n+give us an opportunity to contrast least squares classification\n+[HASH]_ with kernel methods (SVC), with a discussion about robustness\n+of the solution misclassification of the data.\n+\n+.. [#] http://earthquake.usgs.gov/research/software/index.php\n+\n+\n+.. figure:: seismogram-wr1.png\n+\t    \t   \n+   A seismogram measured at the WR1 node of the Warramunga seismic array\n+   showing displacement due to an aftershock of the April 2007 Solomon\n+   Islands earthquake. The red dot indicates the first break motion.\n+   The data was obtained by querying the IRIS database \n+   http://ds.iris.edu/ds/nodes/dmc/data/types/events/. :label:`seismogram`\n+   \n+.. figure:: WR1.png\n+\t    \t   \n+   A portion of the Australian seismic network showing the location\n+   of the Warramunga seismic array, the map was obtained from\n+   http://www.fdsn.org/networks/detail/AU/. :label:`WR1.png`\n+\n+Consider a particular example where we would apply the analysis\n+presented in this paper. In Fig. :ref:`seismogram`, we show a\n+seismogram (recording) of an earthquake that was located in Solomon\n+Islands.  The recording shown was made by the WR1 node of the\n+Warramunga seismic array, which is part of the Australian seismic\n+network, shown partially in Fig. :ref:`WR1.png`. The goal of hazard\n+monitoring in this case would be to characterize the deformation of\n+the earth (focal mechanism) that caused this earthquake. The analysis\n+would involve first locating the source spatially and then classifying\n+its focal mechanism, and importantly the orientation of the fault\n+plane. The orientation of the fault plan is important because\n+displacement of the sea-floor can cause Tsunami. The algorithm\n+discussed in this paper provides the analysis of the focal mechanism,\n+with the extension that we can also compare the spectrum of the\n+solution with a past events located in this area. This additional\n+information maybe useful for decision making regarding what action\n+should be taken given the risk of a historical (or perhaps modeled)\n+scenario repeating.\n+\n+Our discussion will include annotated software explaining important\n+steps in the computation.  And will be contributing software [#]_ to\n+estimate solutions for fault plane orientation, and a correlation\n+coefficients.\n+\n+.. [#] https://github.com/blasscoc/FocalMechClassifier\n+\n+Problem statement\n+-----------------\n+\n+We proceed by detailing exactly the parameters of the problem at hand.\n+The raw data are observations the initial arrival of energy from this\n+earthquake, which is a compressional \"P-wave\". The first motion\n+(initial displacement) recorded at this station is identified (or\n+picked) as shown by a red dot in Fig. :ref:`WR1.png`. Consider this is\n+as a radiation amplitude from the earthquake measured at a particular\n+location. Further measurements across the seismic network begin to\n+inform the shape of the radiation pattern created by the\n+event. However, a radiation pattern measured far from the event\n+becomes distorted because of the refraction of the seismic wave as it\n+propagates through the earth.  To remove this distortion, this energy\n+must migrated back to the neighborhood of the estimated source\n+location. We call this neighborhood the focal sphere. The process of\n+picking and locating seismic events is beyond the scope of this\n+paper. However, seismograms can be requested from the IRIS database\n+[#]_ and a suit of Python tools for processing this data is made\n+available by the Obspy [#]_ Python project.\n+\n+.. [#] http://www.iris.edu\n+.. [#] https://www.obspy.org/\n+.. [#] See scipy.special.sph_harm\n+\n+The input data to our analysis is the polarity (signed amplitude) of\n+the pick, and the azimuth and co-latitude of the observation migrated\n+onto the focal sphere.The design goal is to provide an online tool for\n+characterizing the source mechanism. The emphasis is on robustness of\n+the algorithm, without the need for post facto processing of the\n+data. We also need a system that provides natural metrics of\n+similarity between seismic events. \n+\n+Since we are dealing with the compressional waves in the earth, we\n+expect that an observed radiation pattern should be related to the\n+eigenfunctions of the scalar wave-equation, the spherical harmonic\n+functions [#]_, hence the polarity data should be classified by the\n+signed amplitude of a superposition of these functions. We will learn\n+this classifying function using the SVC. However, it is the spectral\n+representation of the radiation pattern contains the physical meaning\n+of the solution.  The spectral content of the source mechanism also\n+provides for metrics of similarity. Note that, this line of reasoning\n+leads us down a somewhat different than the usual method of analysis\n+based on the moment tensor, see [Aki02]_.\n+\n+In Sec.`Theory` we will review the basic results we need from the\n+theory of seismic sources. Then in Sec. `Existing least squares\n+methods` we will existing methods for classifying earthquake data.\n+The Sec. `Earthquake - Learning with Kernels` reviews the Python code\n+used in the classification, and derives a mapping between the input\n+space of the problem, to the feature space (represented by the\n+spectrum). In Sec. `Physical Interpretation` we translate this\n+spectral representation back to the physics of the problem, and explain\n+how to evaluate the correlation metric. The Sec. `Discussion` we provide\n+an example of the analysis and then we wrap things up with\n+our conclusions Sec. `Conclusions`.\n+\n+\n+       \n+Theory\n+------\n+\n+.. raw:: latex\n+ \n+   \\begin{table}\n+   \\begin{tabular} {ccc}\n+   Source & (Fault normal/slip) & Template \\cr\n+   \\hline\n+   D.C. &\n+   (31) + (13) & $-i(Y_{12} + Y_{-12})$\\cr\n+\tTensile & \n+\t(3) & $\\alpha Y_{00} + 4\\sqrt{5} Y_{02}$\\cr\n+   Tangential & \n+   (3) & $Y_{02} - \\frac{i}{2}(Y_{22} + Y_{-22})$\\ .\n+   \\end{tabular}\n+\n+   \\caption{Describes the angular variation of the displacement due to\n+   three types of earthquake sources in terms of a basis of spherical\n+   harmonic functions.  The source templates summarized are shear,\n+   tensile and tangential dislocation.  The brackets $(\\cdot,\\cdot)$\n+   define the template direction of the fault normal and the direction of\n+   slip in rectangular coordinates.  The constant $\\alpha = 2 +\n+   3\\frac{\\lambda}{\\mu}$, where $\\lambda$ and $\\mu$ are the first Lame\n+   parameter and the shear modulus respectively.}\n+   \n+   \\end{table}\n+\n+The observed displacement created by the collective motion of\n+particles along a fault plane is described by the theory of seismic\n+sources. We will not go into all the details here, but the reference\n+on seismic source theory we follow is Ben-Menahem and Singh\n+[Ben81]_. The key result we will draw upon is a formula for the\n+displacement for various types of seismic sources summarized in Table\n+4.4 of [Ben81]_, which is presented in terms of Hansen vectors.\n+Physically, a shear type failure would represent the slip of rock\n+along the fault plane, a tensile failure would represent cracking of\n+the rock.  The results of [Ben81]_ are general, however we are only\n+modeling the angular variation of the displacement due to the\n+compressional wave measured radially to the focal sphere. From this\n+simplification we can translate solutions of [Ben81]_ into solutions\n+for just the angular variation, in a basis of spherical harmonic\n+functions, which we tabulate in Table 1, notes on translating between\n+[Ben81]_ and Table 1 are summarized in the Appendix `Appendix`. This\n+result gives us an analytical expression for the spectral content of\n+seismic sources given a certain orientation of the fault plane. We\n+will use this information to find general solutions in Sec. `Physical\n+Interpretation`.\n+\n+The amplitude of the radiation pattern cannot typically be migrated\n+back to the location of the event unless an accurate model of seismic\n+attenuation is available, which is not generally the case, even in\n+commercial applications. However, supposing the source type and\n+orientation were known, then the sign of this radiation pattern is a\n+function that must classify the polarity data on the focal sphere. As\n+an example, in Fig. :ref:`beachballs` we render in, 3-dimensions, the\n+signed radiation pattern predicted for shear and tensile source, in a\n+particular orientation.\n+\n+\n+.. figure:: beachball.png\n+\t    \t   \n+   Rendered in 3-dimensions, (left) the signed radiation pattern for\n+   a possible tensile type source. (right) Similarly for the case of\n+   shear type source. Figures are generated using Scipy sph_harm and\n+   Mayavi. :label:`beachballs`\n+\n+The black areas of this beachball diagram represents the region where\n+the displacement at the source is radially outward (vice versa for the\n+white regions). The nodal lines represent the separating margin\n+between classes of data (outward and inward displacement). For the\n+shear source, the nodal lines represent the fault and auxiliary planes\n+respectively.\n+\n+One observation we can immediately take away from Fig\n+:ref:`beachballs` is that two diagrams are topologically\n+different. The nodal lines of the shear source are great circles,\n+which is not the case from the tensile source. That means there is no\n+rotation or smooth deformation that can make one look like the other.\n+This suggests that the two source are distinguishable, but also\n+that there is some potential from identifying admixtures of the two\n+based on their spectral content. \n+\n+\n+Existing least squares methods\n+------------------------------\n+\n+.. figure:: ball_of_yarn.png\n+\t \n+   For event 3146815 from north1 dataset (blue) preferred nodal line estimated\n+   by HASH, (red) a sample from the set of acceptable estimates. :label:`yarn`\n+\n+Currently, a common method (called FPFIT [FPFIT]_) for earthquake\n+classification is to assume that shear failure is the source\n+mechanism, and then, through a least squares optimization, find the\n+fault plane orientation that minimizes the rate of misclassification\n+to the data. A modern code built upon FPFIT is the HASH algorithm\n+[HASH]_. The HASH software is available for download from the USGS\n+[#]_ website. The HASH software comes with an example \"NorthRidge\"\n+dataset which we will use to demonstrate our method. We compare the\n+results of our algorithm with the results of HASH, which is the\n+current state of the art. Hashpy is a Python project for wrappering\n+HASH [#]_.\n+\n+.. [#] http://earthquake.usgs.gov/research/software/index.php\n+.. [#] HashPy https://github.com/markcwill/hashpy.\n+\n+Figure :ref:`yarn` demonstrates how the FPFIT algorithm works.  The\n+coordinate system in the figure is a stereonet projection [#]_ of the\n+lower half space of a sphere. The solid red (open blue) dots are\n+outward (inward) polarity measured across a seismic network for the\n+3146815 event, which was taken from the Northridge dataset\n+\"north1.phase\" supplied with the HASH software. Recall, FPFIT is a\n+least squares method, however the function it is optimizing need not be\n+particularly convex. As such, there are many solutions that have a\n+similar goodness of fit.  Using a grid search method, FPFIT draws a\n+ensemble of these possible solutions for the fault orientation. The\n+red lines are the fault (and auxiliary) planes for each solution. The\n+blue line preferred or most likely solution. In some cases the cost\n+function optimized by FPFIT can become multi-modal, which leads to\n+instability in the solution. An example of this kind of instability is\n+discussed in [HASH], which shows an example where misclassifying\n+single polarity data radically changes the solution.\n+\n+.. [#] Stereonet project code provided by https://pypi.python.org/pypi/mplstereonet\n+\n+Earthquake - Learning with Kernels\n+----------------------------------\n+:label:`kernels`\n+   \n+.. figure:: svm_schematic.png\n+\t    \t   \n+   A schematic of the optimization strategy of the SVC.\n+   The dashed lines represent the edges of the separating margin. The blue open and\n+   red closed dots are the polarity data represented in a feature space.\n+   The dashed lines represent a separating margin between the two classes, the solid\n+   line represents the optimal separating hyper-plane. :label:`svc`\n+\n+In this section we discuss the classification algorithm used, and the application\n+of the Python scikits-learn. Whilst our interest was classification of earthquakes,\n+the algorithm is applicable for any classification problem defined on a sphere.\n+\n+Define the input space of the problem as the surface of the focal sphere, represented\n+for example by the stereonet in Fig. :ref:`yarn`. The data is not linearly separable\n+on this space. The strategy of the SVC is to project the problem\n+into a higher dimensional feature space. And in this feature space, determine the\n+best hyper-plane to separate the two classes of data by maximizing the width of the\n+separating margin, subject to the constraint that the classes are either side of the\n+separating margin, Fig. :ref:`svc` shows a schematic of the algorithm.\n+\n+.. code-block:: python\n+\n+   from sklearn import svm\n+\n+   def classify(cartesian_coords, polarity,\n+                                kernel_degree=2):\n+       \"\"\"\n+       cartesian_coords - x, y, z coordinates on\n+       sphere polarity (1,-1) first break polarity\n+       kernel_degree - truncates the dimension of\n+       expansion.\n+       \"\"\"\n+\n+       # C : slack variable, use the default of 1.0\n+       poly_svc = svm.SVC(kernel='poly',\n+            degree=kernel_degree,\n+            coef0=1, C=1.0).fit(cartesian_coords,\n+\t                        polarity)\n+\t\t\t\t\n+       intercept = poly_svc.intercept_\n+       # Angle [0,pi] - the colatitude\n+       colat = arccos(poly_svc.support_vectors_[:,2])\n+       # Angle [0,2*pi] measured as azimuth\n+       azim = arctan2(poly_svc.support_vectors_[:,1],\n+\t\t      poly_svc.support_vectors_[:,0])\n+       # The lagrange multipliers * class,\n+       # classes are labeled -1 or 1.\n+       dual_coeff = poly_svc.dual_coef_[0,:]\n+       # Remember which points where mis-classified \n+       in_sample = poly_svc.predict(c_[inputs])\n+\n+       return (dual_coeff, azim, colat,\n+\t\t    intercept, in_sample)\n+\n+A Python implementation of the support vector classifier is included in the\n+scikits-learn machine learning suite of codes. The projection to a higher\n+dimensional space is done using a kernel, and evaluated in the input space\n+using the kernel trick. For classification on a sphere, we need to use an\n+inner product kernel, which has the form\n+\n+.. math::\n+   :type: equation\n+\n+   k(\\vec{x},\\vec{x}_{i}) = (\\langle \\vec{x}, \\vec{x}_{i} \\rangle + 1)^{d}\\ .\n+\t \n+Here \"d\" is the degree of the kernel. The parameter \"C\" in the above code\n+snippet is a slack variable. This allows for a soft thresholding, which allows\n+for some misclassification; the default value is usually sufficient.\n+   \n+.. raw:: latex\n+\n+   Given a set of data $y_{i}$, which is either 1 or -1, the support\n+   vector machine learns a corresponding set of coefficients\n+   $\\alpha_{i}$ and intercept $\\beta_{0}$, which determines a classifying function\n+   in the input space,\n+   \\begin{equation}\n+   f(\\vec{x}) = \\sum_{i=1}^{N} \\alpha_{i}y_{i}k(\\vec{x},\\vec{x}_{i}) + \\beta_{0}\\ .\n+   \\end{equation}\n+   In our application, the zero of this function is the nodal line, and the sign\n+   of the function is a prediction for the the direction of the displacement\n+   radial to the focal sphere, given the observed data.\n+   Not all of the data is relevant for determining the best separating\n+   margin, many of the coefficients $\\alpha_{i}$ maybe zero. The\n+   support vectors are the locations of the data where $\\alpha_{i}$\n+   are non-zero. The product $\\alpha_{i}y_{i}$ associated with each of the\n+   support vectors is called the dual coefficients (see the code snippet).\n+\t \n+.. figure:: class_3146815_example.png\n+\n+   For event 3146815 from north1 dataset (green) nodal line estimated\n+   by HASH, (red) nodal line estimated by SVC. :label:`class-example`\n+\n+In Fig. :ref:`class-example` we demonstrate the SVC classifier applied\n+to an event from the Northridge dataset. The red line represents zeros\n+of the classifying function f(x), the green line is the solution for the fault\n+(and auxiliary) planes determined by HASH. Note that the auxiliary\n+plane is computed using the aux_plane function provided by the Obspy\n+library. The learned nodal line is simply connected, the zeros of the\n+classifying function f(x) have been determined using matplotlib's contour\n+function.\n+\n+Both the HASH solution and the learned solution have a similar rate of\n+misclassification.  However the learned solution is still\n+unsatisfactory to us because we cannot make physical sense of the\n+result. What we want is an explanation of the type of source mechanism\n+and its orientation.  To be physically meaningful, we need an\n+expression for the nodal lines in terms of its spectrum in the basis of\n+spherical harmonic functions. In this basis we can then use the seismic\n+source theory of [Ben81]_ to relate the result to a physical process.\n+What we what is to determine the spectral content of f(x), \n+\n+.. math::\n+   :type: equation\n+\n+   f(\\vec{x}) = \\sum_{l=1}^{\\infty}\\sum_{m=-l}^{l} \\hat{f}_{lm}Y_{lm}(\\theta,\\psi)\n+\n+that is, we want to derive its representation in the feature space.\n+The steps in deriving this representation, are to first expand the inner\n+product kernel in terms of the Legendre polynomials [Scholkopf]_,\n+\n+.. raw:: latex\n+\n+   \\begin{equation}\n+   a_{l} = \\int_{-1}^{1}\\ dx\\ (x + 1)^{d} P_{l}(x)\n+   \\end{equation}\n+   \n+   \\begin{align*}\n+   a_{l} &=\n+   \\begin{cases}\n+   \\frac{2^{d+1}\\Gamma(d+1)}{\\Gamma(d+2+l)\\Gamma(d+1-l)} + \\frac{1}{2}\\sqrt{\\frac{1}{\\pi}}\\beta_{0}\\delta_{l0}  & \\text{if } l \\leq d \\\\\n+   0       & \\text{otherwise}\n+   \\end{cases}\\ .\n+   \\end{align*}\n+\n+When we do this, we see that the degree parameter provides a natural truncation on the complexity of the\n+function we are learning. This gives us the intermediate result which expresses the separating margin\n+in terms of Legendre polynomials of the inner product\n+\n+.. math::\n+   :type: equation\n+\n+   f(\\vec{x}) = \\sum_{i=1}^{N}\\alpha_{i}y_{i}\\sum_{l=1}^{\\infty}a_{l}P_{l}(\\langle \\vec{x}, \\vec{x}_{i} \\rangle)\\ .\n+\t \n+\n+The next step is to apply the addition theorem to express this in terms of the spherical harmonics,\n+\n+.. math::\n+   :type: equation\n+\n+    P_{l}(\\langle\\vec{x},\\vec{x}_{i}\\rangle) = \\sum_{m=-l}^{l} Y^{*}_{lm}(\\theta^{\\prime},\\psi^{\\prime})\\\n+                              Y_{lm}(\\theta,\\psi)\\ .\n+\n+The result is a formula for the spectral content of the focal mechanism given the dual coefficients\n+estimated by the support vector classifier,\n+\n+.. math::\n+   :type: equation\n+\t  \n+\t  \\hat{f}_{lm} = \\frac{4\\pi}{2l + 1}\\sum_{i=1}^{N}\\alpha_{i} y_{i} a_{l} \\\n+\t                         Y^{*}_{lm}(\\theta^{\\prime},\\psi^{\\prime})\\ .\n+\n+\n+Finally, suppose we have solutions for the classification from two different\n+sources, either observed or modeled from Table 1. A natural metric for\n+comparing the two sources is a correlation coefficient,\n+\n+.. math::\n+   :label: correl\n+   :type: equation\n+\t  \n+   \\rho = \\frac{\\Vert \\langle g, f\\rangle \\Vert}{\\Vert g\\Vert\\Vert f \\Vert}\\ .\n+\n+Using the orthogonality condition of the spherical harmonic functions,\n+we can show that inner product is,\n+\n+.. math::\n+   :type: eqnarray\n+   \n+   \\langle g, f\\rangle &=& \\int d^{3}x\\ g^{*}(\\vec{x}) \\  f(\\vec{x}) \\cr\n+                       &=& \\sum_{l=0}^{\\infty}\\sum_{m,n} \\hat{g}^{*}_{ln}\\hat{f}_{lm}\\ ,\n+\n+here the integral is over the surface of the focal sphere and the\n+star-notation means complex conjugation.  In the context of hazard\n+monitoring, we could use the as a metric of risk, without having to\n+propose a source mechanism or fault plane orientation, provided of\n+course we have a catalog of earthquakes that are of interest to us.\n+\n+Physical Interpretation\n+-----------------------\n+\n+In the previous section we derived the general earthquake\n+classification algorithm and a metric of correlation. Now suppose we\n+were to assume a model for the source mechanism (e.g shear failure),\n+how would we estimate the most likely orientation of the fault plane\n+in this model?\n+\n+First of all, in Table 1, we have a template for the spectral content\n+of the shear source for a particular direction of fault normal and slip\n+direction. Using this template we might compute a function g(x), and\n+then generate a rotation in the input space to realign the fault\n+plane. Note we will define rotations in terms of the Euler angles\n+(which we can relate to strike, dip and rake of the fault). Then\n+optimize the correlation with the classifying function learned by the\n+SVC, with respect to the Euler angles,\n+\n+.. math::\n+   :type: eqnarray\n+   \n+   \\langle g, f\\rangle &=& \\arg\\max_{\\alpha, \\beta, \\gamma}\\\n+   \\int d^{3}x\\ g^{*}(R(\\alpha, \\beta, \\gamma)\\vec{x}) \\  f(\\vec{x})\\  \\cr   \n+\n+Here, R represents are rotation matrix.  This would be a relatively\n+complicated procedure because we would need to re-evaluate the\n+function g(x) at each iteration of the optimization. It is far more\n+efficient to instead generate the rotations in the feature space. To\n+do this we borrow from quantum theory, and present Wigner's D-matrices,\n+\n+.. math::\n+   :type: eqnarray\n+\n+   g(R(\\alpha, \\beta, \\gamma)\\vec{x}) &=& \\sum_{l=0}^{\\infty}\\sum_{m,n}\\\n+                                     D^{l}_{mn}(\\alpha, \\beta, \\gamma) \\hat{g}_{ln}Y_{lm}(\\theta,\\psi)\\ .\n+\t\t\t\t     \n+.. code-block:: python\n+\t\t\n+   from scipy.optimize import minimize\n+       \n+   def _corr_shear(x, alm):\n+       strike, dip, rake = x\n+       # Wigner is ZYZ Euler rotation, \\gamma = -rake\n+       D = WignerD2(strike, dip, -rake).conjugate()\n+       # Template (13)/(31) : glm = (0, -1j, 0, -1j, 0)\n+       prop = (inner(D[:,3], alm) +\n+                      inner(D[:,1], alm))*1j\n+       # Maximize, not minimize.\n+       return -norm(prop)\n+       \n+   def corr_shear(Alm):\n+       # pick a good starting point.\n+       x0 = _scan_shear(alm)\n+       f = lambda x : _corr_shear(x,alm)\n+       results = minimize(f, x0=x0,\n+                bounds=((0,2*pi), (0,pi), (0,2*pi)))\n+       return rad2deg(results.x), results.fun\n+\n+The function corr_shear shown in the code snippet implements the\n+optimization of the above equation. The function WignerD2 implements\n+the Wigner-D matrices defined in [Morrison]_, the variable \"prop\" is\n+the projection of the learned solution onto the rotated template shear\n+solution shown in Table 1, and Alm are the quadrupole terms\n+from the learned spectral content of the source, we neglect the monopole\n+term because the shear mechanism has zero monopole content.\n+The initial guess is found scanning a coarse grid to find the best the\n+quadrant with the highest initial correlation. This stops the\n+Scipy's default minimization [scipy]_ getting stuck in a local minima.\n+\n+.. figure:: class_3146815_dc.png\n+\n+   For event 314681 from north1 dataset. (green) nodal line estimated by HASH,\n+   (red) optimal solution for the nodal lines derived from the SVC assuming a\n+   shear source. (red dashed) the nodal line estimated by the SVC. :label:`class-dc`\n+\n+As an example, in Fig. :ref:`class-dc` we show the classification results for the\n+3146815 event. The (dashed red) line shows the nodal line of the classifier function.\n+The (solid red) line is the template shear solution, orientated by optimizing\n+the correlation function, and the (solid green) line shows the preferred solution\n+estimated by HASH.  \n+\n+\n+Discussion\n+-----------\n+\n+In Figures :ref:`class-example` and :ref:`class-dc` we have show examples of the classification\n+and fault plane estimation methods. In this section we want to explore the robustness of the\n+algorithm and try to gain some insight into the correlation functions.\n+\n+.. figure:: class_3145744_norev.png\n+\n+\t    \n+   For event 3145744 from north1 dataset. The color scheme for each\n+   subplot as in Fig. :ref:`class-dc`, the dashed lines are solutions\n+   without the station reversal being applied. The black arrow points to\n+   datum for which the polarity is flipped. :label:`flipped`\n+\n+The HASH program has an input (scsn.reverse) which identifies stations\n+whose polarity was found to be erroneous in the past. These reversals\n+are applied post facto to correct the input polarity data.  We will\n+use this feature to demonstrate and example where the support vector\n+and least squares classifiers behaves very differently. In Fig\n+:ref:`flipped` we give an example comparing the results with (solid\n+lines) and without (dashed lines) the benefit of the polarity\n+correction. In this example, the polarity of a single station is\n+changed (highlighted by the black arrow). This point is very close to\n+the nodal line estimated by the SVC, which, given the soft\n+thresholding, is forgiving of misclassification along its separating\n+margin. The solution for the nodal line is largely unchanged. On the\n+other hand, the strategy of FPFIT is to minimize the overall rate of\n+misclassification. And indeed, in each case, it finds the optimal\n+solution on this basis. In fact, in terms of misclassified point,\n+FPFIT outperforms the SVC classifier. But we would question whether\n+minimizing the overall rate of misclassification is reasonable from an\n+applied perspective.  Consider that since the nodal line represents a\n+point where the radiation pattern is changing sign, we expect that the\n+signal to noise level will be smaller in this region.  Conversely,\n+from the point of view of the SVC, these are also the points that are\n+most informative to the proper location of its separating\n+margin. Indeed, many of the best quality picks far from the nodal\n+lines will not influence the solution for the separating plane (recall\n+dual coefficients can be zero). And it is reasonable that data of the\n+correct class located far from the separating margin should not\n+influence the solution. Looking at the problem from this perspective\n+the solution of the SVC is more reasonable.\n+\n+\n+.. figure:: correlation.png\n+\n+   The correlation score for each event in the Northridge dataset, comparing\n+   to event 3146815. (red) The events with maximum and minimum correlation score.\n+   (green) The correlation between 3146815 and itself rotated by 90-degrees strike,\n+   (cyan) the correlation between 3146815 and the tensile source found in\n+   Table 1. :label:`corr`\n+\n+Finally, we derived a metric of similarity based on a correlation\n+score Eq. :ref:`correl`.  To provide an example of how we might use\n+this correlation score, we take the event 3146815, which has the\n+largest number of data associate with it, and compute the correlation\n+coefficient with each of the other events in the Northridge\n+dataset. According to the reference [HASH]_ the Northridge dataset we\n+analyzing is expected to contain similar source mechanisms and\n+certainly we see that the correlation score is high for the majority\n+of the events. To test the sensitivity of the metric, we also compute\n+the correlation between event 3146815 and itself rotated by 90-degrees\n+strike, and we see that this has very low correlation, which we would\n+expect.\n+   \n+.. figure:: highlo.png\n+\n+   The color scheme for each subplot as in Fig. :ref:`class-dc`.\n+   (top left) The solution for event 3146815, (top right) the solution for\n+   events 3158361 and (bottom right) 3153955. Events 3158361 and 3153955\n+   represent the maximum and minimum correlation score\n+   with event 3146815. :label:`highlo`\n+\t    \n+In :ref:`highlo` we provide a visualization of the events with the\n+highest (top right) and lowest (bottom right) correlation score\n+comparing with event 3146815 (top left).  The orientation of the nodal\n+lines for event 3153955, which has the lowest correlation score,\n+indeed is qualitatively very different than solution for","path":"papers/ben_lasscock/00_blasscock.rst","position":650,"original_position":650,"commit_id":"e3c27343d49cbdd2ceece7a1ea1db1f726efbbb5","original_commit_id":"e3c27343d49cbdd2ceece7a1ea1db1f726efbbb5","user":{"login":"carsonfarmer","id":1220613,"avatar_url":"https://avatars.githubusercontent.com/u/1220613?v=3","gravatar_id":"","url":"https://api.github.com/users/carsonfarmer","html_url":"https://github.com/carsonfarmer","followers_url":"https://api.github.com/users/carsonfarmer/followers","following_url":"https://api.github.com/users/carsonfarmer/following{/other_user}","gists_url":"https://api.github.com/users/carsonfarmer/gists{/gist_id}","starred_url":"https://api.github.com/users/carsonfarmer/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/carsonfarmer/subscriptions","organizations_url":"https://api.github.com/users/carsonfarmer/orgs","repos_url":"https://api.github.com/users/carsonfarmer/repos","events_url":"https://api.github.com/users/carsonfarmer/events{/privacy}","received_events_url":"https://api.github.com/users/carsonfarmer/received_events","type":"User","site_admin":false},"body":"than the solution for","created_at":"2016-07-04T18:10:09Z","updated_at":"2016-07-04T18:10:09Z","html_url":"https://github.com/scipy-conference/scipy_proceedings/pull/201#discussion_r69483579","pull_request_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/pulls/201","_links":{"self":{"href":"https://api.github.com/repos/scipy-conference/scipy_proceedings/pulls/comments/69483579"},"html":{"href":"https://github.com/scipy-conference/scipy_proceedings/pull/201#discussion_r69483579"},"pull_request":{"href":"https://api.github.com/repos/scipy-conference/scipy_proceedings/pulls/201"}}},"pull_request":{"url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/pulls/201","id":71926557,"html_url":"https://github.com/scipy-conference/scipy_proceedings/pull/201","diff_url":"https://github.com/scipy-conference/scipy_proceedings/pull/201.diff","patch_url":"https://github.com/scipy-conference/scipy_proceedings/pull/201.patch","issue_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/issues/201","number":201,"state":"open","locked":false,"title":"Paper: Generalized earthquake classification","user":{"login":"blasscoc","id":5124575,"avatar_url":"https://avatars.githubusercontent.com/u/5124575?v=3","gravatar_id":"","url":"https://api.github.com/users/blasscoc","html_url":"https://github.com/blasscoc","followers_url":"https://api.github.com/users/blasscoc/followers","following_url":"https://api.github.com/users/blasscoc/following{/other_user}","gists_url":"https://api.github.com/users/blasscoc/gists{/gist_id}","starred_url":"https://api.github.com/users/blasscoc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/blasscoc/subscriptions","organizations_url":"https://api.github.com/users/blasscoc/orgs","repos_url":"https://api.github.com/users/blasscoc/repos","events_url":"https://api.github.com/users/blasscoc/events{/privacy}","received_events_url":"https://api.github.com/users/blasscoc/received_events","type":"User","site_admin":false},"body":"Hi Scipy 2016,\r\n\r\nThis is my submission of the conference proceedings. \r\n\r\nThe code that created each of the figures is available on:\r\nhttps://github.com/blasscoc/FocalMechClassifier\r\nunder the \"demo\" directory. Look for test[2-6].py, run these scripts from the demo directory.\r\n\r\nFor reproducibility, I've based the results on a dataset that is available with the USGS HASH software, \r\nhttp://earthquake.usgs.gov/research/software/HASH/hash.v1.2.tar.gz\r\nAnyone can get this code. \r\n\r\nBut I didn't want to start distributing their test data, so you'll have to download HASH and copy the north1.phase and scsn.reverse to the demo directory for the demos to run. \r\n\r\nThe version of sklearn I'm using is 0.17, which is the latest available from enpkg. You probably need to go get the Obspy code from their github, I'm using 1.0.1, the version on enpkg is way old.\r\n\r\nThanks\r\nBen Lasscock","created_at":"2016-05-30T17:51:43Z","updated_at":"2016-07-04T18:10:09Z","closed_at":null,"merged_at":null,"merge_commit_sha":"213d80080bac96c49df300a6bf3760d32bf9e672","assignee":null,"assignees":[],"milestone":null,"commits_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/pulls/201/commits","review_comments_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/pulls/201/comments","review_comment_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/pulls/comments{/number}","comments_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/issues/201/comments","statuses_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/statuses/e3c27343d49cbdd2ceece7a1ea1db1f726efbbb5","head":{"label":"blasscoc:2016","ref":"2016","sha":"e3c27343d49cbdd2ceece7a1ea1db1f726efbbb5","user":{"login":"blasscoc","id":5124575,"avatar_url":"https://avatars.githubusercontent.com/u/5124575?v=3","gravatar_id":"","url":"https://api.github.com/users/blasscoc","html_url":"https://github.com/blasscoc","followers_url":"https://api.github.com/users/blasscoc/followers","following_url":"https://api.github.com/users/blasscoc/following{/other_user}","gists_url":"https://api.github.com/users/blasscoc/gists{/gist_id}","starred_url":"https://api.github.com/users/blasscoc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/blasscoc/subscriptions","organizations_url":"https://api.github.com/users/blasscoc/orgs","repos_url":"https://api.github.com/users/blasscoc/repos","events_url":"https://api.github.com/users/blasscoc/events{/privacy}","received_events_url":"https://api.github.com/users/blasscoc/received_events","type":"User","site_admin":false},"repo":{"id":59970787,"name":"scipy_proceedings","full_name":"blasscoc/scipy_proceedings","owner":{"login":"blasscoc","id":5124575,"avatar_url":"https://avatars.githubusercontent.com/u/5124575?v=3","gravatar_id":"","url":"https://api.github.com/users/blasscoc","html_url":"https://github.com/blasscoc","followers_url":"https://api.github.com/users/blasscoc/followers","following_url":"https://api.github.com/users/blasscoc/following{/other_user}","gists_url":"https://api.github.com/users/blasscoc/gists{/gist_id}","starred_url":"https://api.github.com/users/blasscoc/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/blasscoc/subscriptions","organizations_url":"https://api.github.com/users/blasscoc/orgs","repos_url":"https://api.github.com/users/blasscoc/repos","events_url":"https://api.github.com/users/blasscoc/events{/privacy}","received_events_url":"https://api.github.com/users/blasscoc/received_events","type":"User","site_admin":false},"private":false,"html_url":"https://github.com/blasscoc/scipy_proceedings","description":"Tools used to generate the SciPy conference proceedings","fork":true,"url":"https://api.github.com/repos/blasscoc/scipy_proceedings","forks_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/forks","keys_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/keys{/key_id}","collaborators_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/teams","hooks_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/hooks","issue_events_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/issues/events{/number}","events_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/events","assignees_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/assignees{/user}","branches_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/branches{/branch}","tags_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/tags","blobs_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/git/refs{/sha}","trees_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/git/trees{/sha}","statuses_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/statuses/{sha}","languages_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/languages","stargazers_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/stargazers","contributors_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/contributors","subscribers_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/subscribers","subscription_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/subscription","commits_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/commits{/sha}","git_commits_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/git/commits{/sha}","comments_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/comments{/number}","issue_comment_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/issues/comments{/number}","contents_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/contents/{+path}","compare_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/compare/{base}...{head}","merges_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/merges","archive_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/downloads","issues_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/issues{/number}","pulls_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/pulls{/number}","milestones_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/milestones{/number}","notifications_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/labels{/name}","releases_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/releases{/id}","deployments_url":"https://api.github.com/repos/blasscoc/scipy_proceedings/deployments","created_at":"2016-05-30T00:57:45Z","updated_at":"2016-05-30T00:57:46Z","pushed_at":"2016-05-30T17:40:10Z","git_url":"git://github.com/blasscoc/scipy_proceedings.git","ssh_url":"git@github.com:blasscoc/scipy_proceedings.git","clone_url":"https://github.com/blasscoc/scipy_proceedings.git","svn_url":"https://github.com/blasscoc/scipy_proceedings","homepage":"","size":73163,"stargazers_count":0,"watchers_count":0,"language":"Python","has_issues":false,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":0,"mirror_url":null,"open_issues_count":0,"forks":0,"open_issues":0,"watchers":0,"default_branch":"master"}},"base":{"label":"scipy-conference:2016","ref":"2016","sha":"c91d1c88fe313a4503f92413cbdc879ecddf223a","user":{"login":"scipy-conference","id":4884274,"avatar_url":"https://avatars.githubusercontent.com/u/4884274?v=3","gravatar_id":"","url":"https://api.github.com/users/scipy-conference","html_url":"https://github.com/scipy-conference","followers_url":"https://api.github.com/users/scipy-conference/followers","following_url":"https://api.github.com/users/scipy-conference/following{/other_user}","gists_url":"https://api.github.com/users/scipy-conference/gists{/gist_id}","starred_url":"https://api.github.com/users/scipy-conference/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scipy-conference/subscriptions","organizations_url":"https://api.github.com/users/scipy-conference/orgs","repos_url":"https://api.github.com/users/scipy-conference/repos","events_url":"https://api.github.com/users/scipy-conference/events{/privacy}","received_events_url":"https://api.github.com/users/scipy-conference/received_events","type":"Organization","site_admin":false},"repo":{"id":1825629,"name":"scipy_proceedings","full_name":"scipy-conference/scipy_proceedings","owner":{"login":"scipy-conference","id":4884274,"avatar_url":"https://avatars.githubusercontent.com/u/4884274?v=3","gravatar_id":"","url":"https://api.github.com/users/scipy-conference","html_url":"https://github.com/scipy-conference","followers_url":"https://api.github.com/users/scipy-conference/followers","following_url":"https://api.github.com/users/scipy-conference/following{/other_user}","gists_url":"https://api.github.com/users/scipy-conference/gists{/gist_id}","starred_url":"https://api.github.com/users/scipy-conference/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/scipy-conference/subscriptions","organizations_url":"https://api.github.com/users/scipy-conference/orgs","repos_url":"https://api.github.com/users/scipy-conference/repos","events_url":"https://api.github.com/users/scipy-conference/events{/privacy}","received_events_url":"https://api.github.com/users/scipy-conference/received_events","type":"Organization","site_admin":false},"private":false,"html_url":"https://github.com/scipy-conference/scipy_proceedings","description":"Tools used to generate the SciPy conference proceedings","fork":false,"url":"https://api.github.com/repos/scipy-conference/scipy_proceedings","forks_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/forks","keys_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/keys{/key_id}","collaborators_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/collaborators{/collaborator}","teams_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/teams","hooks_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/hooks","issue_events_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/issues/events{/number}","events_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/events","assignees_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/assignees{/user}","branches_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/branches{/branch}","tags_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/tags","blobs_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/git/blobs{/sha}","git_tags_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/git/tags{/sha}","git_refs_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/git/refs{/sha}","trees_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/git/trees{/sha}","statuses_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/statuses/{sha}","languages_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/languages","stargazers_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/stargazers","contributors_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/contributors","subscribers_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/subscribers","subscription_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/subscription","commits_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/commits{/sha}","git_commits_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/git/commits{/sha}","comments_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/comments{/number}","issue_comment_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/issues/comments{/number}","contents_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/contents/{+path}","compare_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/compare/{base}...{head}","merges_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/merges","archive_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/{archive_format}{/ref}","downloads_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/downloads","issues_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/issues{/number}","pulls_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/pulls{/number}","milestones_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/milestones{/number}","notifications_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/notifications{?since,all,participating}","labels_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/labels{/name}","releases_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/releases{/id}","deployments_url":"https://api.github.com/repos/scipy-conference/scipy_proceedings/deployments","created_at":"2011-05-31T10:26:48Z","updated_at":"2016-07-03T17:28:56Z","pushed_at":"2016-07-04T18:06:54Z","git_url":"git://github.com/scipy-conference/scipy_proceedings.git","ssh_url":"git@github.com:scipy-conference/scipy_proceedings.git","clone_url":"https://github.com/scipy-conference/scipy_proceedings.git","svn_url":"https://github.com/scipy-conference/scipy_proceedings","homepage":"","size":219728,"stargazers_count":86,"watchers_count":86,"language":"Python","has_issues":true,"has_downloads":true,"has_wiki":true,"has_pages":false,"forks_count":171,"mirror_url":null,"open_issues_count":26,"forks":171,"open_issues":26,"watchers":86,"default_branch":"master"}},"_links":{"self":{"href":"https://api.github.com/repos/scipy-conference/scipy_proceedings/pulls/201"},"html":{"href":"https://github.com/scipy-conference/scipy_proceedings/pull/201"},"issue":{"href":"https://api.github.com/repos/scipy-conference/scipy_proceedings/issues/201"},"comments":{"href":"https://api.github.com/repos/scipy-conference/scipy_proceedings/issues/201/comments"},"review_comments":{"href":"https://api.github.com/repos/scipy-conference/scipy_proceedings/pulls/201/comments"},"review_comment":{"href":"https://api.github.com/repos/scipy-conference/scipy_proceedings/pulls/comments{/number}"},"commits":{"href":"https://api.github.com/repos/scipy-conference/scipy_proceedings/pulls/201/commits"},"statuses":{"href":"https://api.github.com/repos/scipy-conference/scipy_proceedings/statuses/e3c27343d49cbdd2ceece7a1ea1db1f726efbbb5"}}}}
{"actor":{"display_login":"carsonfarmer"}}