{
  "id": 63250,
  "title": "Solution #9",
  "url": "/competitions/trackml-particle-identification/discussion/63250",
  "author_name": "CPMP",
  "post_date": "2018-08-14T01:27:51.738000",
  "votes": 42,
  "comment_count": 67,
  "views": 0,
  "content": "<p>Did I disclose I have been using DBSCAN?  Well, now you know ;)  </p>\n\n<p>My approach is quite straightforward and has been almost fully disclosed by @yuval.  An helix that starts from z axis can be described by 4 parameters:</p>\n\n<ul>\n<li>z at origin <code>z0</code></li>\n<li>radius <code>r0</code></li>\n<li>angle at origin in transverse plane (x,y plane) <code>phi0</code></li>\n<li>slope <code>zr</code></li>\n</ul>\n\n<p>The last 3 can be expressed as functions of the momentum at origin, <code>px</code>, <code>py</code>, <code>pz</code>, and <code>pt = sqrt(px² + py²)</code>:</p>\n\n<ul>\n<li><code>r0 = C * pt</code></li>\n<li><code>phi0 = arctan(py/px)</code></li>\n<li><code>zr = pz/pt</code></li>\n</ul>\n\n<p>The formula to compute <code>C</code> is given in the documents from CERN but I estimated it from the train data via a linear regression. That's the only use of supervised learning I made ;)</p>\n\n<p>My code loops over <code>z0, r0</code> pairs.  Rather than estimating a distribution I just sample from the tracks in the first 100 train samples.  For each pair I 'unroll the helix', i.e. compute <code>phi0</code> and <code>zr</code> as:</p>\n\n<pre><code>phi0 = phi +- theta0\nzr =  (z - z0) / (2 * r0 * theta0)\n</code></pre>\n\n<p>where <code>rt</code> is the distance to origin in transverse plane, <code>phi</code> the angle in transverse plane, and <code>theta0</code> is the unrolling angle:</p>\n\n<pre><code>rt = sqrt(x² + y²)\nphi = arctan(y/x)\ntheta0 = arcsin(rt / (2 * r0))\n</code></pre>\n\n<p>In one iteration I add <code>theta0</code> to <code>phi</code>, and in the next iteration I subtract it.</p>\n\n<p>In order to cope with the discontinuity at <code>pi</code> and <code>-pi</code> I use <code>cos(phi0)</code> and <code>sin(phi0)</code>.  </p>\n\n<p>The distribution of <code>zr</code> is highly skewed.  Many have use <code>arctan</code> to unskew it, but I found that using <code>arcsinh</code> was way more effective.  I actually use:</p>\n\n<pre><code>arcsinh(zr / 0.7) / 3.5\n</code></pre>\n\n<p>The picture below gives the distribution of arctan(zr), and the one below the distribution of arcsinh. The latter is way more uniform.</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10056/atan1.png\" alt=\"arctan distribution\"></p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10055/asinh.png\" alt=\"arcsinh distribution\"></p>\n\n<p>The last twist is to model the uneven magnetic field at high values of <code>z</code>.  The picture below shows the relative difference between the theoretical angle, and the median of measured angle as a function of <code>z</code>, the picture below gives the number of hits in log scale:</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10052/ratio1.png\" alt=\"ratio1\"></p>\n\n<p>The best way I found was to multiply <code>theta0</code> with a correction that depends on <code>z</code>:</p>\n\n<pre><code>1.005 - (abs(z + 200) / 6000)**2.4\n</code></pre>\n\n<p>The picture below shows a smoothed average of the median measured angle deviation (in blue), and my correction function (in red):</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10053/ratio.png\" alt=\"ratio\"></p>\n\n<p>DBSCAN is run at each iteration.  Its output is merged with existing tracks in a simple way: for each track, or candidate track, I compute the number of volumes with hits from the track.  Hits are then assigned to the candidate track with the most volumes.  Using number of volumes is way more effective than using the number of hits in the track.  </p>\n\n<p>Another criteria is used for deciding which track wins.  I assign a unique <code>vl_id</code> to each <code>volume_id, layer_id</code> pair.  For each of the first 100 train events I represented each particle track by the sequence of its <code>vl_id</code> once data is sorted by <code>z</code>.  I then compute the frequency of each sub sequence of 4 <code>vl_id</code> .  The quality of each track candidate in test events is computed in a similar way: first create the sequence of its <code>vl_id</code> once data is sorted by <code>z</code>, then take the average of the log of the frequencies of its sub sequences of length 4, and multiply by the number of volumes of the candidate track.  A hit is assigned to a new candidate track if the new candidate track has both more volumes and  a better quality than the current track of the hit.  This quality is very effective in removing tracks that do not make sense, for instance tracks that skip a layer entirely.   </p>\n\n<p>The above yields a LB score above 0.785 with about 33000 DBSCAN runs.  It takes about 10 hours per event.</p>\n\n<p>The extra mileage I got comes for a simple idea: run another, similar model, on the inner volumes only (7, 8, and 9).  This model can be more conservative (smaller eps for DBSCAN) because tracks are closer to perfect helix.  I ran this model for about the same number of iterations, then merged its output with the previous model: tracks that overlap significantly are merged, and for the rest, the track with most volumes wins.</p>\n\n<p>The very last improvements (about 0.002) come from merging with a third model that is similar to the first one.</p>\n\n<p>That's it, no fancy math, just lots of tuning.  I hope I have not made errors in the equations, I'll check again tomorrow, but appreciate if you find typos.  They must be correct in the code given the results: the code finds about 95% of the centered tracks.</p>\n\n<p>Things I thought about but did not had time to finish implementing:</p>\n\n<ul>\n<li>Use direction information from cells data</li>\n<li>Extend to tracks that do not pass near z axis</li>\n<li>Fit helix to each track candidate to remove outliers and possibly add missing hits.</li>\n</ul>\n\n<p>I thought my approach would be a nice starting point for second phase, given its simplicity, but I no longer think it is, now that I saw <a href=\"/icecuber\">@icecuber</a> solution!</p>",
  "messages": [
    {
      "id": 369949,
      "postDate": "2018-08-14T01:27:51.737Z",
      "content": "<p>Did I disclose I have been using DBSCAN?  Well, now you know ;)  </p>\n\n<p>My approach is quite straightforward and has been almost fully disclosed by @yuval.  An helix that starts from z axis can be described by 4 parameters:</p>\n\n<ul>\n<li>z at origin <code>z0</code></li>\n<li>radius <code>r0</code></li>\n<li>angle at origin in transverse plane (x,y plane) <code>phi0</code></li>\n<li>slope <code>zr</code></li>\n</ul>\n\n<p>The last 3 can be expressed as functions of the momentum at origin, <code>px</code>, <code>py</code>, <code>pz</code>, and <code>pt = sqrt(px² + py²)</code>:</p>\n\n<ul>\n<li><code>r0 = C * pt</code></li>\n<li><code>phi0 = arctan(py/px)</code></li>\n<li><code>zr = pz/pt</code></li>\n</ul>\n\n<p>The formula to compute <code>C</code> is given in the documents from CERN but I estimated it from the train data via a linear regression. That's the only use of supervised learning I made ;)</p>\n\n<p>My code loops over <code>z0, r0</code> pairs.  Rather than estimating a distribution I just sample from the tracks in the first 100 train samples.  For each pair I 'unroll the helix', i.e. compute <code>phi0</code> and <code>zr</code> as:</p>\n\n<pre><code>phi0 = phi +- theta0\nzr =  (z - z0) / (2 * r0 * theta0)\n</code></pre>\n\n<p>where <code>rt</code> is the distance to origin in transverse plane, <code>phi</code> the angle in transverse plane, and <code>theta0</code> is the unrolling angle:</p>\n\n<pre><code>rt = sqrt(x² + y²)\nphi = arctan(y/x)\ntheta0 = arcsin(rt / (2 * r0))\n</code></pre>\n\n<p>In one iteration I add <code>theta0</code> to <code>phi</code>, and in the next iteration I subtract it.</p>\n\n<p>In order to cope with the discontinuity at <code>pi</code> and <code>-pi</code> I use <code>cos(phi0)</code> and <code>sin(phi0)</code>.  </p>\n\n<p>The distribution of <code>zr</code> is highly skewed.  Many have use <code>arctan</code> to unskew it, but I found that using <code>arcsinh</code> was way more effective.  I actually use:</p>\n\n<pre><code>arcsinh(zr / 0.7) / 3.5\n</code></pre>\n\n<p>The picture below gives the distribution of arctan(zr), and the one below the distribution of arcsinh. The latter is way more uniform.</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10056/atan1.png\" alt=\"arctan distribution\"></p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10055/asinh.png\" alt=\"arcsinh distribution\"></p>\n\n<p>The last twist is to model the uneven magnetic field at high values of <code>z</code>.  The picture below shows the relative difference between the theoretical angle, and the median of measured angle as a function of <code>z</code>, the picture below gives the number of hits in log scale:</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10052/ratio1.png\" alt=\"ratio1\"></p>\n\n<p>The best way I found was to multiply <code>theta0</code> with a correction that depends on <code>z</code>:</p>\n\n<pre><code>1.005 - (abs(z + 200) / 6000)**2.4\n</code></pre>\n\n<p>The picture below shows a smoothed average of the median measured angle deviation (in blue), and my correction function (in red):</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10053/ratio.png\" alt=\"ratio\"></p>\n\n<p>DBSCAN is run at each iteration.  Its output is merged with existing tracks in a simple way: for each track, or candidate track, I compute the number of volumes with hits from the track.  Hits are then assigned to the candidate track with the most volumes.  Using number of volumes is way more effective than using the number of hits in the track.  </p>\n\n<p>Another criteria is used for deciding which track wins.  I assign a unique <code>vl_id</code> to each <code>volume_id, layer_id</code> pair.  For each of the first 100 train events I represented each particle track by the sequence of its <code>vl_id</code> once data is sorted by <code>z</code>.  I then compute the frequency of each sub sequence of 4 <code>vl_id</code> .  The quality of each track candidate in test events is computed in a similar way: first create the sequence of its <code>vl_id</code> once data is sorted by <code>z</code>, then take the average of the log of the frequencies of its sub sequences of length 4, and multiply by the number of volumes of the candidate track.  A hit is assigned to a new candidate track if the new candidate track has both more volumes and  a better quality than the current track of the hit.  This quality is very effective in removing tracks that do not make sense, for instance tracks that skip a layer entirely.   </p>\n\n<p>The above yields a LB score above 0.785 with about 33000 DBSCAN runs.  It takes about 10 hours per event.</p>\n\n<p>The extra mileage I got comes for a simple idea: run another, similar model, on the inner volumes only (7, 8, and 9).  This model can be more conservative (smaller eps for DBSCAN) because tracks are closer to perfect helix.  I ran this model for about the same number of iterations, then merged its output with the previous model: tracks that overlap significantly are merged, and for the rest, the track with most volumes wins.</p>\n\n<p>The very last improvements (about 0.002) come from merging with a third model that is similar to the first one.</p>\n\n<p>That's it, no fancy math, just lots of tuning.  I hope I have not made errors in the equations, I'll check again tomorrow, but appreciate if you find typos.  They must be correct in the code given the results: the code finds about 95% of the centered tracks.</p>\n\n<p>Things I thought about but did not had time to finish implementing:</p>\n\n<ul>\n<li>Use direction information from cells data</li>\n<li>Extend to tracks that do not pass near z axis</li>\n<li>Fit helix to each track candidate to remove outliers and possibly add missing hits.</li>\n</ul>\n\n<p>I thought my approach would be a nice starting point for second phase, given its simplicity, but I no longer think it is, now that I saw <a href=\"/icecuber\">@icecuber</a> solution!</p>",
      "rawMarkdown": "Did I disclose I have been using DBSCAN?  Well, now you know ;)  \n\nMy approach is quite straightforward and has been almost fully disclosed by @yuval.  An helix that starts from z axis can be described by 4 parameters:\n\n - z at origin `z0`\n - radius `r0`\n - angle at origin in transverse plane (x,y plane) `phi0`\n - slope `zr`\n\nThe last 3 can be expressed as functions of the momentum at origin, `px`, `py`, `pz`, and `pt = sqrt(px² + py²)`:\n\n - `r0 = C * pt`\n - `phi0 = arctan(py/px)`\n - `zr = pz/pt`\n\nThe formula to compute `C` is given in the documents from CERN but I estimated it from the train data via a linear regression. That's the only use of supervised learning I made ;)\n\nMy code loops over `z0, r0` pairs.  Rather than estimating a distribution I just sample from the tracks in the first 100 train samples.  For each pair I 'unroll the helix', i.e. compute `phi0` and `zr` as:\n\n    phi0 = phi +- theta0\n    zr =  (z - z0) / (2 * r0 * theta0)\n\nwhere `rt` is the distance to origin in transverse plane, `phi` the angle in transverse plane, and `theta0` is the unrolling angle:\n\n    rt = sqrt(x² + y²)\n    phi = arctan(y/x)\n    theta0 = arcsin(rt / (2 * r0))\n\nIn one iteration I add `theta0` to `phi`, and in the next iteration I subtract it.\n\nIn order to cope with the discontinuity at `pi` and `-pi` I use `cos(phi0)` and `sin(phi0)`.  \n\nThe distribution of `zr` is highly skewed.  Many have use `arctan` to unskew it, but I found that using `arcsinh` was way more effective.  I actually use:\n\n    arcsinh(zr / 0.7) / 3.5\n\nThe picture below gives the distribution of arctan(zr), and the one below the distribution of arcsinh. The latter is way more uniform.\n\n![arctan distribution][1]\n\n![arcsinh distribution][2]\n\nThe last twist is to model the uneven magnetic field at high values of `z`.  The picture below shows the relative difference between the theoretical angle, and the median of measured angle as a function of `z`, the picture below gives the number of hits in log scale:\n\n![ratio1][3]\n\nThe best way I found was to multiply `theta0` with a correction that depends on `z`:\n\n    1.005 - (abs(z + 200) / 6000)**2.4\n\nThe picture below shows a smoothed average of the median measured angle deviation (in blue), and my correction function (in red):\n\n![ratio][4]\n\nDBSCAN is run at each iteration.  Its output is merged with existing tracks in a simple way: for each track, or candidate track, I compute the number of volumes with hits from the track.  Hits are then assigned to the candidate track with the most volumes.  Using number of volumes is way more effective than using the number of hits in the track.  \n\nAnother criteria is used for deciding which track wins.  I assign a unique `vl_id` to each `volume_id, layer_id` pair.  For each of the first 100 train events I represented each particle track by the sequence of its `vl_id` once data is sorted by `z`.  I then compute the frequency of each sub sequence of 4 `vl_id` .  The quality of each track candidate in test events is computed in a similar way: first create the sequence of its `vl_id` once data is sorted by `z`, then take the average of the log of the frequencies of its sub sequences of length 4, and multiply by the number of volumes of the candidate track.  A hit is assigned to a new candidate track if the new candidate track has both more volumes and  a better quality than the current track of the hit.  This quality is very effective in removing tracks that do not make sense, for instance tracks that skip a layer entirely.   \n\nThe above yields a LB score above 0.785 with about 33000 DBSCAN runs.  It takes about 10 hours per event.\n\nThe extra mileage I got comes for a simple idea: run another, similar model, on the inner volumes only (7, 8, and 9).  This model can be more conservative (smaller eps for DBSCAN) because tracks are closer to perfect helix.  I ran this model for about the same number of iterations, then merged its output with the previous model: tracks that overlap significantly are merged, and for the rest, the track with most volumes wins.\n\nThe very last improvements (about 0.002) come from merging with a third model that is similar to the first one.\n\nThat's it, no fancy math, just lots of tuning.  I hope I have not made errors in the equations, I'll check again tomorrow, but appreciate if you find typos.  They must be correct in the code given the results: the code finds about 95% of the centered tracks.\n\nThings I thought about but did not had time to finish implementing:\n\n - Use direction information from cells data\n - Extend to tracks that do not pass near z axis\n - Fit helix to each track candidate to remove outliers and possibly add missing hits.\n\nI thought my approach would be a nice starting point for second phase, given its simplicity, but I no longer think it is, now that I saw @icecuber solution!\n\n\n  [1]: https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10056/atan1.png\n  [2]: https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10055/asinh.png\n  [3]: https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10052/ratio1.png\n  [4]: https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10053/ratio.png",
      "votes": 41
    },
    {
      "id": 370324,
      "postDate": "2018-08-14T16:09:56.577Z",
      "content": "<p>Thanks for you sharing,My solution is also based on DBScan and I also have no time to finish:\"Use direction information from cells data and Extend to tracks that do not pass near z axis\",but I fitted helix to extend the tracks.I also used the tips from Heng to find candicate hits and desinged a  LGBM model to classify the candidates.</p>",
      "rawMarkdown": "Thanks for you sharing,My solution is also based on DBScan and I also have no time to finish:\"Use direction information from cells data and Extend to tracks that do not pass near z axis\",but I fitted helix to extend the tracks.I also used the tips from Heng to find candicate hits and desinged a  LGBM model to classify the candidates.\n",
      "votes": 4,
      "replies": [
        {
          "id": 370361,
          "postDate": "2018-08-14T17:33:31.113Z",
          "content": "<p>Yes, track extension was definitely a miss for me.  Congrats on your result, even if you passed me at the last minute ;)</p>",
          "rawMarkdown": "Yes, track extension was definitely a miss for me.  Congrats on your result, even if you passed me at the last minute ;)"
        }
      ]
    },
    {
      "id": 376482,
      "postDate": "2018-08-27T15:45:48.820Z",
      "content": "<p>Final code and documentation is available on github: <a href=\"https://github.com/jfpuget/Kaggle_TrackML\">https://github.com/jfpuget/Kaggle_TrackML</a></p>\n\n<p>I found why my local score was higher than the LB: I forgot to use the magnetic field correction in one model... Once fixed local score and LB score become much closer, with a difference smaller than 0.001.  I document and share code for the fixed models.</p>",
      "rawMarkdown": "Final code and documentation is available on github: https://github.com/jfpuget/Kaggle_TrackML\n\nI found why my local score was higher than the LB: I forgot to use the magnetic field correction in one model... Once fixed local score and LB score become much closer, with a difference smaller than 0.001.  I document and share code for the fixed models.",
      "votes": 1
    },
    {
      "id": 375535,
      "postDate": "2018-08-25T11:47:44.500Z",
      "content": "<p>@CPMP</p>\n\n<p>Thanks for the solution. It is a nice piece of work!</p>",
      "rawMarkdown": "@CPMP\n \nThanks for the solution. It is a nice piece of work!\n",
      "votes": 1,
      "replies": [
        {
          "id": 375611,
          "postDate": "2018-08-25T15:59:31.750Z",
          "content": "<p>Thanks you Heng! </p>\n\n<p>Your remark about supervised learning being mandatory for reaching 0.8 has been a driver for me!</p>\n\n<p>It is a pity you did not had time to submit a good solution at the end.  I was surprised, as many of us, to not see you above 0.8 at the end.</p>",
          "rawMarkdown": "Thanks you Heng! \n\nYour remark about supervised learning being mandatory for reaching 0.8 has been a driver for me!\n\nIt is a pity you did not had time to submit a good solution at the end.  I was surprised, as many of us, to not see you above 0.8 at the end."
        },
        {
          "id": 375637,
          "postDate": "2018-08-25T17:17:48.230Z",
          "content": "<p>i have some urgent project at work the last minute. I will be continuing this in the speed phase if time permits. Right now, i am at the TGS salt identification competition, do come and take a look!</p>",
          "rawMarkdown": "i have some urgent project at work the last minute. I will be continuing this in the speed phase if time permits. Right now, i am at the TGS salt identification competition, do come and take a look!",
          "votes": 1
        },
        {
          "id": 375656,
          "postDate": "2018-08-25T17:59:06.563Z",
          "content": "<p>I am considering TGS or Airbus as my next ones ;)</p>",
          "rawMarkdown": "I am considering TGS or Airbus as my next ones ;)",
          "votes": 1
        }
      ]
    },
    {
      "id": 374054,
      "postDate": "2018-08-22T11:13:16.807Z",
      "content": "<p>I have put some code on <a href=\"https://github.com/jfpuget/Kaggle_TrackML\">github</a> </p>\n\n<p>This is work in progress, the repo should be final by Monday.  </p>\n\n<p>The code computes something that should give a LB above 0.78.  I'm running it as of now to see what score exactly this yields.</p>\n\n<p>Cleaning my code revealed few little glitches that explain why my LB score was below my local score.  I hope the code on github fixes that.</p>",
      "rawMarkdown": "I have put some code on [github][1] \n\nThis is work in progress, the repo should be final by Monday.  \n\nThe code computes something that should give a LB above 0.78.  I'm running it as of now to see what score exactly this yields.\n\nCleaning my code revealed few little glitches that explain why my LB score was below my local score.  I hope the code on github fixes that.\n\n\n  [1]: https://github.com/jfpuget/Kaggle_TrackML",
      "votes": 1,
      "replies": [
        {
          "id": 374326,
          "postDate": "2018-08-22T20:29:13.680Z",
          "content": "<p>@CPMP thanks  so much for sharing. </p>",
          "rawMarkdown": "@CPMP thanks  so much for sharing. ",
          "votes": 1
        }
      ]
    },
    {
      "id": 372564,
      "postDate": "2018-08-19T18:01:32.607Z",
      "content": "<p>Congratulations, CPMP! I always learn great things from your posts.</p>",
      "rawMarkdown": "Congratulations, CPMP! I always learn great things from your posts.",
      "votes": 1
    },
    {
      "id": 371557,
      "postDate": "2018-08-17T05:10:42.380Z",
      "content": "<p>I'm trying to understand how I can get a better score. You have many improvements, probably every step give you a boost. \nAnyway, Yuval said that's easy yo get 0.7 with right features. I tried his approach with the normal distribution but didn't get a better score. And my features are standard: cos, sin, zr and arctan(zr)  (I noticed that zr is helpful also together with arctan).</p>\n\n<blockquote>\n  <p>The formula to compute C is given in the documents from CERN but I estimated it from the train data via a linear regression. That's the only use of supervised learning I made</p>\n</blockquote>\n\n<p>I don't understand why you need this. Features doesn't involved this constant and you don't have px, py, pz in the test data.</p>\n\n<blockquote>\n  <p>Using number of volumes is way more effective than using the number of hits in the track. </p>\n</blockquote>\n\n<p>Probably this gave you a good boost, right? I used the number of hits.</p>\n\n<blockquote>\n  <p>The extra mileage I got comes for a simple idea: run another, similar model, on the inner volumes only (7, 8, and 9). </p>\n</blockquote>\n\n<p>I used this also in my solution. I constructed tracks inside r &lt; 200 (you can also use cells there). Then I used DBSCAN for all hits but verifying tracks by \"the first half\" of tracks found earlier.</p>",
      "rawMarkdown": "I'm trying to understand how I can get a better score. You have many improvements, probably every step give you a boost. \nAnyway, Yuval said that's easy yo get 0.7 with right features. I tried his approach with the normal distribution but didn't get a better score. And my features are standard: cos, sin, zr and arctan(zr)  (I noticed that zr is helpful also together with arctan).\n\n&gt; The formula to compute C is given in the documents from CERN but I estimated it from the train data via a linear regression. That's the only use of supervised learning I made\n\nI don't understand why you need this. Features doesn't involved this constant and you don't have px, py, pz in the test data.\n\n&gt; Using number of volumes is way more effective than using the number of hits in the track. \n\nProbably this gave you a good boost, right? I used the number of hits.\n\n&gt; The extra mileage I got comes for a simple idea: run another, similar model, on the inner volumes only (7, 8, and 9). \n\nI used this also in my solution. I constructed tracks inside r &lt; 200 (you can also use cells there). Then I used DBSCAN for all hits but verifying tracks by \"the first half\" of tracks found earlier.",
      "votes": 1,
      "replies": [
        {
          "id": 371568,
          "postDate": "2018-08-17T06:11:21.517Z",
          "content": "<blockquote>\n  <p>I don't understand why you need this. </p>\n</blockquote>\n\n<p>You can do without.  I use it when sampling. I sample pt and pz from the tracks in train data, compute r0 from pt instead of having to compute it from the hits in each track.  It is faster.</p>\n\n<blockquote>\n  <p>Probably this gave you a good boost, right? </p>\n</blockquote>\n\n<p>Everything I documented gave me a boost ;)  This one gave me at least 0.02 and probably more.  I did not measure its effect separately  because I first replaced the number of hits by the number of layers, got a boost, then replaced the number of layers by the number of volumes, and again got a boost.</p>",
          "rawMarkdown": "&gt; I don't understand why you need this. \n\nYou can do without.  I use it when sampling. I sample pt and pz from the tracks in train data, compute r0 from pt instead of having to compute it from the hits in each track.  It is faster.\n\n&gt; Probably this gave you a good boost, right? \n\nEverything I documented gave me a boost ;)  This one gave me at least 0.02 and probably more.  I did not measure its effect separately  because I first replaced the number of hits by the number of layers, got a boost, then replaced the number of layers by the number of volumes, and again got a boost.",
          "votes": 1
        },
        {
          "id": 371575,
          "postDate": "2018-08-17T06:29:27.707Z",
          "content": "<blockquote>\n  <p>compute r0 from pt instead of having to compute it from the hits in each track. </p>\n</blockquote>\n\n<p>Ah, I see.</p>\n\n<blockquote>\n  <p>My code loops over z0, r0 pairs.</p>\n</blockquote>\n\n<p>Do you have fixed (z0, r0) pairs unlike Yuval's randomness? \nAnd you don't use StandardScaler, right? \nSorry, if your code is shared, I woudn't ask. :)</p>",
          "rawMarkdown": "&gt;  compute r0 from pt instead of having to compute it from the hits in each track. \n\nAh, I see.\n\n&gt; My code loops over z0, r0 pairs.\n\nDo you have fixed (z0, r0) pairs unlike Yuval's randomness? \nAnd you don't use StandardScaler, right? \nSorry, if your code is shared, I woudn't ask. :)"
        },
        {
          "id": 371651,
          "postDate": "2018-08-17T10:11:32.967Z",
          "content": "<p>As I wrote: </p>\n\n<blockquote>\n  <p>My code loops over z0, r0 pairs. Rather than estimating a distribution I just sample from the tracks in the first 100 train samples. </p>\n</blockquote>\n\n<p>I collected all the <code>(z0, pt)</code> pairs from the train events I'm considering, then turned these into <code>(z0, r0)</code> pairs via the use of the <code>C</code> constant above.  Then I draw one pair randomly at each iteration of the main loop.</p>",
          "rawMarkdown": "As I wrote: \n\n&gt; My code loops over z0, r0 pairs. Rather than estimating a distribution I just sample from the tracks in the first 100 train samples. \n\nI collected all the `(z0, pt)` pairs from the train events I'm considering, then turned these into `(z0, r0)` pairs via the use of the `C` constant above.  Then I draw one pair randomly at each iteration of the main loop.",
          "votes": 1
        },
        {
          "id": 373322,
          "postDate": "2018-08-21T07:02:59.427Z",
          "content": "<blockquote>\n  <p>The formula to compute C is given in the documents from CERN</p>\n</blockquote>\n\n<p>I think the formula is something like pt/(q*B).  For some reason a particle charge 'q' have only +-1 values, so we can ignore them. Otherwise it would be proportional to pt/q.</p>\n\n<blockquote>\n  <p>but I estimated it from the train data via a linear regression. </p>\n</blockquote>\n\n<p>I think there's something you're not saying. ;) We have no the truth 'r0' value. Do use a certain formula or an approximation?</p>",
          "rawMarkdown": "&gt; The formula to compute C is given in the documents from CERN\n\nI think the formula is something like pt/(q*B).  For some reason a particle charge 'q' have only +-1 values, so we can ignore them. Otherwise it would be proportional to pt/q.\n\n&gt; but I estimated it from the train data via a linear regression. \n\nI think there's something you're not saying. ;) We have no the truth 'r0' value. Do use a certain formula or an approximation?\n"
        },
        {
          "id": 373443,
          "postDate": "2018-08-21T11:31:10.090Z",
          "content": "<p>Right, i did not explain how I compute r0 for enought tracks to be able to compute the <code>C</code> constant.</p>\n\n<p>Your questions (and all questions on this topic) will make my final document better.  Thanks for that!</p>\n\n<p>I use the conformal representation that was described in one of the documents shared on the forum, with coordinates <code>x/rt, y/rt</code> where <code>rt = sqrt(x^2 + y^2)</code></p>\n\n<p>In that representation, circles going through the origin are straight lines.  With little math I found that the distance of this line to the origin is <code>alpha0 = 1/r0</code>.  That's how I found the radius of the helix.</p>\n\n<p>There are many ways to compute the radius of a circle once you have 3 points on it (the origin, and 2 points on the track). I could have used another one, for instance: <a href=\"https://math.stackexchange.com/questions/133638/how-does-this-equation-to-find-the-radius-from-3-points-actually-work\">https://math.stackexchange.com/questions/133638/how-does-this-equation-to-find-the-radius-from-3-points-actually-work</a></p>\n\n<p>Another question you had I did not answered: I am not using standard scaler.</p>\n\n<p>I will share my code before the deadline set by organizers, your quest will be over soon ;)  Reason it takes time is that I am on vacation...</p>",
          "rawMarkdown": "Right, i did not explain how I compute r0 for enought tracks to be able to compute the `C` constant.\n\nYour questions (and all questions on this topic) will make my final document better.  Thanks for that!\n\nI use the conformal representation that was described in one of the documents shared on the forum, with coordinates `x/rt, y/rt` where `rt = sqrt(x^2 + y^2)`\n\nIn that representation, circles going through the origin are straight lines.  With little math I found that the distance of this line to the origin is `alpha0 = 1/r0`.  That's how I found the radius of the helix.\n\nThere are many ways to compute the radius of a circle once you have 3 points on it (the origin, and 2 points on the track). I could have used another one, for instance: https://math.stackexchange.com/questions/133638/how-does-this-equation-to-find-the-radius-from-3-points-actually-work\n\nAnother question you had I did not answered: I am not using standard scaler.\n\nI will share my code before the deadline set by organizers, your quest will be over soon ;)  Reason it takes time is that I am on vacation...",
          "votes": 1
        },
        {
          "id": 373464,
          "postDate": "2018-08-21T12:04:27.030Z",
          "content": "<p>@CPMP Thanks for the answer! Now it's clear.</p>\n\n<p>By the way do you know why q is -1 or +1? The CERN document says</p>\n\n<blockquote>\n  <p>the charge as multiple of the absolute electron charge</p>\n</blockquote>\n\n<p>It's strange to me we have no particles with a charge more than 1.</p>",
          "rawMarkdown": "@CPMP Thanks for the answer! Now it's clear.\n\nBy the way do you know why q is -1 or +1? The CERN document says\n\n&gt; the charge as multiple of the absolute electron charge\n\nIt's strange to me we have no particles with a charge more than 1.",
          "votes": 1
        },
        {
          "id": 373492,
          "postDate": "2018-08-21T12:47:16.113Z",
          "content": "<p>I don't know the physics here, better ask the organisers than me!</p>",
          "rawMarkdown": "I don't know the physics here, better ask the organisers than me!"
        },
        {
          "id": 373721,
          "postDate": "2018-08-21T19:50:43.110Z",
          "content": "<p>q=+1 or -1 : charged  particles created in proton collision are mostly charged pions, charged kaons, electron, muons, protons (and their anti particles), which all have charge +/- 1. In the real collisions we might have very rarely alpha particles (or helium nucleus) of charge +2.  In other apparatus, like a mass spectrometer, one can have very large positive charge. </p>",
          "rawMarkdown": "q=+1 or -1 : charged  particles created in proton collision are mostly charged pions, charged kaons, electron, muons, protons (and their anti particles), which all have charge +/- 1. In the real collisions we might have very rarely alpha particles (or helium nucleus) of charge +2.  In other apparatus, like a mass spectrometer, one can have very large positive charge. "
        },
        {
          "id": 373733,
          "postDate": "2018-08-21T20:16:48.653Z",
          "content": "<blockquote>\n  <p>which all have charge +/- 1.</p>\n</blockquote>\n\n<p>Great! Thanks for the answer! <br>\nI think there are also particles with a zero charge. For example, kaons. We don't have it too. </p>\n\n<blockquote>\n  <p>In the real collisions we might have very rarely alpha particles (or helium nucleus) of charge +2</p>\n</blockquote>\n\n<p>In the real collisions, but not in our simulations, right? Though I didn't check all events. :)</p>\n\n<p>It's funny I think about it only after the competition. :) That's because I didn't use ground truth initial values...</p>",
          "rawMarkdown": "&gt; which all have charge +/- 1.\n\nGreat! Thanks for the answer!  \nI think there are also particles with a zero charge. For example, kaons. We don't have it too. \n\n&gt; In the real collisions we might have very rarely alpha particles (or helium nucleus) of charge +2\n\nIn the real collisions, but not in our simulations, right? Though I didn't check all events. :)\n\nIt's funny I think about it only after the competition. :) That's because I didn't use ground truth initial values...\n"
        }
      ]
    },
    {
      "id": 371059,
      "postDate": "2018-08-15T21:57:19.007Z",
      "content": "<p>@CPMP, I'm wondering about your plot of the angle differences due to the magnetic field. You write it is as a function of z, but is your z-axis rescaled? The axis seems to go only from -300 to +300. Did you convert to cm?</p>\n\n<p>I'm interested because of the large peaks in the curve. Do they coincide with the first large caps closest to the large cylinders? I ask because I think I saw some anomalies exactly at (and only at) these first (innermost) large caps.</p>\n\n<p>You curve also has a peaked feature at the positive z-end, which matches with the strange features of the B field visible in my plots in the last (outermost) cap towards +z, I think.</p>",
      "rawMarkdown": "@CPMP, I'm wondering about your plot of the angle differences due to the magnetic field. You write it is as a function of z, but is your z-axis rescaled? The axis seems to go only from -300 to +300. Did you convert to cm?\n\nI'm interested because of the large peaks in the curve. Do they coincide with the first large caps closest to the large cylinders? I ask because I think I saw some anomalies exactly at (and only at) these first (innermost) large caps.\n\nYou curve also has a peaked feature at the positive z-end, which matches with the strange features of the B field visible in my plots in the last (outermost) cap towards +z, I think.",
      "votes": 1,
      "replies": [
        {
          "id": 371231,
          "postDate": "2018-08-16T09:53:37.370Z",
          "content": "<p>Yes, it was rescaled, I should have said it, sorry.  Top one is rescaled by 1/10, bottom one by 1/50.</p>\n\n<p>The most striking finding for me is that the variation is not symmetric when you change z sign.</p>\n\n<p>I was also wondering about the peaks, which is why I also plot the number of hits.  The peaks correspond to values of z with a high number of hits.  It is the valleys that are misleading actually.  The second plot is obtained by scaling z further, and removing values of z with a small number of hits.  I did not investigate further than that, because a small number of hits can be safely ignored for my purpose.</p>\n\n<p>I will release an EDA notebook to show how I produced these plots and other ones I found useful during the competition.</p>\n\n<p>I also looked at magnetic field variation as a function of phi, and found some variation, like you.  But I did not model it.  I guess its effect is way smaller than the variation by z.  </p>",
          "rawMarkdown": "Yes, it was rescaled, I should have said it, sorry.  Top one is rescaled by 1/10, bottom one by 1/50.\n\nThe most striking finding for me is that the variation is not symmetric when you change z sign.\n\nI was also wondering about the peaks, which is why I also plot the number of hits.  The peaks correspond to values of z with a high number of hits.  It is the valleys that are misleading actually.  The second plot is obtained by scaling z further, and removing values of z with a small number of hits.  I did not investigate further than that, because a small number of hits can be safely ignored for my purpose.\n\nI will release an EDA notebook to show how I produced these plots and other ones I found useful during the competition.\n\nI also looked at magnetic field variation as a function of phi, and found some variation, like you.  But I did not model it.  I guess its effect is way smaller than the variation by z.  "
        }
      ]
    },
    {
      "id": 370955,
      "postDate": "2018-08-15T18:13:18.433Z",
      "content": "<p>Congratulations and many thanks to share your solutions :-) Not easy competition not only to understand it but mostly for the computational effort !!! </p>",
      "rawMarkdown": "Congratulations and many thanks to share your solutions :-) Not easy competition not only to understand it but mostly for the computational effort !!! ",
      "votes": 1
    },
    {
      "id": 370609,
      "postDate": "2018-08-15T06:12:19.960Z",
      "content": "<p>congratulations! and thanks for sharing your approach</p>",
      "rawMarkdown": "congratulations! and thanks for sharing your approach",
      "votes": 1
    },
    {
      "id": 370472,
      "postDate": "2018-08-14T21:40:06.623Z",
      "content": "<p>For zr, the math says use arctan to convert to a physically meaningful angle.  How did you ever come up with the idea of using a scaled inverse hyperbolic sine?</p>",
      "rawMarkdown": "For zr, the math says use arctan to convert to a physically meaningful angle.  How did you ever come up with the idea of using a scaled inverse hyperbolic sine?",
      "votes": 1,
      "replies": [
        {
          "id": 370583,
          "postDate": "2018-08-15T04:24:02.740Z",
          "content": "<p>I looked for functions that were similar to tan(), i.e. that had infinite limits in a closed interval.  sinh() was the first function I looked at, and its distribution looked very similar to that of zr. </p>",
          "rawMarkdown": "I looked for functions that were similar to tan(), i.e. that had infinite limits in a closed interval.  sinh() was the first function I looked at, and its distribution looked very similar to that of zr. "
        },
        {
          "id": 371072,
          "postDate": "2018-08-15T23:15:38.377Z",
          "content": "<p>@CPMP Thanks for sharing your result and congratulations to gold!</p>\n\n<p>If one converts <code>zr</code> using <code>arctan</code>, one gets the angle between <code>pt</code> and <code>pz</code>, but this angle is probably not of uniform distribution for the events in a particle collider.</p>\n\n<p>In fact, I found something quite interesting:</p>\n\n<p><a href=\"https://en.m.wikipedia.org/wiki/Pseudorapidity\">https://en.m.wikipedia.org/wiki/Pseudorapidity</a></p>\n\n<p>There is a number in particle physics, called pseudorapidity, given by</p>\n\n<pre><code>eta = -ln(tan(delta/2))\n</code></pre>\n\n<p>where</p>\n\n<pre><code>tan(delta) = pt/pz = 1/zr\n</code></pre>\n\n<p>This can also be written as</p>\n\n<pre><code>eta = arsinh(1/tan(delta)) = arsinh(zr)\n</code></pre>\n\n<p>The interesting thing is that according to the Wikipedia article (and papers that can be found via Google) in hadron colliders \"particle production is constant as a function of rapidity\" (approximately).</p>\n\n<p>It seems like you found exactly the right formula that makes <code>zr</code> uniformly distributed! (except for the factor 1/0.7 which I do not understand right now and could be related to particle masses, the factor 1/3.5 is probably not so important).</p>",
          "rawMarkdown": "@CPMP Thanks for sharing your result and congratulations to gold!\n\nIf one converts `zr` using `arctan`, one gets the angle between `pt` and `pz`, but this angle is probably not of uniform distribution for the events in a particle collider.\n\nIn fact, I found something quite interesting:\n\nhttps://en.m.wikipedia.org/wiki/Pseudorapidity\n\nThere is a number in particle physics, called pseudorapidity, given by\n\n    eta = -ln(tan(delta/2))\n\nwhere\n\n    tan(delta) = pt/pz = 1/zr\n\nThis can also be written as\n\n    eta = arsinh(1/tan(delta)) = arsinh(zr)\n\nThe interesting thing is that according to the Wikipedia article (and papers that can be found via Google) in hadron colliders \"particle production is constant as a function of rapidity\" (approximately).\n\nIt seems like you found exactly the right formula that makes `zr` uniformly distributed! (except for the factor 1/0.7 which I do not understand right now and could be related to particle masses, the factor 1/3.5 is probably not so important).",
          "votes": 3
        },
        {
          "id": 371234,
          "postDate": "2018-08-16T10:01:28.047Z",
          "content": "<p>Wow, thanks for sharing.  I'm impressed I discovered something that is linked to a known physics law.  In a way it is reassuring that this is not just a computation artifact.</p>\n\n<p>The 0.7 factor makes the distribution even more uniform, but results without it were already quite good.  I'll share plots with and without 0.7 scaling ASAP.</p>\n\n<p>The 3.5 factor is just to scale the result to the same scale as the other two features I am using for clustering.  </p>",
          "rawMarkdown": "Wow, thanks for sharing.  I'm impressed I discovered something that is linked to a known physics law.  In a way it is reassuring that this is not just a computation artifact.\n\nThe 0.7 factor makes the distribution even more uniform, but results without it were already quite good.  I'll share plots with and without 0.7 scaling ASAP.\n\nThe 3.5 factor is just to scale the result to the same scale as the other two features I am using for clustering.  "
        },
        {
          "id": 371240,
          "postDate": "2018-08-16T10:26:00.447Z",
          "content": "<p>@Mark JD Hamilton great find and thanks for sharing.</p>",
          "rawMarkdown": "@Mark JD Hamilton great find and thanks for sharing."
        }
      ]
    },
    {
      "id": 370335,
      "postDate": "2018-08-14T16:43:40.443Z",
      "content": "<p>@CPMP, congratulations on reaching your goal of 0.80! I was rooting for you to make it in the final hours before the deadline.</p>\n\n<p>Your solutions looks very elegant. Definitely one of the best score per codelines ratios, I guess.</p>\n\n<p>Yes, all the ensemble clustering approaches would have no chance against the combinatoric/geometric ones in the throughput phase. However, the features you developed and your track quality metric could be interesting to incorporate for track evaluation even in combinatoric solutions.</p>",
      "rawMarkdown": "@CPMP, congratulations on reaching your goal of 0.80! I was rooting for you to make it in the final hours before the deadline.\n\nYour solutions looks very elegant. Definitely one of the best score per codelines ratios, I guess.\n\nYes, all the ensemble clustering approaches would have no chance against the combinatoric/geometric ones in the throughput phase. However, the features you developed and your track quality metric could be interesting to incorporate for track evaluation even in combinatoric solutions.",
      "votes": 1,
      "replies": [
        {
          "id": 370365,
          "postDate": "2018-08-14T17:35:45.077Z",
          "content": "<p>Glad you find it interesting.  And even happier if some of my work is reused in stage 2.  </p>",
          "rawMarkdown": "Glad you find it interesting.  And even happier if some of my work is reused in stage 2.  ",
          "votes": 1
        },
        {
          "id": 370385,
          "postDate": "2018-08-14T18:15:27.007Z",
          "content": "<p>And thanks for rooting for me!</p>",
          "rawMarkdown": "And thanks for rooting for me!",
          "votes": 1
        }
      ]
    },
    {
      "id": 370129,
      "postDate": "2018-08-14T10:24:29.003Z",
      "content": "<p>Thank you for sharing! And special thank you for the post on paralleling, it gave me a great boost once I managed to do it (better late than never :))</p>",
      "rawMarkdown": "Thank you for sharing! And special thank you for the post on paralleling, it gave me a great boost once I managed to do it (better late than never :))",
      "votes": 1,
      "replies": [
        {
          "id": 370130,
          "postDate": "2018-08-14T10:25:20.847Z",
          "content": "<p>Glad what i shared helped you.  I'll try to share earlier next time ;)</p>",
          "rawMarkdown": "Glad what i shared helped you.  I'll try to share earlier next time ;)"
        }
      ]
    },
    {
      "id": 370021,
      "postDate": "2018-08-14T05:21:35.613Z",
      "content": "<p>Congratulations @CPMP on gaining another gold metal and thanks for sharing your solution.</p>",
      "rawMarkdown": "Congratulations @CPMP on gaining another gold metal and thanks for sharing your solution.",
      "votes": 1
    },
    {
      "id": 370953,
      "postDate": "2018-08-15T18:04:22.343Z",
      "content": "<p>@CPMP in the formula:</p>\n\n<p><code>zr =  (z - z0) / (2 * r0 * phi0)</code></p>\n\n<p>didn't you mean</p>\n\n<pre><code> zr =  (z - z0) / (2 * r0 * theta0)\n</code></pre>",
      "rawMarkdown": "@CPMP in the formula:\n\n `zr =  (z - z0) / (2 * r0 * phi0)`\n\ndidn't you mean\n\n     zr =  (z - z0) / (2 * r0 * theta0)",
      "votes": 2,
      "replies": [
        {
          "id": 370956,
          "postDate": "2018-08-15T18:13:28.143Z",
          "content": "<p>Good catch, thanks!</p>",
          "rawMarkdown": "Good catch, thanks!",
          "votes": 2
        },
        {
          "id": 370958,
          "postDate": "2018-08-15T18:18:25.143Z",
          "content": "<p>Just trying to plug your magnetic field fix to my solution to see what I'll get, but can't make it work, yet.</p>",
          "rawMarkdown": "Just trying to plug your magnetic field fix to my solution to see what I'll get, but can't make it work, yet.",
          "votes": 1
        },
        {
          "id": 370964,
          "postDate": "2018-08-15T18:30:41.613Z",
          "content": "<p>I'll share my code soon, in case my writeup missed something relevant.</p>",
          "rawMarkdown": "I'll share my code soon, in case my writeup missed something relevant.",
          "votes": 1
        },
        {
          "id": 370967,
          "postDate": "2018-08-15T18:34:46.710Z",
          "content": "<p>I remember now, you must use the theta0 correction only for computing phi0, but not for computing zr.  </p>",
          "rawMarkdown": "I remember now, you must use the theta0 correction only for computing phi0, but not for computing zr.  ",
          "votes": 1
        },
        {
          "id": 370983,
          "postDate": "2018-08-15T18:57:01.477Z",
          "content": "<p>WoW.  plugged it in. used a short run (as is in my kernel) expanded, and got LB 0.785! I wonder what I'll get with the long run (100K points) .</p>",
          "rawMarkdown": "WoW.  plugged it in. used a short run (as is in my kernel) expanded, and got LB 0.785! I wonder what I'll get with the long run (100K points) .",
          "votes": 1
        },
        {
          "id": 370995,
          "postDate": "2018-08-15T19:23:42.183Z",
          "content": "<p>I tried 2 parts last night...  I used observed r0,z0 values  from EDA as my random values &amp; replaced arctan2 with arcsinh for zr.  r0,z0 seemed to have an improvement between 0.005 - 0.01 ( more than I expected).  Could not get arcsinh to yield any improvement...so maybe I'm doing something wrong.  Didn't try the theta0 adjustment, but now I will 😀</p>",
          "rawMarkdown": "I tried 2 parts last night...  I used observed r0,z0 values  from EDA as my random values &amp; replaced arctan2 with arcsinh for zr.  r0,z0 seemed to have an improvement between 0.005 - 0.01 ( more than I expected).  Could not get arcsinh to yield any improvement...so maybe I'm doing something wrong.  Didn't try the theta0 adjustment, but now I will 😀",
          "votes": 1
        },
        {
          "id": 371020,
          "postDate": "2018-08-15T20:34:24.343Z",
          "content": "<p>&gt; WoW. plugged it in. used a short run (as is in my kernel) expanded, and got LB 0.785! </p>\n\n<p>Great!</p>\n\n<p>The downside is that track extension becomes less effective. In my case, my track extension, based on Heng's code, became totally useless.  You're using a more elaborate way with a supervised ML approach.  Maybe you can get some upside.</p>\n\n<p>Anyway, it is good to know that this correction improves your code.  You may bet better results than mine in a fraction of time.</p>",
          "rawMarkdown": "&gt; WoW. plugged it in. used a short run (as is in my kernel) expanded, and got LB 0.785! \n\nGreat!\n\nThe downside is that track extension becomes less effective. In my case, my track extension, based on Heng's code, became totally useless.  You're using a more elaborate way with a supervised ML approach.  Maybe you can get some upside.\n\nAnyway, it is good to know that this correction improves your code.  You may bet better results than mine in a fraction of time.\n\n",
          "votes": 1
        },
        {
          "id": 371030,
          "postDate": "2018-08-15T21:06:21.003Z",
          "content": "<p><em>*</em> correction **\"\nI had a bug in my code it is \"only\" 0.76 with the short run and 0.785 with the long one.\nStill a 0.02 improvement </p>",
          "rawMarkdown": "*** correction **\"\nI had a bug in my code it is \"only\" 0.76 with the short run and 0.785 with the long one.\nStill a 0.02 improvement ",
          "votes": 2
        },
        {
          "id": 371053,
          "postDate": "2018-08-15T21:46:50.967Z",
          "content": "<blockquote>\n  <p>Still a 0.02 improvement</p>\n</blockquote>\n\n<p>I think that is roughly consistent with my own experience. As mentioned, I got about +0.01 from accounting for the systematic deviations due to the inhomogenous B field. It makes sense that it helps more in your case because your approach is more sensitive to variations in the helix parameters along a track, but it's still the same (small) order of magnitude.</p>",
          "rawMarkdown": "&gt; Still a 0.02 improvement\n\nI think that is roughly consistent with my own experience. As mentioned, I got about +0.01 from accounting for the systematic deviations due to the inhomogenous B field. It makes sense that it helps more in your case because your approach is more sensitive to variations in the helix parameters along a track, but it's still the same (small) order of magnitude.",
          "votes": 1
        },
        {
          "id": 371226,
          "postDate": "2018-08-16T09:23:36.627Z",
          "content": "<p>Mine was improved by 0.03</p>\n\n<p>Not sure why it was more effective for me.</p>",
          "rawMarkdown": "Mine was improved by 0.03\n\nNot sure why it was more effective for me.",
          "votes": 1
        },
        {
          "id": 371248,
          "postDate": "2018-08-16T10:42:24.647Z",
          "content": "<blockquote>\n  <p>Mine was improved by 0.03</p>\n</blockquote>\n\n<p>Interesting. Either it's the different sensitivity of the algorithms to perturbations of the helices, or I missed something in my implementation of the corrections.</p>",
          "rawMarkdown": "&gt; Mine was improved by 0.03\n\nInteresting. Either it's the different sensitivity of the algorithms to perturbations of the helices, or I missed something in my implementation of the corrections."
        }
      ]
    },
    {
      "id": 375722,
      "postDate": "2018-08-25T21:47:58.057Z",
      "content": "<p>@CPMP really good job. Well done. <a href=\"https://twitter.com/trackmllhc/status/1033277891226820608\">enter link description here</a></p>",
      "rawMarkdown": "@CPMP really good job. Well done. [enter link description here][1]\n\n\n  [1]: https://twitter.com/trackmllhc/status/1033277891226820608",
      "votes": 1
    },
    {
      "id": 370330,
      "postDate": "2018-08-14T16:29:00.220Z",
      "content": "<p>Merci d'avoir partagé cela avec nous. </p>",
      "rawMarkdown": "Merci d'avoir partagé cela avec nous. ",
      "votes": 1
    },
    {
      "id": 374889,
      "postDate": "2018-08-24T04:49:07.260Z",
      "content": "<p>Any participant (not necessarily with the highest score) who think they made valuable contributions with innovative algorithms (in particular if they have shared insights on the forum) are welcome to release publicly their code with an open source license and lightweight structured documentation. This will allow to compete for the « HEP meets ML » jury prizes: a NVidia V100 GPU, and two invitations to NIPS 2018 or the spring 2019 CERN workshop.See details in forum topic:</p>\n\n<p><a href=\"https://www.kaggle.com/c/trackml-particle-identification/discussion/63289\">https://www.kaggle.com/c/trackml-particle-identification/discussion/63289</a></p>",
      "rawMarkdown": "Any participant (not necessarily with the highest score) who think they made valuable contributions with innovative algorithms (in particular if they have shared insights on the forum) are welcome to release publicly their code with an open source license and lightweight structured documentation. This will allow to compete for the « HEP meets ML » jury prizes: a NVidia V100 GPU, and two invitations to NIPS 2018 or the spring 2019 CERN workshop.See details in forum topic:\n\nhttps://www.kaggle.com/c/trackml-particle-identification/discussion/63289",
      "replies": [
        {
          "id": 375008,
          "postDate": "2018-08-24T11:14:21.487Z",
          "content": "<p>I'll submit, I have started publishing my code.  But I try to enjoy the end of my vacation as well ;),  hence I will submit Monday probably.</p>",
          "rawMarkdown": "I'll submit, I have started publishing my code.  But I try to enjoy the end of my vacation as well ;),  hence I will submit Monday probably."
        }
      ]
    },
    {
      "id": 371307,
      "postDate": "2018-08-16T13:57:25.937Z",
      "content": "<p>Following up on the <a href=\"https://www.kaggle.com/c/trackml-particle-identification/discussion/63250#371072\">excellent find by Mark JD Hamilton</a>, here is a plot of <code>arcsinh(zr)</code>.  While quite uniform, it is not as uniform as the scaled version I used.</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/371307/10098/asinh2.png\" alt=\"arcsinh\"></p>",
      "rawMarkdown": "Following up on the [excellent find by Mark JD Hamilton][1], here is a plot of `arcsinh(zr)`.  While quite uniform, it is not as uniform as the scaled version I used.\n\n![arcsinh][2]\n\n\n  [1]: https://www.kaggle.com/c/trackml-particle-identification/discussion/63250#371072\n  [2]: https://storage.googleapis.com/kaggle-forum-message-attachments/371307/10098/asinh2.png",
      "replies": [
        {
          "id": 371385,
          "postDate": "2018-08-16T17:32:55.883Z",
          "content": "<p>Thanks for the diagram!</p>\n\n<p>I did a bit more research (which needs to be taken with a caveat, since I am not a particle physicist): There is another number, called rapidity, given by</p>\n\n<pre><code>y = artanh(beta*cos(delta))\n</code></pre>\n\n<p>where </p>\n\n<pre><code>beta = p/E\np = sqrt(pt^2+pz^2)\nE = sqrt(p^2+m^2)\ntan(delta) = pt/pz = 1/zr\n</code></pre>\n\n<p>with particle mass <code>m</code>. It is related to the pseudorapidity</p>\n\n<pre><code>eta = arsinh(1/tan(delta)) = arsinh(zr)\n</code></pre>\n\n<p>by</p>\n\n<pre><code>y = arsinh(zr/k)\n</code></pre>\n\n<p>with</p>\n\n<pre><code>k = sqrt(1+m^2/pt^2)\n</code></pre>\n\n<p>If <code>pt&gt;&gt;m</code>, then <code>y--&gt;eta</code>.</p>\n\n<p>From the references I have seen like </p>\n\n<p><a href=\"https://www.physics.umd.edu/hep/drew/Baden_jets_kinematics_dec_2008.pdf\">https://www.physics.umd.edu/hep/drew/Baden_jets_kinematics_dec_2008.pdf</a> (p. 12)</p>\n\n<p><a href=\"https://warwick.ac.uk/fac/sci/physics/staff/academic/gershon/gradteaching/warwickweek/material/lhcphysics/chill_warwick_lhc_2010_1.pdf\">https://warwick.ac.uk/fac/sci/physics/staff/academic/gershon/gradteaching/warwickweek/material/lhcphysics/chill_warwick_lhc_2010_1.pdf</a> (p.27)</p>\n\n<p>it seems the particle creation is really constant in the rapidity <code>y</code>, not the pseudorapidity <code>eta</code>.</p>\n\n<p>This means that there is a rescaling involved, like in your case, but the following is a bit strange: in the formula for <code>y</code> above the number <code>k</code> is always <code>&gt;=1</code>, but in your case it is <code>0.7&lt;1</code>. In addition, one expects the distribution for <code>eta = arsinh(zr)</code> to have a dip around <code>eta = 0</code>, like in the diagram on page 20 of the first reference, not a hill like in your case.</p>\n\n<p>I don't understand this at the moment, perhaps there is a mistake in the conversions above. I will think about it.</p>",
          "rawMarkdown": "Thanks for the diagram!\n\nI did a bit more research (which needs to be taken with a caveat, since I am not a particle physicist): There is another number, called rapidity, given by\n\n    y = artanh(beta*cos(delta))\n\nwhere \n\n    beta = p/E\n    p = sqrt(pt^2+pz^2)\n    E = sqrt(p^2+m^2)\n    tan(delta) = pt/pz = 1/zr\n\nwith particle mass `m`. It is related to the pseudorapidity\n\n    eta = arsinh(1/tan(delta)) = arsinh(zr)\n\nby\n\n    y = arsinh(zr/k)\n\nwith\n\n    k = sqrt(1+m^2/pt^2)\n\nIf `pt&gt;&gt;m`, then `y--&gt;eta`.\n\nFrom the references I have seen like \n\nhttps://www.physics.umd.edu/hep/drew/Baden_jets_kinematics_dec_2008.pdf (p. 12)\n\nhttps://warwick.ac.uk/fac/sci/physics/staff/academic/gershon/gradteaching/warwickweek/material/lhcphysics/chill_warwick_lhc_2010_1.pdf (p.27)\n\nit seems the particle creation is really constant in the rapidity `y`, not the pseudorapidity `eta`.\n\nThis means that there is a rescaling involved, like in your case, but the following is a bit strange: in the formula for `y` above the number `k` is always `&gt;=1`, but in your case it is `0.7&lt;1`. In addition, one expects the distribution for `eta = arsinh(zr)` to have a dip around `eta = 0`, like in the diagram on page 20 of the first reference, not a hill like in your case.\n\nI don't understand this at the moment, perhaps there is a mistake in the conversions above. I will think about it.\n\n\n",
          "votes": 1
        },
        {
          "id": 371406,
          "postDate": "2018-08-16T18:31:20.903Z",
          "content": "<p>Mark,</p>\n\n<p>bear in mind that we are dealing with simulated data.  Maybe you just uncovered a discrepancy between the simulator and reality?</p>",
          "rawMarkdown": "Mark,\n\nbear in mind that we are dealing with simulated data.  Maybe you just uncovered a discrepancy between the simulator and reality?"
        },
        {
          "id": 371418,
          "postDate": "2018-08-16T19:07:50.777Z",
          "content": "<p>Yes, I know, the data is simulated. </p>\n\n<p>Whether we found a discrepancy with reality - let's see. I started reading about rapidities yesterday and the formulas with <code>sinh</code> etc. can be error prone... I need to check the formulas and the literature again.</p>\n\n<p>But I think your formula with <code>arsinh(zr)</code> is not an coincidence, there should be something behind it.</p>",
          "rawMarkdown": "Yes, I know, the data is simulated. \n\nWhether we found a discrepancy with reality - let's see. I started reading about rapidities yesterday and the formulas with `sinh` etc. can be error prone... I need to check the formulas and the literature again.\n\nBut I think your formula with `arsinh(zr)` is not an coincidence, there should be something behind it."
        },
        {
          "id": 371439,
          "postDate": "2018-08-16T19:57:50.657Z",
          "content": "<p>By the way: If <code>N</code> is the number of particles, the distributions are related by</p>\n\n<pre><code>dN/deta = dN/dy * cosh(eta)/sqrt(m^2/pt^2 + cosh^2(eta))\n</code></pre>\n\n<p>If we assume that <code>dN/dy</code>is constant, then the function <code>dN/deta</code> is determined by the second factor, which is <code>&lt;1</code> for <code>eta = 0</code> and goes to <code>1</code> for <code>|eta|</code> large. That is the dip one should see in the diagram for <code>arsinh(zr)</code>.</p>",
          "rawMarkdown": "By the way: If `N` is the number of particles, the distributions are related by\n\n    dN/deta = dN/dy * cosh(eta)/sqrt(m^2/pt^2 + cosh^2(eta))\n\nIf we assume that `dN/dy`is constant, then the function `dN/deta` is determined by the second factor, which is `&lt;1` for `eta = 0` and goes to `1` for `|eta|` large. That is the dip one should see in the diagram for `arsinh(zr)`.\n\n"
        },
        {
          "id": 371453,
          "postDate": "2018-08-16T20:33:26.847Z",
          "content": "<p>Are you referring to the dip in the plot page 20 of the first reference ? Be careful that this is not a distribution. It only shows the curves of beta vs eta for different Pt for a pion, m=0.140gev. </p>\n\n<p>In most cases we are using the pseudo rapidity eta which is indeed flatish, but which can be sculpted by many effects. Honestly, we did not think it could be of any use for track finding, and it takes time to get used to this strange variable.  </p>",
          "rawMarkdown": "Are you referring to the dip in the plot page 20 of the first reference ? Be careful that this is not a distribution. It only shows the curves of beta vs eta for different Pt for a pion, m=0.140gev. \n\nIn most cases we are using the pseudo rapidity eta which is indeed flatish, but which can be sculpted by many effects. Honestly, we did not think it could be of any use for track finding, and it takes time to get used to this strange variable.  ",
          "votes": 1
        },
        {
          "id": 371476,
          "postDate": "2018-08-16T22:07:39.550Z",
          "content": "<p>@ David Rousseau Thanks for your message!</p>\n\n<p>Yes, if I understand it correctly, the function <code>beta(eta) = dy/deta</code>is called the Jacobian in some references, because it relates the rapidity distribution <code>dN/dy</code> and pseudorapidity distribution <code>dN/deta</code>.</p>\n\n<p>I honestly just tried to make sense out of the curious fact (not primarily regarding track finding) that CPMP's formula</p>\n\n<pre><code>arsinh(zr / 0.7) / 3.5\n</code></pre>\n\n<p>led to a uniform distribution and some Google search showed it could be related to (pseudo-)rapidity.</p>\n\n<p>But I notice I am walking on shaky ground here!</p>",
          "rawMarkdown": "@ David Rousseau Thanks for your message!\n\nYes, if I understand it correctly, the function `beta(eta) = dy/deta`is called the Jacobian in some references, because it relates the rapidity distribution `dN/dy` and pseudorapidity distribution `dN/deta`.\n\nI honestly just tried to make sense out of the curious fact (not primarily regarding track finding) that CPMP's formula\n\n    arsinh(zr / 0.7) / 3.5\n\nled to a uniform distribution and some Google search showed it could be related to (pseudo-)rapidity.\n\nBut I notice I am walking on shaky ground here!"
        },
        {
          "id": 374220,
          "postDate": "2018-08-22T16:16:15.343Z",
          "content": "<p>@Mark, I found that when I restrict the data to be the hits of tracks originating from the z axis, then non scaled arcsinh is best.  It means my code can be improved by removing the scaling probably...</p>",
          "rawMarkdown": "@Mark, I found that when I restrict the data to be the hits of tracks originating from the z axis, then non scaled arcsinh is best.  It means my code can be improved by removing the scaling probably..."
        },
        {
          "id": 374243,
          "postDate": "2018-08-22T16:52:30.057Z",
          "content": "<p>@CPMP, thanks, that's interesting.</p>",
          "rawMarkdown": "@CPMP, thanks, that's interesting."
        },
        {
          "id": 374580,
          "postDate": "2018-08-23T10:22:43.883Z",
          "content": "<p>What is funny is that with unscaled arcsinh my local score climbs faster, but plateaus earlier.  Maybe I need to tune the value of eps for DBSCAN again, but I won't ;)  Just to say that this is not a clear win.</p>",
          "rawMarkdown": "What is funny is that with unscaled arcsinh my local score climbs faster, but plateaus earlier.  Maybe I need to tune the value of eps for DBSCAN again, but I won't ;)  Just to say that this is not a clear win."
        }
      ]
    },
    {
      "id": 370661,
      "postDate": "2018-08-15T08:28:14.233Z",
      "content": "<p>By the way almost everyone used </p>\n\n<pre><code>phi = arctan(y/x)\n</code></pre>\n\n<p>It's not quite right, since (x, y) and (-x, -y) give the same angle, but they should differ by Pi. I used</p>\n\n<pre><code>def calc_phi(hits_row):\nif hits_row['y'] &gt;= 0:\n    return math.acos(hits_row['x'] / hits_row['r2'])\nelse:\n    return 2 * math.pi - math.acos(hits_row['x'] / hits_row['r2'])\n</code></pre>\n\n<p>For some reason it seems doesn't matter for a score.</p>",
      "rawMarkdown": "By the way almost everyone used \n\n    phi = arctan(y/x)\n\nIt's not quite right, since (x, y) and (-x, -y) give the same angle, but they should differ by Pi. I used\n\n    def calc_phi(hits_row):\n    if hits_row['y'] &gt;= 0:\n        return math.acos(hits_row['x'] / hits_row['r2'])\n    else:\n        return 2 * math.pi - math.acos(hits_row['x'] / hits_row['r2'])\n\nFor some reason it seems doesn't matter for a score.",
      "replies": [
        {
          "id": 370666,
          "postDate": "2018-08-15T08:54:23.220Z",
          "content": "<p>arctan2(y,x) in most libraries including np does the job</p>",
          "rawMarkdown": "arctan2(y,x) in most libraries including np does the job",
          "votes": 2
        },
        {
          "id": 370670,
          "postDate": "2018-08-15T09:04:06.723Z",
          "content": "<p>@David Rousseau\nThanks, I didn't know that arctan2 can do that. I had to check the documentation for this function.</p>",
          "rawMarkdown": "@David Rousseau\nThanks, I didn't know that arctan2 can do that. I had to check the documentation for this function."
        },
        {
          "id": 370725,
          "postDate": "2018-08-15T10:57:48.767Z",
          "content": "<p>@Sergey Zlobin, I was doing the same thing as you earlier until I saw np.arctan2(y,x) used in one of the kernels, I checked it out and discovered it works.</p>",
          "rawMarkdown": "@Sergey Zlobin, I was doing the same thing as you earlier until I saw np.arctan2(y,x) used in one of the kernels, I checked it out and discovered it works.",
          "votes": 1
        }
      ]
    },
    {
      "id": 371940,
      "postDate": "2018-08-17T21:32:53.583Z",
      "rawMarkdown": "",
      "isDeleted": true
    },
    {
      "id": 370422,
      "postDate": "2018-08-14T19:52:40.967Z",
      "rawMarkdown": "",
      "votes": 1,
      "isDeleted": true
    }
  ],
  "comments": [
    {
      "id": 370324,
      "author_name": "bestfitting",
      "author_url": "",
      "post_date": "2018-08-14T16:09:56.577000",
      "content": "<p>Thanks for you sharing,My solution is also based on DBScan and I also have no time to finish:\"Use direction information from cells data and Extend to tracks that do not pass near z axis\",but I fitted helix to extend the tracks.I also used the tips from Heng to find candicate hits and desinged a  LGBM model to classify the candidates.</p>",
      "votes": 4,
      "replies": [
        {
          "id": 370361,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-14T17:33:31.113000",
          "content": "<p>Yes, track extension was definitely a miss for me.  Congrats on your result, even if you passed me at the last minute ;)</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 376482,
      "author_name": "CPMP",
      "author_url": "",
      "post_date": "2018-08-27T15:45:48.820000",
      "content": "<p>Final code and documentation is available on github: <a href=\"https://github.com/jfpuget/Kaggle_TrackML\">https://github.com/jfpuget/Kaggle_TrackML</a></p>\n\n<p>I found why my local score was higher than the LB: I forgot to use the magnetic field correction in one model... Once fixed local score and LB score become much closer, with a difference smaller than 0.001.  I document and share code for the fixed models.</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 375535,
      "author_name": "hengck23",
      "author_url": "",
      "post_date": "2018-08-25T11:47:44.500000",
      "content": "<p>@CPMP</p>\n\n<p>Thanks for the solution. It is a nice piece of work!</p>",
      "votes": 1,
      "replies": [
        {
          "id": 375611,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-25T15:59:31.750000",
          "content": "<p>Thanks you Heng! </p>\n\n<p>Your remark about supervised learning being mandatory for reaching 0.8 has been a driver for me!</p>\n\n<p>It is a pity you did not had time to submit a good solution at the end.  I was surprised, as many of us, to not see you above 0.8 at the end.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 375637,
          "author_name": "hengck23",
          "author_url": "",
          "post_date": "2018-08-25T17:17:48.230000",
          "content": "<p>i have some urgent project at work the last minute. I will be continuing this in the speed phase if time permits. Right now, i am at the TGS salt identification competition, do come and take a look!</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 375656,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-25T17:59:06.563000",
          "content": "<p>I am considering TGS or Airbus as my next ones ;)</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 374054,
      "author_name": "CPMP",
      "author_url": "",
      "post_date": "2018-08-22T11:13:16.807000",
      "content": "<p>I have put some code on <a href=\"https://github.com/jfpuget/Kaggle_TrackML\">github</a> </p>\n\n<p>This is work in progress, the repo should be final by Monday.  </p>\n\n<p>The code computes something that should give a LB above 0.78.  I'm running it as of now to see what score exactly this yields.</p>\n\n<p>Cleaning my code revealed few little glitches that explain why my LB score was below my local score.  I hope the code on github fixes that.</p>",
      "votes": 1,
      "replies": [
        {
          "id": 374326,
          "author_name": "YaGana Sheriff-Hussaini",
          "author_url": "",
          "post_date": "2018-08-22T20:29:13.680000",
          "content": "<p>@CPMP thanks  so much for sharing. </p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 372564,
      "author_name": "Siddharth Yadav",
      "author_url": "",
      "post_date": "2018-08-19T18:01:32.607000",
      "content": "<p>Congratulations, CPMP! I always learn great things from your posts.</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 371557,
      "author_name": "Sergey Zlobin",
      "author_url": "",
      "post_date": "2018-08-17T05:10:42.380000",
      "content": "<p>I'm trying to understand how I can get a better score. You have many improvements, probably every step give you a boost. \nAnyway, Yuval said that's easy yo get 0.7 with right features. I tried his approach with the normal distribution but didn't get a better score. And my features are standard: cos, sin, zr and arctan(zr)  (I noticed that zr is helpful also together with arctan).</p>\n\n<blockquote>\n  <p>The formula to compute C is given in the documents from CERN but I estimated it from the train data via a linear regression. That's the only use of supervised learning I made</p>\n</blockquote>\n\n<p>I don't understand why you need this. Features doesn't involved this constant and you don't have px, py, pz in the test data.</p>\n\n<blockquote>\n  <p>Using number of volumes is way more effective than using the number of hits in the track. </p>\n</blockquote>\n\n<p>Probably this gave you a good boost, right? I used the number of hits.</p>\n\n<blockquote>\n  <p>The extra mileage I got comes for a simple idea: run another, similar model, on the inner volumes only (7, 8, and 9). </p>\n</blockquote>\n\n<p>I used this also in my solution. I constructed tracks inside r &lt; 200 (you can also use cells there). Then I used DBSCAN for all hits but verifying tracks by \"the first half\" of tracks found earlier.</p>",
      "votes": 1,
      "replies": [
        {
          "id": 371568,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-17T06:11:21.517000",
          "content": "<blockquote>\n  <p>I don't understand why you need this. </p>\n</blockquote>\n\n<p>You can do without.  I use it when sampling. I sample pt and pz from the tracks in train data, compute r0 from pt instead of having to compute it from the hits in each track.  It is faster.</p>\n\n<blockquote>\n  <p>Probably this gave you a good boost, right? </p>\n</blockquote>\n\n<p>Everything I documented gave me a boost ;)  This one gave me at least 0.02 and probably more.  I did not measure its effect separately  because I first replaced the number of hits by the number of layers, got a boost, then replaced the number of layers by the number of volumes, and again got a boost.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 371575,
          "author_name": "Sergey Zlobin",
          "author_url": "",
          "post_date": "2018-08-17T06:29:27.707000",
          "content": "<blockquote>\n  <p>compute r0 from pt instead of having to compute it from the hits in each track. </p>\n</blockquote>\n\n<p>Ah, I see.</p>\n\n<blockquote>\n  <p>My code loops over z0, r0 pairs.</p>\n</blockquote>\n\n<p>Do you have fixed (z0, r0) pairs unlike Yuval's randomness? \nAnd you don't use StandardScaler, right? \nSorry, if your code is shared, I woudn't ask. :)</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 371651,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-17T10:11:32.967000",
          "content": "<p>As I wrote: </p>\n\n<blockquote>\n  <p>My code loops over z0, r0 pairs. Rather than estimating a distribution I just sample from the tracks in the first 100 train samples. </p>\n</blockquote>\n\n<p>I collected all the <code>(z0, pt)</code> pairs from the train events I'm considering, then turned these into <code>(z0, r0)</code> pairs via the use of the <code>C</code> constant above.  Then I draw one pair randomly at each iteration of the main loop.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 373322,
          "author_name": "Sergey Zlobin",
          "author_url": "",
          "post_date": "2018-08-21T07:02:59.427000",
          "content": "<blockquote>\n  <p>The formula to compute C is given in the documents from CERN</p>\n</blockquote>\n\n<p>I think the formula is something like pt/(q*B).  For some reason a particle charge 'q' have only +-1 values, so we can ignore them. Otherwise it would be proportional to pt/q.</p>\n\n<blockquote>\n  <p>but I estimated it from the train data via a linear regression. </p>\n</blockquote>\n\n<p>I think there's something you're not saying. ;) We have no the truth 'r0' value. Do use a certain formula or an approximation?</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 373443,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-21T11:31:10.090000",
          "content": "<p>Right, i did not explain how I compute r0 for enought tracks to be able to compute the <code>C</code> constant.</p>\n\n<p>Your questions (and all questions on this topic) will make my final document better.  Thanks for that!</p>\n\n<p>I use the conformal representation that was described in one of the documents shared on the forum, with coordinates <code>x/rt, y/rt</code> where <code>rt = sqrt(x^2 + y^2)</code></p>\n\n<p>In that representation, circles going through the origin are straight lines.  With little math I found that the distance of this line to the origin is <code>alpha0 = 1/r0</code>.  That's how I found the radius of the helix.</p>\n\n<p>There are many ways to compute the radius of a circle once you have 3 points on it (the origin, and 2 points on the track). I could have used another one, for instance: <a href=\"https://math.stackexchange.com/questions/133638/how-does-this-equation-to-find-the-radius-from-3-points-actually-work\">https://math.stackexchange.com/questions/133638/how-does-this-equation-to-find-the-radius-from-3-points-actually-work</a></p>\n\n<p>Another question you had I did not answered: I am not using standard scaler.</p>\n\n<p>I will share my code before the deadline set by organizers, your quest will be over soon ;)  Reason it takes time is that I am on vacation...</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 373464,
          "author_name": "Sergey Zlobin",
          "author_url": "",
          "post_date": "2018-08-21T12:04:27.030000",
          "content": "<p>@CPMP Thanks for the answer! Now it's clear.</p>\n\n<p>By the way do you know why q is -1 or +1? The CERN document says</p>\n\n<blockquote>\n  <p>the charge as multiple of the absolute electron charge</p>\n</blockquote>\n\n<p>It's strange to me we have no particles with a charge more than 1.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 373492,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-21T12:47:16.113000",
          "content": "<p>I don't know the physics here, better ask the organisers than me!</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 373721,
          "author_name": "David Rousseau",
          "author_url": "",
          "post_date": "2018-08-21T19:50:43.110000",
          "content": "<p>q=+1 or -1 : charged  particles created in proton collision are mostly charged pions, charged kaons, electron, muons, protons (and their anti particles), which all have charge +/- 1. In the real collisions we might have very rarely alpha particles (or helium nucleus) of charge +2.  In other apparatus, like a mass spectrometer, one can have very large positive charge. </p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 373733,
          "author_name": "Sergey Zlobin",
          "author_url": "",
          "post_date": "2018-08-21T20:16:48.653000",
          "content": "<blockquote>\n  <p>which all have charge +/- 1.</p>\n</blockquote>\n\n<p>Great! Thanks for the answer! <br>\nI think there are also particles with a zero charge. For example, kaons. We don't have it too. </p>\n\n<blockquote>\n  <p>In the real collisions we might have very rarely alpha particles (or helium nucleus) of charge +2</p>\n</blockquote>\n\n<p>In the real collisions, but not in our simulations, right? Though I didn't check all events. :)</p>\n\n<p>It's funny I think about it only after the competition. :) That's because I didn't use ground truth initial values...</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 371059,
      "author_name": "Edwin Steiner",
      "author_url": "",
      "post_date": "2018-08-15T21:57:19.007000",
      "content": "<p>@CPMP, I'm wondering about your plot of the angle differences due to the magnetic field. You write it is as a function of z, but is your z-axis rescaled? The axis seems to go only from -300 to +300. Did you convert to cm?</p>\n\n<p>I'm interested because of the large peaks in the curve. Do they coincide with the first large caps closest to the large cylinders? I ask because I think I saw some anomalies exactly at (and only at) these first (innermost) large caps.</p>\n\n<p>You curve also has a peaked feature at the positive z-end, which matches with the strange features of the B field visible in my plots in the last (outermost) cap towards +z, I think.</p>",
      "votes": 1,
      "replies": [
        {
          "id": 371231,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-16T09:53:37.370000",
          "content": "<p>Yes, it was rescaled, I should have said it, sorry.  Top one is rescaled by 1/10, bottom one by 1/50.</p>\n\n<p>The most striking finding for me is that the variation is not symmetric when you change z sign.</p>\n\n<p>I was also wondering about the peaks, which is why I also plot the number of hits.  The peaks correspond to values of z with a high number of hits.  It is the valleys that are misleading actually.  The second plot is obtained by scaling z further, and removing values of z with a small number of hits.  I did not investigate further than that, because a small number of hits can be safely ignored for my purpose.</p>\n\n<p>I will release an EDA notebook to show how I produced these plots and other ones I found useful during the competition.</p>\n\n<p>I also looked at magnetic field variation as a function of phi, and found some variation, like you.  But I did not model it.  I guess its effect is way smaller than the variation by z.  </p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 370955,
      "author_name": "Kenshiro75",
      "author_url": "",
      "post_date": "2018-08-15T18:13:18.433000",
      "content": "<p>Congratulations and many thanks to share your solutions :-) Not easy competition not only to understand it but mostly for the computational effort !!! </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 370609,
      "author_name": "Alexandra Yakunina",
      "author_url": "",
      "post_date": "2018-08-15T06:12:19.960000",
      "content": "<p>congratulations! and thanks for sharing your approach</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 370472,
      "author_name": "John Sweeney",
      "author_url": "",
      "post_date": "2018-08-14T21:40:06.623000",
      "content": "<p>For zr, the math says use arctan to convert to a physically meaningful angle.  How did you ever come up with the idea of using a scaled inverse hyperbolic sine?</p>",
      "votes": 1,
      "replies": [
        {
          "id": 370583,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-15T04:24:02.740000",
          "content": "<p>I looked for functions that were similar to tan(), i.e. that had infinite limits in a closed interval.  sinh() was the first function I looked at, and its distribution looked very similar to that of zr. </p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 371072,
          "author_name": "Mark JD Hamilton",
          "author_url": "",
          "post_date": "2018-08-15T23:15:38.377000",
          "content": "<p>@CPMP Thanks for sharing your result and congratulations to gold!</p>\n\n<p>If one converts <code>zr</code> using <code>arctan</code>, one gets the angle between <code>pt</code> and <code>pz</code>, but this angle is probably not of uniform distribution for the events in a particle collider.</p>\n\n<p>In fact, I found something quite interesting:</p>\n\n<p><a href=\"https://en.m.wikipedia.org/wiki/Pseudorapidity\">https://en.m.wikipedia.org/wiki/Pseudorapidity</a></p>\n\n<p>There is a number in particle physics, called pseudorapidity, given by</p>\n\n<pre><code>eta = -ln(tan(delta/2))\n</code></pre>\n\n<p>where</p>\n\n<pre><code>tan(delta) = pt/pz = 1/zr\n</code></pre>\n\n<p>This can also be written as</p>\n\n<pre><code>eta = arsinh(1/tan(delta)) = arsinh(zr)\n</code></pre>\n\n<p>The interesting thing is that according to the Wikipedia article (and papers that can be found via Google) in hadron colliders \"particle production is constant as a function of rapidity\" (approximately).</p>\n\n<p>It seems like you found exactly the right formula that makes <code>zr</code> uniformly distributed! (except for the factor 1/0.7 which I do not understand right now and could be related to particle masses, the factor 1/3.5 is probably not so important).</p>",
          "votes": 3,
          "replies": []
        },
        {
          "id": 371234,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-16T10:01:28.047000",
          "content": "<p>Wow, thanks for sharing.  I'm impressed I discovered something that is linked to a known physics law.  In a way it is reassuring that this is not just a computation artifact.</p>\n\n<p>The 0.7 factor makes the distribution even more uniform, but results without it were already quite good.  I'll share plots with and without 0.7 scaling ASAP.</p>\n\n<p>The 3.5 factor is just to scale the result to the same scale as the other two features I am using for clustering.  </p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 371240,
          "author_name": "YaGana Sheriff-Hussaini",
          "author_url": "",
          "post_date": "2018-08-16T10:26:00.447000",
          "content": "<p>@Mark JD Hamilton great find and thanks for sharing.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 370335,
      "author_name": "Edwin Steiner",
      "author_url": "",
      "post_date": "2018-08-14T16:43:40.443000",
      "content": "<p>@CPMP, congratulations on reaching your goal of 0.80! I was rooting for you to make it in the final hours before the deadline.</p>\n\n<p>Your solutions looks very elegant. Definitely one of the best score per codelines ratios, I guess.</p>\n\n<p>Yes, all the ensemble clustering approaches would have no chance against the combinatoric/geometric ones in the throughput phase. However, the features you developed and your track quality metric could be interesting to incorporate for track evaluation even in combinatoric solutions.</p>",
      "votes": 1,
      "replies": [
        {
          "id": 370365,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-14T17:35:45.077000",
          "content": "<p>Glad you find it interesting.  And even happier if some of my work is reused in stage 2.  </p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 370385,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-14T18:15:27.007000",
          "content": "<p>And thanks for rooting for me!</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 370129,
      "author_name": "Blonde",
      "author_url": "",
      "post_date": "2018-08-14T10:24:29.003000",
      "content": "<p>Thank you for sharing! And special thank you for the post on paralleling, it gave me a great boost once I managed to do it (better late than never :))</p>",
      "votes": 1,
      "replies": [
        {
          "id": 370130,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-14T10:25:20.847000",
          "content": "<p>Glad what i shared helped you.  I'll try to share earlier next time ;)</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 370021,
      "author_name": "YaGana Sheriff-Hussaini",
      "author_url": "",
      "post_date": "2018-08-14T05:21:35.613000",
      "content": "<p>Congratulations @CPMP on gaining another gold metal and thanks for sharing your solution.</p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 370953,
      "author_name": "yuval reina",
      "author_url": "",
      "post_date": "2018-08-15T18:04:22.343000",
      "content": "<p>@CPMP in the formula:</p>\n\n<p><code>zr =  (z - z0) / (2 * r0 * phi0)</code></p>\n\n<p>didn't you mean</p>\n\n<pre><code> zr =  (z - z0) / (2 * r0 * theta0)\n</code></pre>",
      "votes": 2,
      "replies": [
        {
          "id": 370956,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-15T18:13:28.143000",
          "content": "<p>Good catch, thanks!</p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 370958,
          "author_name": "yuval reina",
          "author_url": "",
          "post_date": "2018-08-15T18:18:25.143000",
          "content": "<p>Just trying to plug your magnetic field fix to my solution to see what I'll get, but can't make it work, yet.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 370964,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-15T18:30:41.613000",
          "content": "<p>I'll share my code soon, in case my writeup missed something relevant.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 370967,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-15T18:34:46.710000",
          "content": "<p>I remember now, you must use the theta0 correction only for computing phi0, but not for computing zr.  </p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 370983,
          "author_name": "yuval reina",
          "author_url": "",
          "post_date": "2018-08-15T18:57:01.477000",
          "content": "<p>WoW.  plugged it in. used a short run (as is in my kernel) expanded, and got LB 0.785! I wonder what I'll get with the long run (100K points) .</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 370995,
          "author_name": "John Sweeney",
          "author_url": "",
          "post_date": "2018-08-15T19:23:42.183000",
          "content": "<p>I tried 2 parts last night...  I used observed r0,z0 values  from EDA as my random values &amp; replaced arctan2 with arcsinh for zr.  r0,z0 seemed to have an improvement between 0.005 - 0.01 ( more than I expected).  Could not get arcsinh to yield any improvement...so maybe I'm doing something wrong.  Didn't try the theta0 adjustment, but now I will 😀</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 371020,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-15T20:34:24.343000",
          "content": "<p>&gt; WoW. plugged it in. used a short run (as is in my kernel) expanded, and got LB 0.785! </p>\n\n<p>Great!</p>\n\n<p>The downside is that track extension becomes less effective. In my case, my track extension, based on Heng's code, became totally useless.  You're using a more elaborate way with a supervised ML approach.  Maybe you can get some upside.</p>\n\n<p>Anyway, it is good to know that this correction improves your code.  You may bet better results than mine in a fraction of time.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 371030,
          "author_name": "yuval reina",
          "author_url": "",
          "post_date": "2018-08-15T21:06:21.003000",
          "content": "<p><em>*</em> correction **\"\nI had a bug in my code it is \"only\" 0.76 with the short run and 0.785 with the long one.\nStill a 0.02 improvement </p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 371053,
          "author_name": "Edwin Steiner",
          "author_url": "",
          "post_date": "2018-08-15T21:46:50.967000",
          "content": "<blockquote>\n  <p>Still a 0.02 improvement</p>\n</blockquote>\n\n<p>I think that is roughly consistent with my own experience. As mentioned, I got about +0.01 from accounting for the systematic deviations due to the inhomogenous B field. It makes sense that it helps more in your case because your approach is more sensitive to variations in the helix parameters along a track, but it's still the same (small) order of magnitude.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 371226,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-16T09:23:36.627000",
          "content": "<p>Mine was improved by 0.03</p>\n\n<p>Not sure why it was more effective for me.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 371248,
          "author_name": "Edwin Steiner",
          "author_url": "",
          "post_date": "2018-08-16T10:42:24.647000",
          "content": "<blockquote>\n  <p>Mine was improved by 0.03</p>\n</blockquote>\n\n<p>Interesting. Either it's the different sensitivity of the algorithms to perturbations of the helices, or I missed something in my implementation of the corrections.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 375722,
      "author_name": "Mukharbek Organokov",
      "author_url": "",
      "post_date": "2018-08-25T21:47:58.057000",
      "content": "<p>@CPMP really good job. Well done. <a href=\"https://twitter.com/trackmllhc/status/1033277891226820608\">enter link description here</a></p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 370330,
      "author_name": "Mukharbek Organokov",
      "author_url": "",
      "post_date": "2018-08-14T16:29:00.220000",
      "content": "<p>Merci d'avoir partagé cela avec nous. </p>",
      "votes": 1,
      "replies": []
    },
    {
      "id": 374889,
      "author_name": "JR",
      "author_url": "",
      "post_date": "2018-08-24T04:49:07.260000",
      "content": "<p>Any participant (not necessarily with the highest score) who think they made valuable contributions with innovative algorithms (in particular if they have shared insights on the forum) are welcome to release publicly their code with an open source license and lightweight structured documentation. This will allow to compete for the « HEP meets ML » jury prizes: a NVidia V100 GPU, and two invitations to NIPS 2018 or the spring 2019 CERN workshop.See details in forum topic:</p>\n\n<p><a href=\"https://www.kaggle.com/c/trackml-particle-identification/discussion/63289\">https://www.kaggle.com/c/trackml-particle-identification/discussion/63289</a></p>",
      "votes": 0,
      "replies": [
        {
          "id": 375008,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-24T11:14:21.487000",
          "content": "<p>I'll submit, I have started publishing my code.  But I try to enjoy the end of my vacation as well ;),  hence I will submit Monday probably.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 371307,
      "author_name": "CPMP",
      "author_url": "",
      "post_date": "2018-08-16T13:57:25.937000",
      "content": "<p>Following up on the <a href=\"https://www.kaggle.com/c/trackml-particle-identification/discussion/63250#371072\">excellent find by Mark JD Hamilton</a>, here is a plot of <code>arcsinh(zr)</code>.  While quite uniform, it is not as uniform as the scaled version I used.</p>\n\n<p><img src=\"https://storage.googleapis.com/kaggle-forum-message-attachments/371307/10098/asinh2.png\" alt=\"arcsinh\"></p>",
      "votes": 0,
      "replies": [
        {
          "id": 371385,
          "author_name": "Mark JD Hamilton",
          "author_url": "",
          "post_date": "2018-08-16T17:32:55.883000",
          "content": "<p>Thanks for the diagram!</p>\n\n<p>I did a bit more research (which needs to be taken with a caveat, since I am not a particle physicist): There is another number, called rapidity, given by</p>\n\n<pre><code>y = artanh(beta*cos(delta))\n</code></pre>\n\n<p>where </p>\n\n<pre><code>beta = p/E\np = sqrt(pt^2+pz^2)\nE = sqrt(p^2+m^2)\ntan(delta) = pt/pz = 1/zr\n</code></pre>\n\n<p>with particle mass <code>m</code>. It is related to the pseudorapidity</p>\n\n<pre><code>eta = arsinh(1/tan(delta)) = arsinh(zr)\n</code></pre>\n\n<p>by</p>\n\n<pre><code>y = arsinh(zr/k)\n</code></pre>\n\n<p>with</p>\n\n<pre><code>k = sqrt(1+m^2/pt^2)\n</code></pre>\n\n<p>If <code>pt&gt;&gt;m</code>, then <code>y--&gt;eta</code>.</p>\n\n<p>From the references I have seen like </p>\n\n<p><a href=\"https://www.physics.umd.edu/hep/drew/Baden_jets_kinematics_dec_2008.pdf\">https://www.physics.umd.edu/hep/drew/Baden_jets_kinematics_dec_2008.pdf</a> (p. 12)</p>\n\n<p><a href=\"https://warwick.ac.uk/fac/sci/physics/staff/academic/gershon/gradteaching/warwickweek/material/lhcphysics/chill_warwick_lhc_2010_1.pdf\">https://warwick.ac.uk/fac/sci/physics/staff/academic/gershon/gradteaching/warwickweek/material/lhcphysics/chill_warwick_lhc_2010_1.pdf</a> (p.27)</p>\n\n<p>it seems the particle creation is really constant in the rapidity <code>y</code>, not the pseudorapidity <code>eta</code>.</p>\n\n<p>This means that there is a rescaling involved, like in your case, but the following is a bit strange: in the formula for <code>y</code> above the number <code>k</code> is always <code>&gt;=1</code>, but in your case it is <code>0.7&lt;1</code>. In addition, one expects the distribution for <code>eta = arsinh(zr)</code> to have a dip around <code>eta = 0</code>, like in the diagram on page 20 of the first reference, not a hill like in your case.</p>\n\n<p>I don't understand this at the moment, perhaps there is a mistake in the conversions above. I will think about it.</p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 371406,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-16T18:31:20.903000",
          "content": "<p>Mark,</p>\n\n<p>bear in mind that we are dealing with simulated data.  Maybe you just uncovered a discrepancy between the simulator and reality?</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 371418,
          "author_name": "Mark JD Hamilton",
          "author_url": "",
          "post_date": "2018-08-16T19:07:50.777000",
          "content": "<p>Yes, I know, the data is simulated. </p>\n\n<p>Whether we found a discrepancy with reality - let's see. I started reading about rapidities yesterday and the formulas with <code>sinh</code> etc. can be error prone... I need to check the formulas and the literature again.</p>\n\n<p>But I think your formula with <code>arsinh(zr)</code> is not an coincidence, there should be something behind it.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 371439,
          "author_name": "Mark JD Hamilton",
          "author_url": "",
          "post_date": "2018-08-16T19:57:50.657000",
          "content": "<p>By the way: If <code>N</code> is the number of particles, the distributions are related by</p>\n\n<pre><code>dN/deta = dN/dy * cosh(eta)/sqrt(m^2/pt^2 + cosh^2(eta))\n</code></pre>\n\n<p>If we assume that <code>dN/dy</code>is constant, then the function <code>dN/deta</code> is determined by the second factor, which is <code>&lt;1</code> for <code>eta = 0</code> and goes to <code>1</code> for <code>|eta|</code> large. That is the dip one should see in the diagram for <code>arsinh(zr)</code>.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 371453,
          "author_name": "David Rousseau",
          "author_url": "",
          "post_date": "2018-08-16T20:33:26.847000",
          "content": "<p>Are you referring to the dip in the plot page 20 of the first reference ? Be careful that this is not a distribution. It only shows the curves of beta vs eta for different Pt for a pion, m=0.140gev. </p>\n\n<p>In most cases we are using the pseudo rapidity eta which is indeed flatish, but which can be sculpted by many effects. Honestly, we did not think it could be of any use for track finding, and it takes time to get used to this strange variable.  </p>",
          "votes": 1,
          "replies": []
        },
        {
          "id": 371476,
          "author_name": "Mark JD Hamilton",
          "author_url": "",
          "post_date": "2018-08-16T22:07:39.550000",
          "content": "<p>@ David Rousseau Thanks for your message!</p>\n\n<p>Yes, if I understand it correctly, the function <code>beta(eta) = dy/deta</code>is called the Jacobian in some references, because it relates the rapidity distribution <code>dN/dy</code> and pseudorapidity distribution <code>dN/deta</code>.</p>\n\n<p>I honestly just tried to make sense out of the curious fact (not primarily regarding track finding) that CPMP's formula</p>\n\n<pre><code>arsinh(zr / 0.7) / 3.5\n</code></pre>\n\n<p>led to a uniform distribution and some Google search showed it could be related to (pseudo-)rapidity.</p>\n\n<p>But I notice I am walking on shaky ground here!</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 374220,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-22T16:16:15.343000",
          "content": "<p>@Mark, I found that when I restrict the data to be the hits of tracks originating from the z axis, then non scaled arcsinh is best.  It means my code can be improved by removing the scaling probably...</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 374243,
          "author_name": "Mark JD Hamilton",
          "author_url": "",
          "post_date": "2018-08-22T16:52:30.057000",
          "content": "<p>@CPMP, thanks, that's interesting.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 374580,
          "author_name": "CPMP",
          "author_url": "",
          "post_date": "2018-08-23T10:22:43.883000",
          "content": "<p>What is funny is that with unscaled arcsinh my local score climbs faster, but plateaus earlier.  Maybe I need to tune the value of eps for DBSCAN again, but I won't ;)  Just to say that this is not a clear win.</p>",
          "votes": 0,
          "replies": []
        }
      ]
    },
    {
      "id": 370661,
      "author_name": "Sergey Zlobin",
      "author_url": "",
      "post_date": "2018-08-15T08:28:14.233000",
      "content": "<p>By the way almost everyone used </p>\n\n<pre><code>phi = arctan(y/x)\n</code></pre>\n\n<p>It's not quite right, since (x, y) and (-x, -y) give the same angle, but they should differ by Pi. I used</p>\n\n<pre><code>def calc_phi(hits_row):\nif hits_row['y'] &gt;= 0:\n    return math.acos(hits_row['x'] / hits_row['r2'])\nelse:\n    return 2 * math.pi - math.acos(hits_row['x'] / hits_row['r2'])\n</code></pre>\n\n<p>For some reason it seems doesn't matter for a score.</p>",
      "votes": 0,
      "replies": [
        {
          "id": 370666,
          "author_name": "David Rousseau",
          "author_url": "",
          "post_date": "2018-08-15T08:54:23.220000",
          "content": "<p>arctan2(y,x) in most libraries including np does the job</p>",
          "votes": 2,
          "replies": []
        },
        {
          "id": 370670,
          "author_name": "Sergey Zlobin",
          "author_url": "",
          "post_date": "2018-08-15T09:04:06.723000",
          "content": "<p>@David Rousseau\nThanks, I didn't know that arctan2 can do that. I had to check the documentation for this function.</p>",
          "votes": 0,
          "replies": []
        },
        {
          "id": 370725,
          "author_name": "YaGana Sheriff-Hussaini",
          "author_url": "",
          "post_date": "2018-08-15T10:57:48.767000",
          "content": "<p>@Sergey Zlobin, I was doing the same thing as you earlier until I saw np.arctan2(y,x) used in one of the kernels, I checked it out and discovered it works.</p>",
          "votes": 1,
          "replies": []
        }
      ]
    },
    {
      "id": 371940,
      "author_name": "",
      "author_url": "",
      "post_date": "2018-08-17T21:32:53.583000",
      "content": "",
      "votes": 0,
      "replies": []
    },
    {
      "id": 370422,
      "author_name": "",
      "author_url": "",
      "post_date": "2018-08-14T19:52:40.967000",
      "content": "",
      "votes": 1,
      "replies": []
    }
  ],
  "raw_markdown_by_id": {
    "369949": "Did I disclose I have been using DBSCAN?  Well, now you know ;)  \n\nMy approach is quite straightforward and has been almost fully disclosed by @yuval.  An helix that starts from z axis can be described by 4 parameters:\n\n - z at origin `z0`\n - radius `r0`\n - angle at origin in transverse plane (x,y plane) `phi0`\n - slope `zr`\n\nThe last 3 can be expressed as functions of the momentum at origin, `px`, `py`, `pz`, and `pt = sqrt(px² + py²)`:\n\n - `r0 = C * pt`\n - `phi0 = arctan(py/px)`\n - `zr = pz/pt`\n\nThe formula to compute `C` is given in the documents from CERN but I estimated it from the train data via a linear regression. That's the only use of supervised learning I made ;)\n\nMy code loops over `z0, r0` pairs.  Rather than estimating a distribution I just sample from the tracks in the first 100 train samples.  For each pair I 'unroll the helix', i.e. compute `phi0` and `zr` as:\n\n    phi0 = phi +- theta0\n    zr =  (z - z0) / (2 * r0 * theta0)\n\nwhere `rt` is the distance to origin in transverse plane, `phi` the angle in transverse plane, and `theta0` is the unrolling angle:\n\n    rt = sqrt(x² + y²)\n    phi = arctan(y/x)\n    theta0 = arcsin(rt / (2 * r0))\n\nIn one iteration I add `theta0` to `phi`, and in the next iteration I subtract it.\n\nIn order to cope with the discontinuity at `pi` and `-pi` I use `cos(phi0)` and `sin(phi0)`.  \n\nThe distribution of `zr` is highly skewed.  Many have use `arctan` to unskew it, but I found that using `arcsinh` was way more effective.  I actually use:\n\n    arcsinh(zr / 0.7) / 3.5\n\nThe picture below gives the distribution of arctan(zr), and the one below the distribution of arcsinh. The latter is way more uniform.\n\n![arctan distribution][1]\n\n![arcsinh distribution][2]\n\nThe last twist is to model the uneven magnetic field at high values of `z`.  The picture below shows the relative difference between the theoretical angle, and the median of measured angle as a function of `z`, the picture below gives the number of hits in log scale:\n\n![ratio1][3]\n\nThe best way I found was to multiply `theta0` with a correction that depends on `z`:\n\n    1.005 - (abs(z + 200) / 6000)**2.4\n\nThe picture below shows a smoothed average of the median measured angle deviation (in blue), and my correction function (in red):\n\n![ratio][4]\n\nDBSCAN is run at each iteration.  Its output is merged with existing tracks in a simple way: for each track, or candidate track, I compute the number of volumes with hits from the track.  Hits are then assigned to the candidate track with the most volumes.  Using number of volumes is way more effective than using the number of hits in the track.  \n\nAnother criteria is used for deciding which track wins.  I assign a unique `vl_id` to each `volume_id, layer_id` pair.  For each of the first 100 train events I represented each particle track by the sequence of its `vl_id` once data is sorted by `z`.  I then compute the frequency of each sub sequence of 4 `vl_id` .  The quality of each track candidate in test events is computed in a similar way: first create the sequence of its `vl_id` once data is sorted by `z`, then take the average of the log of the frequencies of its sub sequences of length 4, and multiply by the number of volumes of the candidate track.  A hit is assigned to a new candidate track if the new candidate track has both more volumes and  a better quality than the current track of the hit.  This quality is very effective in removing tracks that do not make sense, for instance tracks that skip a layer entirely.   \n\nThe above yields a LB score above 0.785 with about 33000 DBSCAN runs.  It takes about 10 hours per event.\n\nThe extra mileage I got comes for a simple idea: run another, similar model, on the inner volumes only (7, 8, and 9).  This model can be more conservative (smaller eps for DBSCAN) because tracks are closer to perfect helix.  I ran this model for about the same number of iterations, then merged its output with the previous model: tracks that overlap significantly are merged, and for the rest, the track with most volumes wins.\n\nThe very last improvements (about 0.002) come from merging with a third model that is similar to the first one.\n\nThat's it, no fancy math, just lots of tuning.  I hope I have not made errors in the equations, I'll check again tomorrow, but appreciate if you find typos.  They must be correct in the code given the results: the code finds about 95% of the centered tracks.\n\nThings I thought about but did not had time to finish implementing:\n\n - Use direction information from cells data\n - Extend to tracks that do not pass near z axis\n - Fit helix to each track candidate to remove outliers and possibly add missing hits.\n\nI thought my approach would be a nice starting point for second phase, given its simplicity, but I no longer think it is, now that I saw @icecuber solution!\n\n\n  [1]: https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10056/atan1.png\n  [2]: https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10055/asinh.png\n  [3]: https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10052/ratio1.png\n  [4]: https://storage.googleapis.com/kaggle-forum-message-attachments/369949/10053/ratio.png",
    "370324": "Thanks for you sharing,My solution is also based on DBScan and I also have no time to finish:\"Use direction information from cells data and Extend to tracks that do not pass near z axis\",but I fitted helix to extend the tracks.I also used the tips from Heng to find candicate hits and desinged a  LGBM model to classify the candidates.\n",
    "376482": "Final code and documentation is available on github: https://github.com/jfpuget/Kaggle_TrackML\n\nI found why my local score was higher than the LB: I forgot to use the magnetic field correction in one model... Once fixed local score and LB score become much closer, with a difference smaller than 0.001.  I document and share code for the fixed models.",
    "375535": "@CPMP\n \nThanks for the solution. It is a nice piece of work!\n",
    "374054": "I have put some code on [github][1] \n\nThis is work in progress, the repo should be final by Monday.  \n\nThe code computes something that should give a LB above 0.78.  I'm running it as of now to see what score exactly this yields.\n\nCleaning my code revealed few little glitches that explain why my LB score was below my local score.  I hope the code on github fixes that.\n\n\n  [1]: https://github.com/jfpuget/Kaggle_TrackML",
    "372564": "Congratulations, CPMP! I always learn great things from your posts.",
    "371557": "I'm trying to understand how I can get a better score. You have many improvements, probably every step give you a boost. \nAnyway, Yuval said that's easy yo get 0.7 with right features. I tried his approach with the normal distribution but didn't get a better score. And my features are standard: cos, sin, zr and arctan(zr)  (I noticed that zr is helpful also together with arctan).\n\n&gt; The formula to compute C is given in the documents from CERN but I estimated it from the train data via a linear regression. That's the only use of supervised learning I made\n\nI don't understand why you need this. Features doesn't involved this constant and you don't have px, py, pz in the test data.\n\n&gt; Using number of volumes is way more effective than using the number of hits in the track. \n\nProbably this gave you a good boost, right? I used the number of hits.\n\n&gt; The extra mileage I got comes for a simple idea: run another, similar model, on the inner volumes only (7, 8, and 9). \n\nI used this also in my solution. I constructed tracks inside r &lt; 200 (you can also use cells there). Then I used DBSCAN for all hits but verifying tracks by \"the first half\" of tracks found earlier.",
    "371059": "@CPMP, I'm wondering about your plot of the angle differences due to the magnetic field. You write it is as a function of z, but is your z-axis rescaled? The axis seems to go only from -300 to +300. Did you convert to cm?\n\nI'm interested because of the large peaks in the curve. Do they coincide with the first large caps closest to the large cylinders? I ask because I think I saw some anomalies exactly at (and only at) these first (innermost) large caps.\n\nYou curve also has a peaked feature at the positive z-end, which matches with the strange features of the B field visible in my plots in the last (outermost) cap towards +z, I think.",
    "370955": "Congratulations and many thanks to share your solutions :-) Not easy competition not only to understand it but mostly for the computational effort !!! ",
    "370609": "congratulations! and thanks for sharing your approach",
    "370472": "For zr, the math says use arctan to convert to a physically meaningful angle.  How did you ever come up with the idea of using a scaled inverse hyperbolic sine?",
    "370335": "@CPMP, congratulations on reaching your goal of 0.80! I was rooting for you to make it in the final hours before the deadline.\n\nYour solutions looks very elegant. Definitely one of the best score per codelines ratios, I guess.\n\nYes, all the ensemble clustering approaches would have no chance against the combinatoric/geometric ones in the throughput phase. However, the features you developed and your track quality metric could be interesting to incorporate for track evaluation even in combinatoric solutions.",
    "370129": "Thank you for sharing! And special thank you for the post on paralleling, it gave me a great boost once I managed to do it (better late than never :))",
    "370021": "Congratulations @CPMP on gaining another gold metal and thanks for sharing your solution.",
    "370953": "@CPMP in the formula:\n\n `zr =  (z - z0) / (2 * r0 * phi0)`\n\ndidn't you mean\n\n     zr =  (z - z0) / (2 * r0 * theta0)",
    "375722": "@CPMP really good job. Well done. [enter link description here][1]\n\n\n  [1]: https://twitter.com/trackmllhc/status/1033277891226820608",
    "370330": "Merci d'avoir partagé cela avec nous. ",
    "374889": "Any participant (not necessarily with the highest score) who think they made valuable contributions with innovative algorithms (in particular if they have shared insights on the forum) are welcome to release publicly their code with an open source license and lightweight structured documentation. This will allow to compete for the « HEP meets ML » jury prizes: a NVidia V100 GPU, and two invitations to NIPS 2018 or the spring 2019 CERN workshop.See details in forum topic:\n\nhttps://www.kaggle.com/c/trackml-particle-identification/discussion/63289",
    "371307": "Following up on the [excellent find by Mark JD Hamilton][1], here is a plot of `arcsinh(zr)`.  While quite uniform, it is not as uniform as the scaled version I used.\n\n![arcsinh][2]\n\n\n  [1]: https://www.kaggle.com/c/trackml-particle-identification/discussion/63250#371072\n  [2]: https://storage.googleapis.com/kaggle-forum-message-attachments/371307/10098/asinh2.png",
    "370661": "By the way almost everyone used \n\n    phi = arctan(y/x)\n\nIt's not quite right, since (x, y) and (-x, -y) give the same angle, but they should differ by Pi. I used\n\n    def calc_phi(hits_row):\n    if hits_row['y'] &gt;= 0:\n        return math.acos(hits_row['x'] / hits_row['r2'])\n    else:\n        return 2 * math.pi - math.acos(hits_row['x'] / hits_row['r2'])\n\nFor some reason it seems doesn't matter for a score.",
    "371940": "",
    "370422": ""
  }
}