From 8587d4008f5f324824db0b0e771e596cbfb0df5f Mon Sep 17 00:00:00 2001 From: Jeffrey Newman Date: Mon, 9 Jan 2023 13:10:51 -0600 Subject: [PATCH 1/7] df.get, NL, streaming (#32) * adds processor for `df.get(xxx)` notation * adds streaming data * logit models are maskable (only a subset of rows are evaluated) * when converting dataframe to dataset, duplicate column names are generally not allowed, but if column data is identical then the duplicate column is dropped (this compatibility comes at a cost of some performance and should be avoided if possible) * code now emits `CacheMissWarning` when compile is triggered, this is totally normal and expected on the first pass to compile things, but can give useful information when a function is unexpectedly recompiled (e.g. due to an accidental difference in input dtypes) * intermediate functions are no longer cached, reducing the cache footprint on disk with no impact on performance * ast processing now completes a first pass on each expression with each subspace before cascading down to fallback subspaces, this permits more complex expressions to complete * implements nested logit, `mnl_draws` function name changed to `logit_draw`. * no longer tested for compatibility with Python 3.7 (google colab updated to 3.8) --- .github/workflows/run-tests.yml | 2 +- .pre-commit-config.yaml | 8 +- docs/api.rst | 2 +- docs/walkthrough/one-dim.ipynb | 584 +- docs/walkthrough/two-dim.ipynb | 92 +- envs/development.yml | 1 + envs/testing.yml | 1 + sharrow/__init__.py | 2 +- sharrow/aster.py | 49 +- sharrow/dataset.py | 126 +- sharrow/debug.py | 5 + sharrow/digital_encoding.py | 18 + sharrow/flows.py | 1084 +++- sharrow/logging.py | 9 +- sharrow/nested_logit.py | 194 + sharrow/relationships.py | 246 +- sharrow/selectors.py | 11 +- sharrow/shared_memory.py | 16 +- sharrow/tests/test_nesting.py | 254 + sharrow/tests/test_relationships.py | 336 +- sharrow/tests/test_relationships/test_get.csv | 5001 +++++++++++++++++ sharrow/viz.py | 163 + 22 files changed, 7820 insertions(+), 384 deletions(-) create mode 100644 sharrow/debug.py create mode 100644 sharrow/nested_logit.py create mode 100644 sharrow/tests/test_nesting.py create mode 100644 sharrow/tests/test_relationships/test_get.csv create mode 100644 sharrow/viz.py diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index f0ddd61..7ec36fc 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -18,7 +18,7 @@ jobs: strategy: matrix: os: ["ubuntu-latest", "macos-latest", "windows-latest"] - python-version: ["3.7", "3.9", "3.10"] + python-version: ["3.9", "3.10"] defaults: run: shell: bash -l {0} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 35cc926..333916f 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v4.3.0 hooks: - id: check-yaml - id: end-of-file-fixer @@ -9,7 +9,7 @@ repos: - id: trailing-whitespace - repo: https://github.com/kynan/nbstripout - rev: 0.5.0 + rev: 0.6.1 hooks: - id: nbstripout @@ -20,11 +20,11 @@ repos: args: ["--profile", "black", "--filter-files"] - repo: https://github.com/psf/black - rev: 21.12b0 + rev: 22.10.0 hooks: - id: black - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 + rev: 5.0.4 hooks: - id: flake8 diff --git a/docs/api.rst b/docs/api.rst index 317e985..6389a2c 100644 --- a/docs/api.rst +++ b/docs/api.rst @@ -63,7 +63,7 @@ Dot Logit ~~~~~~~~~ -.. automethod:: sharrow.Flow.mnl_draws +.. automethod:: sharrow.Flow.logit_draws Convenience ~~~~~~~~~~~ diff --git a/docs/walkthrough/one-dim.ipynb b/docs/walkthrough/one-dim.ipynb index 60fc0f0..96ec3f3 100644 --- a/docs/walkthrough/one-dim.ipynb +++ b/docs/walkthrough/one-dim.ipynb @@ -422,7 +422,7 @@ "metadata": {}, "outputs": [], "source": [ - "%time flow.load(compile_watch=True)" + "%time flow.load()" ] }, { @@ -437,7 +437,7 @@ "outputs": [], "source": [ "# TEST utility data\n", - "assert flow.compiled_recently == True\n", + "assert flow.check_cache_misses(fresh=False)\n", "actual = flow.load()\n", "expected = np.array([[ 9.4 , 16.9572 , 4.5 , 0. , 1. ],\n", " [ 9.32 , 14.3628 , 4.5 , 1. , 1. ],\n", @@ -470,7 +470,7 @@ "metadata": {}, "outputs": [], "source": [ - "%time flow.load(compile_watch=True)" + "%time flow.load()" ] }, { @@ -480,8 +480,7 @@ "metadata": {}, "outputs": [], "source": [ - "# test compile flags\n", - "assert flow.compiled_recently == False\n", + "# TEST compile flags\n", "flow.load(compile_watch=False)\n", "import pytest\n", "with pytest.raises(AttributeError):\n", @@ -615,7 +614,7 @@ }, "outputs": [], "source": [ - "# test df\n", + "# TEST df\n", "assert len(df) == len(tours)\n", "pd.testing.assert_index_equal(\n", " df.columns, \n", @@ -784,7 +783,7 @@ "id": "0beb2c18", "metadata": {}, "source": [ - "Given those draws, we use the `mnl_draws` method to build and apply a \n", + "Given those draws, we use the `logit_draws` method to build and apply a \n", "MNL simulator, which returns to us both the choices and the probability that\n", "was computed for each chosen alternative. " ] @@ -796,7 +795,7 @@ "metadata": {}, "outputs": [], "source": [ - "%time choices, choice_probs = flow.mnl_draws(b, draws)" + "%time choices, choice_probs = flow.logit_draws(b, draws)" ] }, { @@ -817,7 +816,7 @@ "metadata": {}, "outputs": [], "source": [ - "%time choices2, choice_probs2 = flow.mnl_draws(b, draws, source=tree_2)" + "%time choices2, choice_probs2 = flow.logit_draws(b, draws, source=tree_2)" ] }, { @@ -875,6 +874,571 @@ " choice_probs.ravel(),\n", ")" ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "2d8be259", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST\n", + "choices_darr, choice_probs_darr = flow.logit_draws(b, draws, as_dataarray=True)\n", + "assert choices_darr.dims == (\"TOURIDX\",)\n", + "assert choices_darr.shape == (100000,)\n", + "assert choice_probs_darr.dims == (\"TOURIDX\",)\n", + "assert choice_probs_darr.shape == (100000,)" + ] + }, + { + "cell_type": "markdown", + "id": "bf8445d5", + "metadata": {}, + "source": [ + "## Nested Logit Simulation\n", + "\n", + "Sharrow can also apply nested logit models. To do so, you'll also need\n", + "to install a recent version of *larch* (e.g. `conda install \"larch>=5.7.1\" -c conda-forge`).\n", + "\n", + "The nesting tree can be defined as usual in Larch, or you can use the\n", + "`construct_nesting_tree` convenience function to read in a nesting tree\n", + "definition according to the usual ActivitySim yaml notation, like this:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8b830bf6", + "metadata": {}, + "outputs": [], + "source": [ + "nesting_settings = \"\"\"\n", + "NESTS:\n", + " name: root\n", + " coefficient: coef_nest_root\n", + " alternatives:\n", + " - name: MOTORIZED\n", + " coefficient: coef_nest_motor\n", + " alternatives:\n", + " - DRIVE\n", + " - TRANSIT\n", + " - WALK\n", + "\"\"\"\n", + "\n", + "import yaml\n", + "from sharrow.nested_logit import construct_nesting_tree\n", + "\n", + "nesting_settings = yaml.safe_load(nesting_settings)['NESTS']\n", + "nest_tree = construct_nesting_tree(\n", + " alternatives=spec.columns[1:],\n", + " nesting_settings=nesting_settings\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "fb9f17cc", + "metadata": {}, + "outputs": [], + "source": [ + "nest_tree" + ] + }, + { + "cell_type": "markdown", + "id": "dfc1a442", + "metadata": {}, + "source": [ + "Once the nesting tree is defined, it needs to be converted to operating arrays, using the `as_arrays` method (available in larch 5.7.1 and later). Since we note estimating a nested logit model and just applying one,\n", + "we can give the parameter values as a dictionary instead of a `larch.Model` to link against." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "7b04d439", + "metadata": {}, + "outputs": [], + "source": [ + "nesting = nest_tree.as_arrays(trim=True, parameter_dict={'coef_nest_motor': 0.5, 'coef_nest_root': 1.0})" + ] + }, + { + "cell_type": "markdown", + "id": "accbae24", + "metadata": {}, + "source": [ + "This dictionary of arrays can be passed in to the `logit_draws` function to compile a nested logit model\n", + "intead of a simple MNL." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c9369f69", + "metadata": {}, + "outputs": [], + "source": [ + "%time choices_nl, choice_probs_nl = flow.logit_draws(b, draws, nesting=nesting)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "5c53c918", + "metadata": {}, + "outputs": [], + "source": [ + "%time choices2_nl, choice2_probs_nl = flow.logit_draws(b, draws, source=tree_2, nesting=nesting)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "abfa83a1", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST\n", + "choices2_nl_darr, choice2_probs_nl_darr = flow.logit_draws(\n", + " b, draws, source=tree_2, nesting=nesting, as_dataarray=True\n", + ")\n", + "assert choices2_nl_darr.dims == (\"TOURIDX\",)\n", + "assert choices2_nl_darr.shape == (100000,)\n", + "assert choice2_probs_nl_darr.dims == (\"TOURIDX\",)\n", + "assert choice2_probs_nl_darr.shape == (100000,)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "698f9211", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST devolve NL to MNL\n", + "choices_nl_1, choice_probs_nl_1 = flow.logit_draws(\n", + " b, draws, \n", + " nesting=nest_tree.as_arrays(trim=True, parameter_dict={'coef_nest_motor': 1.0, 'coef_nest_root': 1.0}),\n", + ")\n", + "assert (choices_nl_1 == choices).all()\n", + "assert choice_probs == approx(choice_probs_nl_1)" + ] + }, + { + "cell_type": "markdown", + "id": "da30839b", + "metadata": {}, + "source": [ + "For nested logit models, computing just the logsums is faster than generating probabilities (and making choices) so the `logsums=1` argument allows you to short-circuit the computations if you only want the logsums." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0545ad8b", + "metadata": {}, + "outputs": [], + "source": [ + "flow.logit_draws(b, draws, source=tree_2, nesting=nesting, logsums=1)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "85071783", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST \n", + "_ch, _pr, _pc, _ls = flow.logit_draws(b, draws, source=tree_2, nesting=nesting, logsums=1)\n", + "assert _ch is None\n", + "assert _pr is None\n", + "assert _pc is None\n", + "assert _ls.size == 100000\n", + "np.testing.assert_array_almost_equal(\n", + " _ls[:5],\n", + " [ 0.532791, 0.490935, 0.557529, 0.556371, 0.54812 ]\n", + ")\n", + "np.testing.assert_array_almost_equal(\n", + " _ls[-5:],\n", + " [ 0.452682, 0.465422, 0.554312, 0.525064, 0.515226 ]\n", + ")\n", + "\n", + "_ch, _pr, _pc, _ls = flow.logit_draws(\n", + " b, draws, source=tree_2, nesting=nesting, logsums=1, as_dataarray=True,\n", + ")\n", + "assert _ch is None\n", + "assert _pr is None\n", + "assert _pc is None\n", + "assert _ls.size == 100000\n", + "assert _ls.dims == (\"TOURIDX\",)\n", + "assert _ls.shape == (100000,)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0ded2556", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST masking\n", + "masker = np.zeros(draws.shape, dtype=np.int8)\n", + "masker[::2] = 1\n", + "_ch_m, _pr_m, _pc_m, _ls_m = flow.logit_draws(b, draws, source=tree_2, nesting=nesting, logsums=1, mask=masker)\n", + "\n", + "assert _ls_m == approx(np.where(masker, _ls, 0))\n", + "assert (_ch_m, _pr_m, _pc_m) == (None, None, None)" + ] + }, + { + "cell_type": "markdown", + "id": "67ac7131", + "metadata": {}, + "source": [ + "Note that for consistency, the choices, probabilities of choices,\n", + "and pick count arrays are still returned as the first three elements\n", + "of the returned tuple, but they're all zero-size empty arrays.\n", + "\n", + "To get *both* the logsums and the choices, set `logsums=2`." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "c6110f4e", + "metadata": {}, + "outputs": [], + "source": [ + "flow.logit_draws(b, draws, source=tree_2, nesting=nesting, logsums=2)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "bc32808c", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST \n", + "_ch, _pr, _pc, _ls = flow.logit_draws(b, draws, source=tree_2, nesting=nesting, logsums=2)\n", + "assert _ch.size == 100000\n", + "assert _pr.size == 100000\n", + "assert _pc is None\n", + "assert _ls.size == 100000\n", + "np.testing.assert_array_almost_equal(\n", + " _ch[:5],\n", + " [ 1, 2, 1, 1, 1 ]\n", + ")\n", + "np.testing.assert_array_almost_equal(\n", + " _ch[-5:],\n", + " [ 0, 1, 0, 1, 0 ]\n", + ")\n", + "np.testing.assert_array_almost_equal(\n", + " _pr[:5],\n", + " [ 0.393454, 0.16956 , 0.38384 , 0.384285, 0.387469 ]\n", + ")\n", + "np.testing.assert_array_almost_equal(\n", + " _pr[-5:],\n", + " [ 0.503606, 0.420874, 0.478898, 0.396506, 0.468742 ]\n", + ")\n", + "np.testing.assert_array_almost_equal(\n", + " _ls[:5],\n", + " [ 0.532791, 0.490935, 0.557529, 0.556371, 0.54812 ]\n", + ")\n", + "np.testing.assert_array_almost_equal(\n", + " _ls[-5:],\n", + " [ 0.452682, 0.465422, 0.554312, 0.525064, 0.515226 ]\n", + ")\n", + "_ch, _pr, _pc, _ls = flow.logit_draws(b, draws, source=tree_2, nesting=nesting, logsums=2, as_dataarray=True)\n", + "assert _ch.size == 100000\n", + "assert _ch.dims == (\"TOURIDX\",)\n", + "assert _ch.shape == (100000,)\n", + "assert _pr.size == 100000\n", + "assert _pr.dims == (\"TOURIDX\",)\n", + "assert _pr.shape == (100000,)\n", + "assert _ls.size == 100000\n", + "assert _ls.dims == (\"TOURIDX\",)\n", + "assert _ls.shape == (100000,)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a6bccd5d", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST\n", + "draws_many = np.random.default_rng(42).random(size=(tree.shape[0], 5))\n", + "_ch, _pr, _pc, _ls = flow.logit_draws(b, draws_many, source=tree_2, nesting=nesting, logsums=2, as_dataarray=True)\n", + "assert _ch.dims == ('TOURIDX', 'DRAW')\n", + "assert _ch.shape == (100000, 5)\n", + "assert _pr.dims == ('TOURIDX', 'DRAW')\n", + "assert _pr.shape == (100000, 5)\n", + "assert _ls.dims == ('TOURIDX', )\n", + "assert _ls.shape == (100000, )\n", + "assert _pc is None\n", + "\n", + "_ch, _pr, _pc, _ls = flow.logit_draws(b, draws_many, source=tree_2, nesting=nesting, logsums=2, as_dataarray=True, pick_counted=True)\n", + "assert _ch.dims == ('TOURIDX', 'DRAW')\n", + "assert _ch.shape == (100000, 5)\n", + "assert _pr.dims == ('TOURIDX', 'DRAW')\n", + "assert _pr.shape == (100000, 5)\n", + "assert _ls.dims == ('TOURIDX', )\n", + "assert _ls.shape == (100000, )\n", + "assert _pc.dims == ('TOURIDX', 'DRAW')\n", + "assert _pc.shape == (100000, 5)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3ddd6c3b", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST masking\n", + "masker = np.zeros(tree.shape[0], dtype=np.int8)\n", + "masker[::3] = 1\n", + "\n", + "_ch_m, _pr_m, _pc_m, _ls_m = flow.logit_draws(\n", + " b, draws_many, source=tree_2, nesting=nesting, logsums=2, as_dataarray=True, mask=masker, pick_counted=True\n", + ")\n", + "\n", + "assert (_ch_m.values == (np.where(np.expand_dims(masker, -1), _ch, -1))).all()\n", + "assert (_pr_m.values == (np.where(np.expand_dims(masker, -1), _pr, 0))).all()\n", + "assert (_pc_m.values == (np.where(np.expand_dims(masker, -1), _pc, 0))).all()\n", + "assert (_ls_m.values == (np.where(masker, _ls, 0))).all()" + ] + }, + { + "cell_type": "markdown", + "id": "6169e4cc", + "metadata": {}, + "source": [ + "## Batch Simulation" + ] + }, + { + "cell_type": "markdown", + "id": "a83d4036", + "metadata": {}, + "source": [ + "Suppose we want to compute logsums not just for one destination, but for many destinations. We can construct a `Dataset` with two dimensions to use at the top of our `DataTree`, one for the tours and one for the candidate destinations." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "39d39131", + "metadata": {}, + "outputs": [], + "source": [ + "tour_by_dest = tree.subspaces['tour']\n", + "tour_by_dest = tour_by_dest.assign_coords({'CAND_DEST': xr.DataArray(np.arange(25), dims='CAND_DEST')})\n", + "tour_by_dest" + ] + }, + { + "cell_type": "markdown", + "id": "fced6ace", + "metadata": {}, + "source": [ + "Then we can create a very similar DataTree as above, using this two dimension root Dataset, but we will point to our destination zones from the new tour dimension. and then create a flow from that." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "399e875f", + "metadata": {}, + "outputs": [], + "source": [ + "wide_tree = sh.DataTree(\n", + " tour=tour_by_dest,\n", + " person=persons,\n", + " hh=households,\n", + " odt_skims=skims,\n", + " dot_skims=skims,\n", + " relationships=(\n", + " \"tour.PERID @ person.PERID\",\n", + " \"person.household_id @ hh.HHID\",\n", + " \"hh.TAZ @ odt_skims.otaz\",\n", + " \"tour.CAND_DEST -> odt_skims.dtaz\",\n", + " \"tour.out_time_period @ odt_skims.time_period\",\n", + " \"tour.CAND_DEST -> dot_skims.otaz\",\n", + " \"hh.TAZ @ dot_skims.dtaz\",\n", + " \"tour.in_time_period @ dot_skims.time_period\",\n", + " ),\n", + " extra_vars={\n", + " 'shortwait': 3,\n", + " 'one': 1,\n", + " },\n", + " aux_vars={\n", + " 'short_i_wait_mult': 0.75,\n", + " 'income_breakpoints': income_breakpoints,\n", + " },\n", + " dim_order=('TOURIDX', 'CAND_DEST')\n", + ")\n", + "wide_flow = wide_tree.setup_flow(spec.Expression)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9d7bd3fa", + "metadata": {}, + "outputs": [], + "source": [ + "%time wide_logsums = wide_flow.logit_draws(b, logsums=1, compile_watch=\"simple\")[-1]" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "8a036273", + "metadata": {}, + "outputs": [], + "source": [ + "%time wide_logsums = wide_flow.logit_draws(b, logsums=1, compile_watch=\"simple\")[-1]\n", + "wide_logsums" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "d19548d9", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST\n", + "np.testing.assert_array_almost_equal(\n", + " wide_logsums[:5,:5],\n", + " np.array([[ 0.759222, 0.75862 , 0.744936, 0.758251, 0.737007],\n", + " [ 0.671698, 0.671504, 0.663015, 0.661482, 0.667133],\n", + " [ 0.670188, 0.678498, 0.687647, 0.691152, 0.715783],\n", + " [ 0.760743, 0.769123, 0.763733, 0.784487, 0.802356],\n", + " [ 0.73474 , 0.743051, 0.751439, 0.754731, 0.778121]], dtype=np.float32)\n", + ")\n", + "np.testing.assert_array_almost_equal(\n", + " wide_logsums[-5:,-5:],\n", + " np.array([[ 0.719523, 0.755152, 0.739368, 0.762664, 0.764388],\n", + " [ 0.740303, 0.678783, 0.649964, 0.694407, 0.681555],\n", + " [ 0.758865, 0.663663, 0.637266, 0.673351, 0.65875 ],\n", + " [ 0.765125, 0.706478, 0.676878, 0.717814, 0.713912],\n", + " [ 0.73348 , 0.683626, 0.647698, 0.69146 , 0.673006]], dtype=np.float32)\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "ef2d38ae", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST\n", + "np.testing.assert_array_almost_equal(\n", + " wide_logsums[np.arange(len(tours)), tours['dest_taz_idx'].to_numpy()],\n", + " flow.logit_draws(b, logsums=1)[-1]\n", + ")" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "9d5e74df", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST\n", + "wide_logsums_ = wide_flow.logit_draws(b, logsums=1, compile_watch=True, as_dataarray=True)[-1]\n", + "assert wide_logsums_.dims == (\"TOURIDX\", \"CAND_DEST\")\n", + "assert wide_logsums_.shape == (100000, 25)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "a9b0e5c5", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST\n", + "wide_draws = np.random.default_rng(42).random(size=wide_tree.shape)\n", + "with pytest.warns(sh.CacheMissWarning):\n", + " wide_logsums_plus = wide_flow.logit_draws(\n", + " b, logsums=2, compile_watch=True, as_dataarray=True, draws=wide_draws\n", + " )\n", + "assert wide_logsums_plus[0].dims == (\"TOURIDX\", \"CAND_DEST\")\n", + "assert wide_logsums_plus[0].shape == (100000, 25)\n", + "assert wide_logsums_plus[3].dims == (\"TOURIDX\", \"CAND_DEST\")\n", + "assert wide_logsums_plus[3].shape == (100000, 25)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "0dc7210b", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST\n", + "wide_draws = np.random.default_rng(42).random(size=wide_tree.shape + (2,))\n", + "wide_logsums_plus = wide_flow.logit_draws(b, logsums=2, compile_watch=True, as_dataarray=True, draws=wide_draws)\n", + "assert wide_logsums_plus[0].dims == (\"TOURIDX\", \"CAND_DEST\", \"DRAW\")\n", + "assert wide_logsums_plus[0].shape == (100000, 25, 2)\n", + "assert wide_logsums_plus[3].dims == (\"TOURIDX\", \"CAND_DEST\")\n", + "assert wide_logsums_plus[3].shape == (100000, 25)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "92d83292", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST masking\n", + "mask = np.zeros(wide_tree.shape, dtype=np.int8)\n", + "mask[::7] = 1\n", + "with pytest.warns(sh.CacheMissWarning):\n", + " wide_logsums_mask = wide_flow.logit_draws(\n", + " b, logsums=2, compile_watch=True, as_dataarray=True, draws=wide_draws, mask=mask\n", + " )\n", + "assert wide_logsums_mask[0].dims == (\"TOURIDX\", \"CAND_DEST\", \"DRAW\")\n", + "assert wide_logsums_mask[0].shape == (100000, 25, 2)\n", + "assert wide_logsums_mask[3].dims == (\"TOURIDX\", \"CAND_DEST\")\n", + "assert wide_logsums_mask[3].shape == (100000, 25)\n", + "\n", + "assert (wide_logsums_plus[0].where(np.expand_dims(mask, -1), -1) == wide_logsums_mask[0]).all()\n", + "assert (wide_logsums_plus[1].where(np.expand_dims(mask, -1), 0) == wide_logsums_mask[1]).all()\n", + "assert (wide_logsums_plus[3].where(mask, 0) == wide_logsums_mask[3]).all()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "de8251d3", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST masking performance\n", + "import timeit, warnings\n", + "with warnings.catch_warnings():\n", + " warnings.simplefilter(\"error\")\n", + " masked_time = timeit.timeit(lambda: wide_flow.logit_draws(\n", + " b, logsums=2, compile_watch=True, as_dataarray=True, draws=wide_draws, mask=mask\n", + " ), number=1)\n", + " raw_time = timeit.timeit(lambda: wide_flow.logit_draws(\n", + " b, logsums=2, compile_watch=True, as_dataarray=True, draws=wide_draws\n", + " ), number=1)\n", + "assert masked_time * 2 < raw_time # generous buffer, should be nearly 7 times faster\n", + "assert len(wide_flow.cache_misses['_imnl_plus1d']) == 3" + ] } ], "metadata": { @@ -893,7 +1457,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.10" + "version": "3.10.6" }, "toc": { "base_numbering": 1, diff --git a/docs/walkthrough/two-dim.ipynb b/docs/walkthrough/two-dim.ipynb index e0633c2..f37a34c 100644 --- a/docs/walkthrough/two-dim.ipynb +++ b/docs/walkthrough/two-dim.ipynb @@ -439,6 +439,7 @@ }, "outputs": [], "source": [ + "# TEST\n", "assert arr.shape == (4361, 25, 4)\n", "expected = np.array([\n", " [[ 0.61 , 0.61 , 0. , 4.610157],\n", @@ -585,7 +586,7 @@ "source": [ "## Multinomial Logit Simulation\n", "\n", - "And we can build and simulate an MNL model directly using the `mnl_draws` method. \n", + "And we can build and simulate an MNL model directly using the `logit_draws` method. \n", "To do so we need to\n", "provide the \"random\" draws exogenously. Here, we'll sample 10 zones (with\n", "replacement) from the selection of alternatives." @@ -608,7 +609,7 @@ "metadata": {}, "outputs": [], "source": [ - "choices, choice_probs = flow.mnl_draws(\n", + "choices, choice_probs = flow.logit_draws(\n", " coefficients=coefs,\n", " draws=draws,\n", ")" @@ -645,7 +646,8 @@ }, "outputs": [], "source": [ - "expected = np.array([[ 5, 8, 8, 9, 9, 18, 19, 19, 19, 20],\n", + "# TEST\n", + "expected_ch = np.array([[ 5, 8, 8, 9, 9, 18, 19, 19, 19, 20],\n", " [ 7, 7, 7, 9, 10, 17, 18, 19, 20, 23],\n", " [ 1, 6, 6, 7, 9, 9, 13, 17, 18, 22],\n", " [ 8, 9, 9, 18, 18, 19, 19, 19, 19, 20],\n", @@ -656,10 +658,10 @@ " [ 5, 6, 7, 13, 15, 22, 22, 22, 23, 23],\n", " [ 0, 2, 3, 13, 16, 22, 22, 22, 24, 24],\n", " [ 7, 8, 8, 11, 14, 14, 16, 21, 22, 22]], dtype=np.int32)\n", - "np.testing.assert_array_equal(choices[:5], expected[:5])\n", - "np.testing.assert_array_equal(choices[-5:], expected[-5:])\n", + "np.testing.assert_array_equal(choices[:5], expected_ch[:5])\n", + "np.testing.assert_array_equal(choices[-5:], expected_ch[-5:])\n", "\n", - "expected = np.array([\n", + "expected_pr = np.array([\n", " [ 0.021757, 0.082092, 0.082092, 0.090812, 0.090812, 0.239048, 0.130507, 0.130507, 0.130507, 0.038469],\n", " [ 0.063636, 0.063636, 0.063636, 0.103338, 0.039564, 0.035372, 0.10316 , 0.064873, 0.021167, 0.031342],\n", " [ 0.017309, 0.052503, 0.052503, 0.063636, 0.103338, 0.103338, 0.008113, 0.035372, 0.10316 , 0.054565],\n", @@ -671,8 +673,31 @@ " [ 0.039726, 0.027111, 0.019715, 0.031909, 0.023773, 0.207882, 0.207882, 0.207882, 0.069134, 0.069134],\n", " [ 0.046512, 0.036197, 0.025022, 0.031909, 0.03535 , 0.207882, 0.207882, 0.207882, 0.06648 , 0.06648 ],\n", " [ 0.019715, 0.038968, 0.038968, 0.013389, 0.048031, 0.048031, 0.03535 , 0.08728 , 0.207882, 0.207882]])\n", - "np.testing.assert_array_almost_equal(choice_probs[:5], expected[:5])\n", - "np.testing.assert_array_almost_equal(choice_probs[-5:], expected[-5:])\n" + "np.testing.assert_array_almost_equal(choice_probs[:5], expected_pr[:5])\n", + "np.testing.assert_array_almost_equal(choice_probs[-5:], expected_pr[-5:])\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3a6163c0", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST\n", + "choices_darr, choice_probs_darr = flow.logit_draws(\n", + " coefficients=coefs,\n", + " draws=draws,\n", + " as_dataarray=True,\n", + ")\n", + "assert choices_darr.dims == ('WORKERID', 'DRAW')\n", + "assert choices_darr.shape == (4361, 10)\n", + "np.testing.assert_array_equal(choices_darr[:5], expected_ch[:5])\n", + "np.testing.assert_array_equal(choices_darr[-5:], expected_ch[-5:])\n", + "assert choice_probs_darr.dims == ('WORKERID', 'DRAW')\n", + "assert choice_probs_darr.shape == (4361, 10)\n", + "np.testing.assert_array_almost_equal(choice_probs_darr[:5], expected_pr[:5])\n", + "np.testing.assert_array_almost_equal(choice_probs_darr[-5:], expected_pr[-5:])" ] }, { @@ -692,7 +717,7 @@ "metadata": {}, "outputs": [], "source": [ - "choices_, choice_probs_, pick_count = flow.mnl_draws(\n", + "choices_, choice_probs_, pick_count = flow.logit_draws(\n", " coefficients=coefs,\n", " draws=draws,\n", " pick_counted=True,\n", @@ -750,6 +775,28 @@ " np.testing.assert_array_equal(np.zeros(10-len(uc)), pick_count[i, len(uc):])\n" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "7877231e", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST\n", + "choices__darr, choice_probs__darr, pick_count_darr = flow.logit_draws(\n", + " coefficients=coefs,\n", + " draws=draws,\n", + " pick_counted=True,\n", + " as_dataarray=True,\n", + ")\n", + "assert choices__darr.dims == ('WORKERID', 'DRAW')\n", + "assert choices__darr.shape == (4361, 10)\n", + "assert choice_probs__darr.dims == ('WORKERID', 'DRAW')\n", + "assert choice_probs__darr.shape == (4361, 10)\n", + "assert pick_count_darr.dims == ('WORKERID', 'DRAW')\n", + "assert pick_count_darr.shape == (4361, 10)" + ] + }, { "cell_type": "markdown", "id": "289a75a1", @@ -770,7 +817,7 @@ "metadata": {}, "outputs": [], "source": [ - "choices, choice_probs, _, logsums = flow.mnl_draws(\n", + "choices, choice_probs, _, logsums = flow.logit_draws(\n", " coefficients=coefs,\n", " draws=draws,\n", " logsums=True,\n", @@ -795,6 +842,29 @@ "np.testing.assert_array_almost_equal(logsums[-5:], expected[-5:])" ] }, + { + "cell_type": "code", + "execution_count": null, + "id": "7f6bc921", + "metadata": {}, + "outputs": [], + "source": [ + "# TEST\n", + "choices_darr2, choice_probs_darr2, pick_count_nope, logsums_darr = flow.logit_draws(\n", + " coefficients=coefs,\n", + " draws=draws,\n", + " logsums=True,\n", + " as_dataarray=True,\n", + ")\n", + "assert choices_darr2.dims == ('WORKERID', 'DRAW')\n", + "assert choices_darr2.shape == (4361, 10)\n", + "assert choice_probs_darr2.dims == ('WORKERID', 'DRAW')\n", + "assert choice_probs_darr2.shape == (4361, 10)\n", + "assert pick_count_nope is None\n", + "assert logsums_darr.dims == (\"WORKERID\",)\n", + "assert logsums_darr.shape == (4361,)" + ] + }, { "cell_type": "markdown", "id": "bc317541", @@ -895,7 +965,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.9.10" + "version": "3.10.6" }, "toc": { "base_numbering": 1, diff --git a/envs/development.yml b/envs/development.yml index e649edc..6555c2e 100644 --- a/envs/development.yml +++ b/envs/development.yml @@ -10,6 +10,7 @@ dependencies: - filelock - flake8 - jupyter + - larch>=5.7.1 - nbmake - networkx - notebook diff --git a/envs/testing.yml b/envs/testing.yml index 6e9baea..deb0879 100644 --- a/envs/testing.yml +++ b/envs/testing.yml @@ -23,3 +23,4 @@ dependencies: - nbmake - openmatrix - zarr + - larch>=5.7.1 diff --git a/sharrow/__init__.py b/sharrow/__init__.py index 100580c..df6c3b8 100644 --- a/sharrow/__init__.py +++ b/sharrow/__init__.py @@ -4,6 +4,6 @@ from ._infer_version import __version__, __version_tuple__ from .dataset import Dataset from .digital_encoding import array_decode, array_encode -from .flows import Flow +from .flows import CacheMissWarning, Flow from .relationships import DataTree, Relationship from .table import Table, concat_tables diff --git a/sharrow/aster.py b/sharrow/aster.py index ce2e2ba..4fb8f24 100755 --- a/sharrow/aster.py +++ b/sharrow/aster.py @@ -338,6 +338,8 @@ def __init__( extra_vars=None, blenders=None, bool_wrapping=False, + swallow_errors=False, + get_default=False, ): self.spacename = spacename self.dim_slots = dim_slots @@ -349,6 +351,8 @@ def __init__( self.extra_vars = extra_vars or {} self.blenders = blenders or {} self.bool_wrapping = bool_wrapping + self.swallow_errors = swallow_errors + self.get_default = get_default def log_event(self, tag, node1=None, node2=None): if logger.getEffectiveLevel() <= 0: @@ -394,12 +398,16 @@ def _replacement( if self.spacevars is not None: if attr not in self.spacevars: - if topname == pref_topname: + if topname == pref_topname and not self.swallow_errors: raise KeyError(f"{topname}..{attr}") # we originally raised a KeyError here regardless, but what if we just # give back the original node, and see if other spaces, # possibly fallback spaces, might work? If nothing works then # it will still eventually error out when compiling? + # The swallow errors option allows us to continue processing + # using the same rules, then circle back later to clean up + # errors, so that as-yet unprocessed Ast elements get the + # chance to be seen by the first pass. return original_node dim_slots = self.dim_slots @@ -904,6 +912,41 @@ def visit_Call(self, node): keywords=[], ) + # implement x.get("y",z) + if ( + isinstance(node.func, ast.Attribute) + and node.func.attr == "get" + and node.func.value.id == self.spacename + ): + if len(node.args) == 2 and len(node.keywords) == 0: + try: + return self._replacement( + ast_String_value(node.args[0]), node.func.value.ctx, node + ) + except KeyError: + if self.get_default: + return self.visit(node.args[1]) + else: + raise + if ( + len(node.args) == 1 + and len(node.keywords) == 1 + and "default" == node.keywords[0].arg + ): + try: + return self._replacement( + ast_String_value(node.args[0]), node.func.value.ctx, node + ) + except KeyError: + if self.get_default: + return self.visit(node.keywords[0].value) + else: + raise + if len(node.args) == 1 and len(node.keywords) == 0: + return self._replacement( + ast_String_value(node.args[0]), node.func.value.ctx, node + ) + # if no other changes if result is None: args = [self.visit(i) for i in node.args] @@ -929,6 +972,8 @@ def expression_for_numba( extra_vars=None, blenders=None, bool_wrapping=False, + swallow_errors=False, + get_default=False, ): """ Rewrite an expression so numba can compile it. @@ -964,6 +1009,8 @@ def expression_for_numba( extra_vars, blenders, bool_wrapping, + swallow_errors, + get_default, ).visit(ast.parse(expr)) ) diff --git a/sharrow/dataset.py b/sharrow/dataset.py index 7918603..68be2be 100755 --- a/sharrow/dataset.py +++ b/sharrow/dataset.py @@ -9,7 +9,7 @@ import pandas as pd import pyarrow as pa import xarray as xr -from xarray import Dataset +from xarray import DataArray, Dataset from .accessors import register_dataset_method from .aster import extract_all_name_tokens @@ -143,7 +143,29 @@ def dataset_from_dataframe_fast( return Dataset.from_dataframe(dataframe, sparse) if not dataframe.columns.is_unique: - raise ValueError("cannot convert DataFrame with non-unique columns") + # if the dataframe has non-unique column names, but all the duplicate + # names contain the same data, we can recover safely by dropping the + # duplicates, otherwise throw an error. + cannot_fix = False + dupe_columns = dataframe.columns.duplicated() + dupe_column_names = dataframe.columns[dupe_columns] + for j in dupe_column_names: + subframe = dataframe[j] + ref_col = subframe.iloc[:, 0] + for k in range(1, len(subframe.columns)): + if not ref_col.equals(subframe.iloc[:, k]): + cannot_fix = True + break + if cannot_fix: + break + dupe_column_names = [f"- {i}" for i in dupe_column_names] + logger.error( + "DataFrame has non-unique columns\n" + "\n".join(dupe_column_names) + ) + if cannot_fix: + raise ValueError("cannot convert DataFrame with non-unique columns") + else: + dataframe = dataframe.loc[:, ~dupe_columns] if isinstance(dataframe.index, pd.CategoricalIndex): idx = dataframe.index.remove_unused_categories() @@ -597,7 +619,7 @@ def from_zarr(store, *args, **kwargs): ---------- http://zarr.readthedocs.io/ """ - return xr.Dataset(xr.open_zarr(store, *args, **kwargs)) + return xr.open_zarr(store, *args, **kwargs) def from_zarr_with_attr(*args, **kwargs): @@ -643,6 +665,67 @@ def is_dict_like(value: Any) -> bool: return hasattr(value, "keys") and hasattr(value, "__getitem__") +@xr.register_dataset_accessor("single_dim") +class _SingleDim: + """ + Convenience accessor for single-dimension datasets. + """ + + __slots__ = ("dataset", "dim_name") + + def __init__(self, dataset: "Dataset"): + self.dataset = dataset + if len(self.dataset.dims) != 1: + raise ValueError("single_dim implies a single dimension dataset") + self.dim_name = self.dataset.dims.__iter__().__next__() + + @property + def coords(self): + return self.dataset.coords[self.dim_name] + + @property + def index(self): + return self.dataset.indexes[self.dim_name] + + @property + def size(self): + return self.dataset.dims[self.dim_name] + + def to_pyarrow(self): + return pa.Table.from_pydict( + {k: pa.array(v.to_numpy()) for k, v in self.dataset.variables.items()} + ) + + +@xr.register_dataarray_accessor("single_dim") +class _SingleDimArray: + """ + Convenience accessor for single-dimension datasets. + """ + + __slots__ = ("dataarray", "dim_name") + + def __init__(self, dataarray: "DataArray"): + self.dataarray = dataarray + if len(self.dataarray.dims) != 1: + raise ValueError("single_dim implies a single dimension dataset") + self.dim_name = self.dataarray.dims[0] + + @property + def coords(self): + return self.dataarray.coords[self.dim_name] + + @property + def index(self): + return self.dataarray.indexes[self.dim_name] + + def rename(self, name: str) -> DataArray: + """Rename the single dimension.""" + if self.dim_name == name: + return self.dataarray + return self.dataarray.rename({self.dim_name: name}) + + @xr.register_dataset_accessor("iloc") class _iLocIndexer: """ @@ -872,6 +955,43 @@ def to_zarr_with_attr(self, *args, **kwargs): return obj.to_zarr(*args, **kwargs) +@register_dataset_method +def to_table(self): + """ + Convert dataset contents to a pyarrow Table. + + This dataset must not contain more than one dimension. + """ + assert isinstance(self, Dataset) + if len(self.dims) != 1: + raise ValueError("Only 1-dim datasets can be converted to tables") + + import pyarrow as pa + + from .relationships import sparse_array_type + + def to_numpy(var): + """Coerces wrapped data to numpy and returns a numpy.ndarray""" + data = var.data + if hasattr(data, "chunks"): + data = data.compute() + if isinstance(data, sparse_array_type): + data = data.todense() + return np.asarray(data) + + pydict = {} + for i in self.variables: + dictionary = self[i].attrs.get("DICTIONARY", None) + if dictionary is not None: + pydict[i] = pa.DictionaryArray.from_arrays( + to_numpy(self[i]), + dictionary, + ) + else: + pydict[i] = pa.array(to_numpy(self[i])) + return pa.Table.from_pydict(pydict) + + @register_dataset_method def select_and_rename(self, name_dict=None, **names): """ diff --git a/sharrow/debug.py b/sharrow/debug.py new file mode 100644 index 0000000..c3fd012 --- /dev/null +++ b/sharrow/debug.py @@ -0,0 +1,5 @@ +import logging + +from .logging import log_to_console + +logger = log_to_console(level=logging.DEBUG) diff --git a/sharrow/digital_encoding.py b/sharrow/digital_encoding.py index 2b974c4..7dee25f 100644 --- a/sharrow/digital_encoding.py +++ b/sharrow/digital_encoding.py @@ -289,6 +289,24 @@ def baggage(self, names): bag.add(de["offset_source"]) return bag + def drop_dims(self, dim_name, *, errors="raise"): + if isinstance(dim_name, str): + vars_to_drop = set() + for k in self._obj.variables: + k_attrs = self._obj._variables[k].attrs + if "digital_encoding" in k_attrs: + offset_array_name = k_attrs["digital_encoding"].get("offset_source") + if dim_name in self._obj._variables[offset_array_name].dims: + vars_to_drop.add(k) + if dim_name in self._obj._variables[k].dims: + vars_to_drop.add(k) + return self._obj.drop_vars(vars_to_drop, errors=errors) + else: + obj = self._obj + for i in dim_name: + obj = obj.digital_encoding.drop_dims(i, errors=errors) + return obj + def multivalue_digitize_by_dictionary(ds, encode_vars=None, encoding_name=None): """ diff --git a/sharrow/flows.py b/sharrow/flows.py index b96f823..5ba3439 100644 --- a/sharrow/flows.py +++ b/sharrow/flows.py @@ -25,6 +25,11 @@ logger = logging.getLogger("sharrow") + +class CacheMissWarning(UserWarning): + pass + + well_known_names = { "nb", "np", @@ -147,7 +152,7 @@ def coerce_to_range_index(idx): FUNCTION_TEMPLATE = """ # {init_expr} -@nb.jit(cache=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}) +@nb.jit(cache=False, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) def {fname}( {argtokens} _outputs, @@ -159,43 +164,50 @@ def {fname}( IRUNNER_1D_TEMPLATE = """ -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}) +@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) def irunner( argshape, {joined_namespace_names} dtype=np.{dtype}, + mask=None, ): result = np.empty((argshape[0], {len_self_raw_functions}), dtype=dtype) - if argshape[0] > 1000: - for j0 in nb.prange(argshape[0]): - linemaker(result[j0], j0, {joined_namespace_names}) - else: - for j0 in range(argshape[0]): - linemaker(result[j0], j0, {joined_namespace_names}) + if mask is not None: + assert mask.ndim == 1 + assert mask.shape[0] == argshape[0] + for j0 in nb.prange(argshape[0]): + if mask is not None: + if not mask[j0]: + result[j0, :] = np.nan + continue + linemaker(result[j0], j0, {joined_namespace_names}) return result """ IRUNNER_2D_TEMPLATE = """ -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}) +@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) def irunner( argshape, {joined_namespace_names} dtype=np.{dtype}, + mask=None, ): result = np.empty((argshape[0], argshape[1], {len_self_raw_functions}), dtype=dtype) - if argshape[0] * argshape[1] > 1000: - for j0 in nb.prange(argshape[0]): - for j1 in range(argshape[1]): - linemaker(result[j0, j1], j0, j1, {joined_namespace_names}) - else: - for j0 in range(argshape[0]): - for j1 in range(argshape[1]): + if mask is not None: + assert mask.ndim == 2 + assert mask.shape[0] == argshape[0] + assert mask.shape[1] == argshape[1] + for j0 in nb.prange(argshape[0]): + for j1 in range(argshape[1]): + if mask is not None: + if not mask[j0, j1]: + result[j0, j1, :] = np.nan linemaker(result[j0, j1], j0, j1, {joined_namespace_names}) return result """ IDOTTER_1D_TEMPLATE = """ -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}) +@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) def idotter( argshape, {joined_namespace_names} @@ -220,7 +232,7 @@ def idotter( """ IDOTTER_2D_TEMPLATE = """ -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}) +@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) def idotter( argshape, {joined_namespace_names} @@ -247,7 +259,7 @@ def idotter( """ ILINER_1D_TEMPLATE = """ -@nb.jit(cache=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}) +@nb.jit(cache=False, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) def linemaker( intermediate, j0, {joined_namespace_names} @@ -257,7 +269,7 @@ def linemaker( """ ILINER_2D_TEMPLATE = """ -@nb.jit(cache=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}) +@nb.jit(cache=False, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) def linemaker( intermediate, j0, j1, {joined_namespace_names} @@ -268,7 +280,7 @@ def linemaker( MNL_GENERIC_TEMPLATE = """ -@nb.jit(cache=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}) +@nb.jit(cache=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) def _sample_choices_maker( prob_array, random_array, @@ -318,7 +330,7 @@ def _sample_choices_maker( -@nb.jit(cache=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}) +@nb.jit(cache=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) def _sample_choices_maker_counted( prob_array, random_array, @@ -381,8 +393,10 @@ def _sample_choices_maker_counted( MNL_GENERIC_TEMPLATE + """ -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}) -def mnl_transform( +logit_ndims = 1 + +@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +def mnl_transform_plus1d( argshape, {joined_namespace_names} dtype=np.{dtype}, @@ -390,42 +404,39 @@ def mnl_transform( random_draws=None, pick_counted=False, logsums=False, + choice_dtype=np.int32, + pick_count_dtype=np.int32, + mask=None, ): if dotarray is None: raise ValueError("dotarray cannot be None") assert dotarray.ndim == 2 - result = np.full((argshape[0], random_draws.shape[1]), -1, dtype=np.int32) + if mask is not None: + assert mask.ndim == 1 + assert mask.shape[0] == argshape[0] + result = np.full((argshape[0], random_draws.shape[1]), -1, dtype=choice_dtype) result_p = np.zeros((argshape[0], random_draws.shape[1]), dtype=dtype) if pick_counted: - pick_count = np.zeros((argshape[0], random_draws.shape[1]), dtype=np.int32) + pick_count = np.zeros((argshape[0], random_draws.shape[1]), dtype=pick_count_dtype) else: - pick_count = np.zeros((argshape[0], 0), dtype=np.int32) + pick_count = np.zeros((argshape[0], 0), dtype=pick_count_dtype) if logsums: _logsums = np.zeros((argshape[0], ), dtype=dtype) else: _logsums = np.zeros((0, ), dtype=dtype) - if argshape[0] > 1000: - for j0 in nb.prange(argshape[0]): + for j0 in nb.prange(argshape[0]): + if mask is not None: + if not mask[j0]: + continue intermediate = np.zeros({len_self_raw_functions}, dtype=dtype) {meta_code_stack_dot} - partial = np.exp(np.dot(intermediate, dotarray)) - local_sum = np.sum(partial) - partial /= local_sum - if logsums: - _logsums[j0] = np.log(local_sum) - if pick_counted: - _sample_choices_maker_counted(partial, random_draws[j0], result[j0], result_p[j0], pick_count[j0]) - else: - _sample_choices_maker(partial, random_draws[j0], result[j0], result_p[j0]) - else: - intermediate = np.zeros({len_self_raw_functions}, dtype=dtype) - for j0 in range(argshape[0]): - {meta_code_stack_dot} - partial = np.exp(np.dot(intermediate, dotarray)) + dotprod = np.dot(intermediate, dotarray) + shifter = np.max(dotprod) + partial = np.exp(dotprod - shifter) local_sum = np.sum(partial) partial /= local_sum if logsums: - _logsums[j0] = np.log(local_sum) + _logsums[j0] = np.log(local_sum) + shifter if pick_counted: _sample_choices_maker_counted(partial, random_draws[j0], result[j0], result_p[j0], pick_count[j0]) else: @@ -434,13 +445,56 @@ def mnl_transform( """ ) +# @nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}) +# def mnl_transform_plus1d( +# argshape, +# {joined_namespace_names} +# dtype=np.{dtype}, +# dotarray=None, +# random_draws=None, +# pick_counted=False, +# logsums=False, +# choice_dtype=np.int32, +# pick_count_dtype=np.int32, +# ): +# if dotarray is None: +# raise ValueError("dotarray cannot be None") +# assert dotarray.ndim == 2 +# result = np.full((argshape[0], argshape[1], random_draws.shape[1]), -1, dtype=choice_dtype) +# result_p = np.zeros((argshape[0], argshape[1], random_draws.shape[1]), dtype=dtype) +# if pick_counted: +# pick_count = np.zeros((argshape[0], argshape[1], random_draws.shape[1]), dtype=pick_count_dtype) +# else: +# pick_count = np.zeros((argshape[0], argshape[1], 0), dtype=pick_count_dtype) +# if logsums: +# _logsums = np.zeros((argshape[0], argshape[1], ), dtype=dtype) +# else: +# _logsums = np.zeros((0, 0), dtype=dtype) +# for j0 in nb.prange(argshape[0]): +# for k0 in range(argshape[1]): +# intermediate = np.zeros({len_self_raw_functions}, dtype=dtype) +# {meta_code_stack_dot} +# dotprod = np.dot(intermediate, dotarray) +# shifter = np.max(dotprod) +# partial = np.exp(dotprod - shifter) +# local_sum = np.sum(partial) +# partial /= local_sum +# if logsums: +# _logsums[j0,k0] = np.log(local_sum) + shifter +# if pick_counted: +# _sample_choices_maker_counted(partial, random_draws[j0,k0], result[j0,k0], result_p[j0,k0], pick_count[j0,k0]) +# else: +# _sample_choices_maker(partial, random_draws[j0,k0], result[j0,k0], result_p[j0,k0]) +# return result, result_p, pick_count, _logsums MNL_2D_TEMPLATE = ( MNL_GENERIC_TEMPLATE + """ -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}) +logit_ndims = 2 + +@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) def mnl_transform( argshape, {joined_namespace_names} @@ -449,60 +503,225 @@ def mnl_transform( random_draws=None, pick_counted=False, logsums=False, + choice_dtype=np.int32, + pick_count_dtype=np.int32, + mask=None, ): if dotarray is None: raise ValueError("dotarray cannot be None") assert dotarray.ndim == 2 assert dotarray.shape[1] == 1 + dotarray = dotarray.reshape(-1) if random_draws is None: raise ValueError("random_draws cannot be None") assert random_draws.ndim == 2 assert random_draws.shape[0] == argshape[0] + if mask is not None: + assert mask.ndim == 1 + assert mask.shape[0] == argshape[0] - result = np.full((argshape[0], random_draws.shape[1]), -1, dtype=np.int32) + result = np.full((argshape[0], random_draws.shape[1]), -1, dtype=choice_dtype) result_p = np.zeros((argshape[0], random_draws.shape[1]), dtype=dtype) if pick_counted: - pick_count = np.zeros((argshape[0], random_draws.shape[1]), dtype=np.int32) + pick_count = np.zeros((argshape[0], random_draws.shape[1]), dtype=pick_count_dtype) else: - pick_count = np.zeros((argshape[0], 0), dtype=np.int32) + pick_count = np.zeros((argshape[0], 0), dtype=pick_count_dtype) if logsums: _logsums = np.zeros((argshape[0], ), dtype=dtype) else: _logsums = np.zeros((0, ), dtype=dtype) - if argshape[0] > 1000: - for j0 in nb.prange(argshape[0]): - partial = np.zeros(argshape[1], dtype=dtype) - for j1 in range(argshape[1]): - intermediate = np.zeros({len_self_raw_functions}, dtype=dtype) + for j0 in nb.prange(argshape[0]): + if mask is not None: + if not mask[j0]: + continue + partial = np.zeros(argshape[1], dtype=dtype) + intermediate = np.zeros({len_self_raw_functions}, dtype=dtype) + shifter = -99999 + for j1 in range(argshape[1]): + intermediate[:] = 0 {meta_code_stack_dot} - partial[j1] = np.exp(np.dot(intermediate, dotarray))[0] - local_sum = np.sum(partial) - if logsums: - _logsums[j0] = np.log(local_sum) - partial /= local_sum - if pick_counted: + v = partial[j1] = np.dot(intermediate, dotarray) + if v > shifter: + shifter = v + for j1 in range(argshape[1]): + partial[j1] = np.exp(partial[j1] - shifter) + local_sum = np.sum(partial) + if logsums: + _logsums[j0] = np.log(local_sum) + shifter + if logsums == 1: + continue + partial /= local_sum + if pick_counted: _sample_choices_maker_counted(partial, random_draws[j0], result[j0], result_p[j0], pick_count[j0]) - else: + else: _sample_choices_maker(partial, random_draws[j0], result[j0], result_p[j0]) + return result, result_p, pick_count, _logsums + + +@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +def mnl_transform_plus1d( + argshape, + {joined_namespace_names} + dtype=np.{dtype}, + dotarray=None, + random_draws=None, + pick_counted=False, + logsums=False, + choice_dtype=np.int32, + pick_count_dtype=np.int32, + mask=None, +): + if dotarray is None: + raise ValueError("dotarray cannot be None") + assert dotarray.ndim == 2 + assert dotarray.shape[1] >= 1 + if random_draws is None: + raise ValueError("random_draws cannot be None") + assert random_draws.ndim == 3 + assert random_draws.shape[0] == argshape[0] + assert random_draws.shape[1] == argshape[1] + if mask is not None: + assert mask.ndim == 2 + assert mask.shape[0] == argshape[0] + assert mask.shape[1] == argshape[1] + + result = np.full((argshape[0], argshape[1], random_draws.shape[2]), -1, dtype=choice_dtype) + result_p = np.zeros((argshape[0], argshape[1], random_draws.shape[2]), dtype=dtype) + if pick_counted: + pick_count = np.zeros((argshape[0], argshape[1], random_draws.shape[2]), dtype=pick_count_dtype) else: - intermediate = np.zeros({len_self_raw_functions}, dtype=dtype) - partial = np.zeros(argshape[1], dtype=dtype) - for j0 in range(argshape[0]): - for j1 in range(argshape[1]): + pick_count = np.zeros((argshape[0], argshape[1], 0), dtype=pick_count_dtype) + if logsums: + _logsums = np.zeros((argshape[0], argshape[1], ), dtype=dtype) + else: + _logsums = np.zeros((0, 0), dtype=dtype) + for j0 in nb.prange(argshape[0]): + partial = np.zeros(dotarray.shape[1], dtype=dtype) + for j1 in range(argshape[1]): + if mask is not None: + if not mask[j0,j1]: + continue + intermediate = np.zeros({len_self_raw_functions}, dtype=dtype) {meta_code_stack_dot} - partial[j1] = np.exp(np.dot(intermediate, dotarray))[0] - local_sum = np.sum(partial) - if logsums: - _logsums[j0] = np.log(local_sum) - partial /= local_sum - if pick_counted: - _sample_choices_maker_counted(partial, random_draws[j0], result[j0], result_p[j0], pick_count[j0]) - else: - _sample_choices_maker(partial, random_draws[j0], result[j0], result_p[j0]) + partial = np.dot(intermediate, dotarray, out=partial) + shifter = np.max(partial) + partial = np.exp(partial - shifter) + local_sum = np.sum(partial) + if logsums: + _logsums[j0,j1] = np.log(local_sum) + shifter + if logsums == 1: + continue + partial /= local_sum + if pick_counted: + _sample_choices_maker_counted(partial, random_draws[j0,j1], result[j0,j1], result_p[j0,j1], pick_count[j0,j1]) + else: + _sample_choices_maker(partial, random_draws[j0,j1], result[j0,j1], result_p[j0,j1]) return result, result_p, pick_count, _logsums + """ ) +NL_1D_TEMPLATE = """ + +from sharrow.nested_logit import _utility_to_probability + +@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +def nl_transform( + argshape, + {joined_namespace_names} + dtype=np.{dtype}, + dotarray=None, + random_draws=None, + pick_counted=False, + logsums=False, + n_nodes=0, + n_alts=0, + edges_up=None, # int input shape=[edges] + edges_dn=None, # int input shape=[edges] + mu_params=None, # float input shape=[nests] + start_slots=None, # int input shape=[nests] + len_slots=None, # int input shape=[nests] + choice_dtype=np.int32, + pick_count_dtype=np.int32, + mask=None, +): + if dotarray is None: + raise ValueError("dotarray cannot be None") + assert dotarray.ndim == 2 + if mask is not None: + assert mask.ndim == 1 + assert mask.shape[0] == argshape[0] + if logsums == 1: + result = np.full((0, random_draws.shape[1]), -1, dtype=choice_dtype) + result_p = np.zeros((0, random_draws.shape[1]), dtype=dtype) + else: + result = np.full((argshape[0], random_draws.shape[1]), -1, dtype=choice_dtype) + result_p = np.zeros((argshape[0], random_draws.shape[1]), dtype=dtype) + if pick_counted: + pick_count = np.zeros((argshape[0], random_draws.shape[1]), dtype=pick_count_dtype) + else: + pick_count = np.zeros((argshape[0], 0), dtype=pick_count_dtype) + if logsums: + _logsums = np.zeros((argshape[0], ), dtype=dtype) + else: + _logsums = np.zeros((0, ), dtype=dtype) + for j0 in nb.prange(argshape[0]): + if mask is not None: + if not mask[j0]: + continue + intermediate = np.zeros({len_self_raw_functions}, dtype=dtype) + {meta_code_stack_dot} + utility = np.zeros(n_nodes, dtype=dtype) + utility[:n_alts] = np.dot(intermediate, dotarray) + if logsums == 1: + logprob = np.zeros(0, dtype=dtype) + probability = np.zeros(0, dtype=dtype) + else: + logprob = np.zeros(n_nodes, dtype=dtype) + probability = np.zeros(n_nodes, dtype=dtype) + _utility_to_probability( + n_alts, + edges_up, # int input shape=[edges] + edges_dn, # int input shape=[edges] + mu_params, # float input shape=[nests] + start_slots, # int input shape=[nests] + len_slots, # int input shape=[nests] + (logsums==1), + utility, # float output shape=[nodes] + logprob, # float output shape=[nodes] + probability, # float output shape=[nodes] + ) + if logsums: + _logsums[j0] = utility[-1] + if logsums != 1: + if pick_counted: + _sample_choices_maker_counted(probability[:n_alts], random_draws[j0], result[j0], result_p[j0], pick_count[j0]) + else: + _sample_choices_maker(probability[:n_alts], random_draws[j0], result[j0], result_p[j0]) + return result, result_p, pick_count, _logsums + +""" + + +def zero_size_to_None(x): + if x is not None and x.size == 0: + return None + return x + + +def squeeze(x, *args): + x = zero_size_to_None(x) + if x is None: + return None + try: + return np.squeeze(x, *args) + except Exception: + if hasattr(x, "shape"): + logger.error(f"failed to squeeze {args!r} from array of shape {x.shape}") + else: + logger.error(f"failed to squeeze {args!r} from array of unknown shape") + raise + class Flow: """ @@ -881,6 +1100,21 @@ def init_sub_funcs( bool_wrapping=self.bool_wrapping, ) except KeyError as key_err: + # there was an error, but lets make sure we process the + # whole expression to rewrite all the things we can before + # moving on to the fallback processing. + expr = expression_for_numba( + expr, + spacename, + dim_slots, + dim_slots, + digital_encodings=digital_encodings, + extra_vars=self.tree.extra_vars, + blenders=blenders, + bool_wrapping=self.bool_wrapping, + swallow_errors=True, + ) + # Now for the fallback processing... if ".." in key_err.args[0]: topkey, attrkey = key_err.args[0].split("..") else: @@ -910,6 +1144,26 @@ def init_sub_funcs( other_way = True # at least one variable was found in a fallback break + if not other_way and "get" in expr: + # any remaining "get" expressions with defaults should now use them + try: + expr = expression_for_numba( + expr, + spacename, + dim_slots, + dim_slots, + digital_encodings=digital_encodings, + extra_vars=self.tree.extra_vars, + blenders=blenders, + bool_wrapping=self.bool_wrapping, + get_default=True, + ) + except KeyError as err: # noqa: F841 + pass + else: + other_way = True + # at least one variable was found in a get + break if not other_way: raise if prior_expr == expr: @@ -1261,6 +1515,9 @@ def __initialize_2( mnl_template = MNL_1D_TEMPLATE.format(**locals()).format( **locals() ) + nl_template = NL_1D_TEMPLATE.format(**locals()).format( + **locals() + ) elif n_root_dims == 2: meta_template = IRUNNER_2D_TEMPLATE.format(**locals()).format( **locals() @@ -1274,6 +1531,7 @@ def __initialize_2( mnl_template = MNL_2D_TEMPLATE.format(**locals()).format( **locals() ) + nl_template = "" else: raise ValueError(f"invalid n_root_dims {n_root_dims}") @@ -1285,6 +1543,8 @@ def __initialize_2( f_code.write("\n\n") f_code.write(blacken(textwrap.dedent(mnl_template))) f_code.write("\n\n") + f_code.write(blacken(textwrap.dedent(nl_template))) + f_code.write("\n\n") f_code.write(blacken(textwrap.dedent(meta_template))) f_code.write("\n\n") f_code.write(blacken(textwrap.dedent(meta_template_dot))) @@ -1305,18 +1565,38 @@ def __initialize_2( ) f_code.write(f"flow_hash = {self.flow_hash!r}\n") - if str(self.cache_dir) not in sys.path: - logger.debug(f"inserting {self.cache_dir} into sys.path") - sys.path.insert(0, str(self.cache_dir)) + abs_cache_dir = os.path.abspath(self.cache_dir) + if str(abs_cache_dir) not in sys.path: + logger.debug(f"inserting {abs_cache_dir} into sys.path") + sys.path.insert(0, str(abs_cache_dir)) + added_cache_dir_to_sys_path = True + else: + added_cache_dir_to_sys_path = False importlib.invalidate_caches() logger.debug(f"importing {self.name}") - module = importlib.import_module(self.name) - sys.path = sys.path[1:] + try: + module = importlib.import_module(self.name) + except ModuleNotFoundError: + # maybe we got out in front of the file system, wait a beat and retry + time.sleep(2) + try: + module = importlib.import_module(self.name) + except ModuleNotFoundError: + logger.error(f"- os.getcwd: {os.getcwd()}") + for i in sys.path: + logger.error(f"- sys.path: {i}") + raise + if added_cache_dir_to_sys_path: + sys.path = sys.path[1:] self._runner = getattr(module, "runner", None) self._dotter = getattr(module, "dotter", None) self._irunner = getattr(module, "irunner", None) + self._logit_ndims = getattr(module, "logit_ndims", None) self._imnl = getattr(module, "mnl_transform", None) + self._imnl_plus1d = getattr(module, "mnl_transform_plus1d", None) + self._inestedlogit = getattr(module, "nl_transform", None) self._idotter = getattr(module, "idotter", None) + self._linemaker = getattr(module, "linemaker", None) if not writing: self.function_names = module.function_names self.output_name_positions = module.output_name_positions @@ -1393,7 +1673,7 @@ def load_raw(self, rg, args, runner=None, dtype=None, dot=None): else: raise err - def iload_raw( + def _iload_raw( self, rg, runner=None, @@ -1402,6 +1682,9 @@ def iload_raw( mnl=None, pick_counted=False, logsums=False, + nesting=None, + mask=None, + compile_watch=False, ): assert isinstance(rg, DataTree) with warnings.catch_warnings(): @@ -1409,29 +1692,59 @@ def iload_raw( "ignore", category=nb.NumbaExperimentalFeatureWarning ) try: + known_arg_names = { + "dtype", + "dotarray", + "argshape", + "random_draws", + "pick_counted", + "logsums", + "choice_dtype", + "pick_count_dtype", + "mask", + } if runner is None: if mnl is not None: - runner_ = self._imnl + if nesting is None: + if dot.shape[1] > 1: + runner_ = self._imnl_plus1d + else: + runner_ = self._imnl + else: + runner_ = self._inestedlogit + known_arg_names.update( + { + "n_nodes", + "n_alts", + "edges_up", + "edges_dn", + "mu_params", + "start_slots", + "len_slots", + } + ) elif dot is None: runner_ = self._irunner + known_arg_names.update({"mask"}) + if ( + mask is not None + and dtype is not None + and not np.issubdtype(dtype, np.floating) + ): + raise TypeError("cannot use mask unless dtype is float") else: runner_ = self._idotter else: runner_ = runner try: - named_args = inspect.getfullargspec(runner_.py_func).args + fullargspec = inspect.getfullargspec(runner_.py_func) except AttributeError: - named_args = inspect.getfullargspec(runner_).args + fullargspec = inspect.getfullargspec(runner_) + named_args = fullargspec.args arguments = [] + _arguments_names = [] for arg in named_args: - if arg in { - "dtype", - "dotarray", - "argshape", - "random_draws", - "pick_counted", - "logsums", - }: + if arg in known_arg_names: continue argument = rg.get_named_array(arg) # aux_vars get passed through as is, not forced to be arrays @@ -1448,6 +1761,7 @@ def iload_raw( arguments.append(np.asarray(argument_)) else: arguments.append(np.asarray(argument)) + _arguments_names.append(arg) kwargs = {} if dtype is not None: kwargs["dtype"] = dtype @@ -1457,12 +1771,60 @@ def iload_raw( kwargs["random_draws"] = mnl kwargs["pick_counted"] = pick_counted kwargs["logsums"] = logsums + if nesting is not None: + nesting.pop("edges_1st", None) # unused in simple NL + nesting.pop("edges_alloc", None) # unused in simple NL + kwargs.update(nesting) + if mask is not None: + kwargs["mask"] = mask tree_root_dims = rg.root_dataset.dims argshape = [ tree_root_dims[i] for i in presorted(tree_root_dims, self.dim_order, self.dim_exclude) ] - return runner_(np.asarray(argshape), *arguments, **kwargs) + if mnl is not None: + if nesting is not None: + n_alts = nesting["n_alts"] + elif len(argshape) == 2: + n_alts = argshape[1] + else: + n_alts = kwargs["dotarray"].shape[1] + if n_alts < 128: + kwargs["choice_dtype"] = np.int8 + elif n_alts < 32768: + kwargs["choice_dtype"] = np.int16 + if logger.isEnabledFor(logging.DEBUG): + logger.debug( + "========= PASSING ARGUMENT TO SHARROW LOAD ==========" + ) + logger.debug(f"{argshape=}") + for _name, _info in zip(_arguments_names, arguments): + try: + logger.debug(f"ARG {_name}: {_info.dtype}, {_info.shape}") + except AttributeError: + alt_repr = repr(_info) + if len(alt_repr) < 200: + logger.debug(f"ARG {_name}: {alt_repr}") + else: + logger.debug(f"ARG {_name}: type={type(_info)}") + for _name, _info in kwargs.items(): + try: + logger.debug(f"KWARG {_name}: {_info.dtype}, {_info.shape}") + except AttributeError: + alt_repr = repr(_info) + if len(alt_repr) < 200: + logger.debug(f"KWARG {_name}: {alt_repr}") + else: + logger.debug(f"KWARG {_name}: type={type(_info)}") + logger.debug( + "========= ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ==========" + ) + result = runner_(np.asarray(argshape), *arguments, **kwargs) + if compile_watch: + self.check_cache_misses( + runner_, log_details=compile_watch != "simple" + ) + return result except nb.TypingError as err: _raw_functions = getattr(self, "_raw_functions", {}) logger.error(f"nb.TypingError in {len(_raw_functions)} functions") @@ -1478,13 +1840,84 @@ def iload_raw( if problem: raise NameError(problem.group(1)) from err raise - except KeyError as err: - # raise the inner key error which is more helpful - context = getattr(err, "__context__", None) - if context: - raise context + # except KeyError as err: + # # raise the inner key error which is more helpful + # context = getattr(err, "__context__", None) + # if context: + # raise context + # else: + # raise err + + def check_cache_misses(self, *funcs, fresh=True, log_details=True): + self.compiled_recently = False + if not hasattr(self, "_known_cache_misses"): + self._known_cache_misses = {} + if not funcs: + funcs = ( + self._imnl, + self._imnl_plus1d, + self._inestedlogit, + self._irunner, + self._idotter, + ) + for f in funcs: + if f is None: + continue + try: + fullargspec = inspect.getfullargspec(f.py_func) + except AttributeError: + fullargspec = inspect.getfullargspec(f) + named_args = fullargspec.args + cache_misses = f.stats.cache_misses + runner_name = f.__name__ + if cache_misses: + if runner_name not in self._known_cache_misses: + self._known_cache_misses[runner_name] = {} + if fresh: + known_cache_misses = self._known_cache_misses[runner_name] else: - raise err + known_cache_misses = {} + for k, v in cache_misses.items(): + if v > known_cache_misses.get(k, 0): + if log_details: + warning_text = "\n".join( + f" - {argname}: {sig}" + for (sig, argname) in zip(k, named_args) + ) + warning_text = f"\n{runner_name}(\n{warning_text}\n)" + else: + warning_text = "" + timers = ( + f.overloads[k] + .metadata["timers"] + .get("compiler_lock", "N/A") + ) + if isinstance(timers, float): + if timers < 1e-3: + timers = f"{timers/1e-6:.0f} ยตs" + elif timers < 1: + timers = f"{timers/1e-3:.1f} ms" + else: + timers = f"{timers:.2f} s" + logger.warning( + f"cache miss in {self.flow_hash}{warning_text}\n" + f"Compile Time: {timers}" + ) + warnings.warn(f"{self.flow_hash}", CacheMissWarning) + self.compiled_recently = True + self._known_cache_misses[runner_name][k] = v + return self.compiled_recently + + @property + def cache_misses(self): + """dict[str, dict]: Numba cache misses across all defined flow methods.""" + misses = {} + for k, v in self.__dict__.items(): + from numba.core.dispatcher import Dispatcher + + if isinstance(v, Dispatcher): + misses[k] = v.stats.cache_misses.copy() + return misses def _load( self, @@ -1495,10 +1928,12 @@ def _load( runner=None, dtype=None, dot=None, - mnl_draws=None, + logit_draws=None, pick_counted=False, compile_watch=False, - logsums=False, + logsums=0, + nesting=None, + mask=None, ): """ Compute the flow outputs. @@ -1526,15 +1961,19 @@ def _load( dot-product of the computed expressions and this array of coefficients, but without ever materializing the array of computed expression values in memory, achiving significant performance gains. - mnl_draws : array-like, optional + logit_draws : array-like, optional An array of random values in the unit interval. If provided, `dot` must also be provided. The dot-product is treated as the utility function for a multinomial logit model, and these draws are used to simulate choices from the implied probabilities. compile_watch : bool, default False Watch for compiled code. - logsums : bool, default False - Also return logsums when making draws from MNL models. + logsums : int, default 0 + Set to 1 to return only logsums instead of making draws from logit models. + Set to 2 to return both logsums and draws. + nesting : dict, optional + Nesting arrays + mask : array-like, optional """ if compile_watch: compile_watch = time.time() @@ -1544,32 +1983,166 @@ def _load( source = self.tree if dtype is None and dot is not None: dtype = dot.dtype - dot_collapse = False + + if logit_draws is None and logsums == 1: + logit_draws = np.zeros(source.shape + (0,), dtype=dtype) + + use_dims = list( + presorted(source.root_dataset.dims, self.dim_order, self.dim_exclude) + ) + + if logit_draws is not None: + if dot is None: + raise NotImplementedError + if dot.ndim == 1 or (dot.ndim == 2 and dot.shape[1] == 1): + while logit_draws.ndim < self._logit_ndims: + logit_draws = np.expand_dims(logit_draws, -1) + else: + while logit_draws.ndim < self._logit_ndims + 1: + logit_draws = np.expand_dims(logit_draws, -1) + + result_dims = None + result_squeeze = None + if dot is None: + # returning extracted raw data, with all dims plus expressions + result_dims = use_dims + ["expressions"] + result_squeeze = None + else: + if not isinstance(dot, xr.DataArray): + dot_trailing_dim = ["ALT_COL"] + else: + dot_trailing_dim = [dot.dims[1]] + if dot.ndim == 1 and logit_draws is None: + # returning a dot-product for idca-type data + result_dims = use_dims + result_squeeze = (-1,) + elif dot.ndim == 2 and logit_draws is None: + # returning a dot-product for idco-type data + result_dims = use_dims + dot_trailing_dim + result_squeeze = None + elif dot.ndim > 2 and logit_draws is None: + raise NotImplementedError + else: + # returning a logit model result + if not isinstance(logit_draws, xr.DataArray): + logit_draws_trailing_dim = ["DRAW"] + else: + logit_draws_trailing_dim = [logit_draws.dims[-1]] + if dot.ndim == 1 and logit_draws.ndim == len(use_dims): + result_dims = use_dims[:-1] + logit_draws_trailing_dim + elif ( + dot.ndim == 2 + and dot.shape[1] == 1 + and logit_draws.ndim == len(use_dims) + and logit_draws.shape[-1] == 1 + ): + result_dims = use_dims[:-1] + result_squeeze = (-1,) + elif ( + dot.ndim == 2 + and dot.shape[1] == 1 + and logit_draws.ndim == len(use_dims) + ): + result_dims = use_dims[:-1] + logit_draws_trailing_dim + elif dot.ndim == 2 and logit_draws.ndim == len(use_dims): + result_dims = use_dims[:-1] + dot_trailing_dim + elif dot.ndim == 1 and logit_draws.ndim == len(use_dims) + 1: + result_dims = use_dims[:-1] + logit_draws_trailing_dim + if logit_draws.shape[-1] == 1: + result_squeeze = (-1,) + elif ( + dot.ndim == 2 + and logit_draws.ndim == len(use_dims) + 1 + and logit_draws.shape[-1] == 1 + and self._logit_ndims == 1 + ): + result_dims = use_dims + result_squeeze = (-1,) + elif ( + dot.ndim == 2 + and logit_draws.ndim == len(use_dims) + 1 + and logit_draws.shape[-1] > 1 + and self._logit_ndims == 1 + ): + result_dims = use_dims + logit_draws_trailing_dim + elif ( + dot.ndim == 2 + and logit_draws.ndim == len(use_dims) + 1 + and logit_draws.shape[-1] == 0 + ): + # logsums only + result_dims = use_dims + result_squeeze = (-1,) + elif ( + dot.ndim == 2 + and logit_draws.ndim == len(use_dims) + 1 + and logit_draws.shape[-1] > 1 + and self._logit_ndims == 2 + ): + # wide choices + result_dims = use_dims + logit_draws_trailing_dim + elif ( + dot.ndim == 2 + and logit_draws.ndim == len(use_dims) + 1 + and logit_draws.shape[-1] == 1 + and self._logit_ndims == 2 + ): + # wide choices + result_dims = use_dims + result_squeeze = (-1,) + else: + print(f"{dot.ndim=}") + print(f"{logit_draws.ndim=}") + print(f"{len(use_dims)=}") + print(f"{self._logit_ndims=}") + raise NotImplementedError() + + # dot_collapse = False result_p = None pick_count = None out_logsum = None if dot is not None and dot.ndim == 1: dot = np.expand_dims(dot, -1) - dot_collapse = True - mnl_collapse = False - if mnl_draws is not None and mnl_draws.ndim == 1: - mnl_draws = np.expand_dims(mnl_draws, -1) - mnl_collapse = True + # dot_collapse = True + # mnl_collapse = False + # idca_collapse = False + # if logit_draws is not None and logit_draws.ndim == 1: + # logit_draws = np.expand_dims(logit_draws, -1) + # mnl_collapse = True + # elif ( + # logit_draws is not None + # and logit_draws.ndim == 2 + # and dot.ndim == 2 + # and dot.shape[1] == 1 + # ): + # idca_collapse = True if not source.relationships_are_digitized: source = source.digitize_relationships() if source.relationships_are_digitized: - if mnl_draws is None: - result = self.iload_raw(source, runner=runner, dtype=dtype, dot=dot) + if logit_draws is None: + result = self._iload_raw( + source, + runner=runner, + dtype=dtype, + dot=dot, + mask=mask, + compile_watch=compile_watch, + ) else: - result, result_p, pick_count, out_logsum = self.iload_raw( + result, result_p, pick_count, out_logsum = self._iload_raw( source, runner=runner, dtype=dtype, dot=dot, - mnl=mnl_draws, + mnl=logit_draws, pick_counted=pick_counted, logsums=logsums, + nesting=nesting, + mask=mask, + compile_watch=compile_watch, ) + pick_count = zero_size_to_None(pick_count) + out_logsum = zero_size_to_None(out_logsum) else: raise RuntimeError("please digitize") if as_dataframe: @@ -1582,111 +2155,85 @@ def _load( {k: result[:, n] for n, k in enumerate(self._raw_functions.keys())} ) elif as_dataarray: - use_dims = list( - presorted(source.root_dataset.dims, self.dim_order, self.dim_exclude) - ) - if dot is None: + + if result_squeeze: + result = squeeze(result, result_squeeze) + result_p = squeeze(result_p, result_squeeze) + pick_count = squeeze(pick_count, result_squeeze) + result_coords = { + k: v for k, v in source.root_dataset.coords.items() if k in result_dims + } + if result is not None: result = xr.DataArray( result, - dims=use_dims + ["expressions"], - coords={ - k: v - for k, v in source.root_dataset.coords.items() - if k in use_dims - }, - ) - result.coords["expressions"] = self.function_names - elif dot_collapse and mnl_draws is None: - result = xr.DataArray( - np.squeeze(result, -1), - dims=use_dims, - coords=source.root_dataset.coords, - ) - elif mnl_collapse: - if isinstance(dot, xr.DataArray): - plus_dims = list(dot.dims[1:]) - else: - plus_dims = [] - result = xr.DataArray( - np.squeeze(result, -1), - dims=use_dims[:-1] + plus_dims, - coords=source.root_dataset.coords, + dims=result_dims, + coords=result_coords, ) + if "expressions" in result_dims: + result.coords["expressions"] = self.function_names + if result_p is not None: result_p = xr.DataArray( - np.squeeze(result_p, -1), - dims=use_dims[:-1] + plus_dims, - coords=source.root_dataset.coords, + result_p, + dims=result_dims, + coords=result_coords, ) - if pick_count is not None: - pick_count = xr.DataArray( - np.squeeze(pick_count, -1), - dims=use_dims[:-1] + plus_dims, - coords=source.root_dataset.coords, - ) - for plus_dim in plus_dims: - if plus_dim in dot.coords: - result.coords[plus_dim] = dot.coords[plus_dim] - result_p.coords[plus_dim] = dot.coords[plus_dim] - if pick_count is not None: - pick_count.coords[plus_dim] = dot.coords[plus_dim] - elif isinstance(dot, xr.DataArray): - plus_dims = dot.dims[1:] - result = xr.DataArray( - result, - dims=use_dims + list(plus_dims), - coords=source.root_dataset.coords, + if pick_count is not None: + pick_count = xr.DataArray( + pick_count, + dims=result_dims, + coords=result_coords, ) - for plus_dim in plus_dims: - if plus_dim in dot.coords: - result.coords[plus_dim] = dot.coords[plus_dim] - else: - dot_ = xr.DataArray(dot) - plus_dims = dot_.dims[1:] - result = xr.DataArray( - result, - dims=use_dims + list(plus_dims), - coords=source.root_dataset.coords, + if out_logsum is not None: + out_logsum = xr.DataArray( + out_logsum, + dims=result_dims[: out_logsum.ndim], + coords={ + k: v + for k, v in source.root_dataset.coords.items() + if k in result_dims[: out_logsum.ndim] + }, ) - elif dot_collapse and mnl_draws is None: - result = np.squeeze(result, -1) - elif mnl_collapse: - result = np.squeeze(result, -1) - result_p = np.squeeze(result_p, -1) - if compile_watch: - self.compiled_recently = False - for i in os.walk(os.path.join(self.cache_dir, self.name)): - for f in i[2]: - fi = os.path.join(i[0], f) - try: - t = os.path.getmtime(fi) - except FileNotFoundError: - # something is actively happening in this directory - self.compiled_recently = True - logger.warning( - f"unidentified activity (file deletion) detected for {self.name}" - ) - break - if t > compile_watch: - self.compiled_recently = True - logger.warning(f"compilation activity detected for {self.name}") - break - if self.compiled_recently: - break + else: + if result_squeeze: + result = squeeze(result, result_squeeze) + result_p = squeeze(result_p, result_squeeze) + pick_count = squeeze(pick_count, result_squeeze) + + # if compile_watch: + # self.compiled_recently = False + # for i in os.walk(os.path.join(self.cache_dir, self.name)): + # for f in i[2]: + # fi = os.path.join(i[0], f) + # try: + # t = os.path.getmtime(fi) + # except FileNotFoundError: + # # something is actively happening in this directory + # self.compiled_recently = True + # logger.warning( + # f"unidentified activity (file deletion) detected for {self.name}" + # ) + # break + # if t > compile_watch: + # self.compiled_recently = True + # logger.warning(f"compilation activity detected for {self.name}") + # break + # if self.compiled_recently: + # break + if not compile_watch: try: del self.compiled_recently except AttributeError: pass + if out_logsum is not None: + return result, result_p, pick_count, out_logsum + if pick_count is not None: + return result, result_p, pick_count if result_p is not None: - if logsums: - return result, result_p, pick_count, out_logsum - if pick_counted: - return result, result_p, pick_count - else: - return result, result_p + return result, result_p return result - def load(self, source=None, dtype=None, compile_watch=False): + def load(self, source=None, dtype=None, compile_watch=False, mask=None): """ Compute the flow outputs as a numpy array. @@ -1701,14 +2248,18 @@ def load(self, source=None, dtype=None, compile_watch=False): compile_watch : bool, default False Set the `compiled_recently` flag on this flow to True if any file modification activity is observed in the cache directory. + mask : array-like, optional + Only compute values for items where mask is truthy. Returns ------- numpy.array """ - return self._load(source=source, dtype=dtype, compile_watch=compile_watch) + return self._load( + source=source, dtype=dtype, compile_watch=compile_watch, mask=mask + ) - def load_dataframe(self, source=None, dtype=None, compile_watch=False): + def load_dataframe(self, source=None, dtype=None, compile_watch=False, mask=None): """ Compute the flow outputs as a pandas.DataFrame. @@ -1723,16 +2274,22 @@ def load_dataframe(self, source=None, dtype=None, compile_watch=False): compile_watch : bool, default False Set the `compiled_recently` flag on this flow to True if any file modification activity is observed in the cache directory. + mask : array-like, optional + Only compute values for items where mask is truthy. Returns ------- pandas.DataFrame """ return self._load( - source=source, dtype=dtype, as_dataframe=True, compile_watch=compile_watch + source=source, + dtype=dtype, + as_dataframe=True, + compile_watch=compile_watch, + mask=mask, ) - def load_dataarray(self, source=None, dtype=None, compile_watch=False): + def load_dataarray(self, source=None, dtype=None, compile_watch=False, mask=None): """ Compute the flow outputs as a xarray.DataArray. @@ -1747,13 +2304,19 @@ def load_dataarray(self, source=None, dtype=None, compile_watch=False): compile_watch : bool, default False Set the `compiled_recently` flag on this flow to True if any file modification activity is observed in the cache directory. + mask : array-like, optional + Only compute values for items where mask is truthy. Returns ------- xarray.DataArray """ return self._load( - source=source, dtype=dtype, as_dataarray=True, compile_watch=compile_watch + source=source, + dtype=dtype, + as_dataarray=True, + compile_watch=compile_watch, + mask=mask, ) def dot(self, coefficients, source=None, dtype=None, compile_watch=False): @@ -1821,15 +2384,18 @@ def dot_dataarray(self, coefficients, source=None, dtype=None, compile_watch=Fal compile_watch=compile_watch, ) - def mnl_draws( + def logit_draws( self, coefficients, - draws, + draws=None, source=None, pick_counted=False, - logsums=False, + logsums=0, dtype=None, compile_watch=False, + nesting=None, + as_dataarray=False, + mask=None, ): """ Make random simulated choices for a multinomial logit model. @@ -1852,8 +2418,9 @@ def mnl_draws( tree used to initialize this flow is used. pick_counted : bool, default False Whether to tally multiple repeated choices with a pick count. - logsums : bool, default False - Whether to also return logsums. + logsums : int, default 0 + Set to 1 to return only logsums instead of making draws from logit models. + Set to 2 to return both logsums and draws. dtype : str or dtype Override the default dtype for the probability. May trigger re-compilation of the underlying code. The choices and pick counts (if included) @@ -1861,6 +2428,11 @@ def mnl_draws( compile_watch : bool, default False Set the `compiled_recently` flag on this flow to True if any file modification activity is observed in the cache directory. + nesting : dict, optional + Nesting instructions + as_dataarray : bool, default False + mask : array-like, optional + Only compute values for items where mask is truthy. Returns ------- @@ -1875,11 +2447,14 @@ def mnl_draws( return self._load( source=source, dot=coefficients, - mnl_draws=draws, + logit_draws=draws, dtype=dtype, pick_counted=pick_counted, compile_watch=compile_watch, - logsums=logsums, + logsums=np.int8(logsums), + nesting=nesting, + as_dataarray=as_dataarray, + mask=mask, ) @property @@ -1933,3 +2508,84 @@ def show_code(self, linenos="inline"): bbedit_url = f"x-bbedit://open?url=file://{codefile}" bb_link = f'{codefile}' return HTML(f"

{bb_link}

{pretty}") + + def init_streamer(self, source=None, dtype=None): + """ + Initialize a compiled closure on the data for loading individual lines. + + Parameters + ---------- + source : DataTree, optional + This is the source of the data for this flow. If not provided, the + tree used to initialize this flow is used. + dtype : str or dtype, default float32 + Override the default dtype for the result. May trigger re-compilation + of the underlying code. + + Returns + ------- + callable + """ + if source is None: + source = self.tree + if dtype is None: + dtype = np.float32 + + named_args = inspect.getfullargspec(self._linemaker.py_func).args + skip_args = ["intermediate", "j0", "j1"] + named_args = tuple(i for i in named_args if i not in skip_args) + + general_mapping = {} + for k, v in source.subspaces.items(): + for i in v: + mangled_key = f"__{k}__{i}" + if mangled_key in named_args: + general_mapping[mangled_key] = v[i].to_numpy() + for i in v.indexes: + mangled_key = f"__{k}__{i}" + if mangled_key in named_args: + general_mapping[mangled_key] = v[i].to_numpy() + + selected_args = tuple(general_mapping[k] for k in named_args) + len_self_raw_functions = len(self._raw_functions) + tree_root_dims = source.root_dataset.dims + argshape = tuple( + tree_root_dims[i] + for i in presorted(tree_root_dims, self.dim_order, self.dim_exclude) + ) + + if len(argshape) == 1: + linemaker = self._linemaker + + @nb.njit + def streamer(c, out=None): + if out is None: + result = np.zeros(len_self_raw_functions, dtype=dtype) + else: + result = out + assert result.ndim == 1 + assert result.size == len_self_raw_functions + linemaker(result, c, *selected_args) + return result + + elif len(argshape) == 2: + n_alts = argshape[1] + linemaker = self._linemaker + + @nb.njit + def streamer(c, out=None): + if out is None: + result = np.zeros((n_alts, len_self_raw_functions), dtype=dtype) + else: + result = out + assert result.shape == (n_alts, len_self_raw_functions) + for i in range(n_alts): + linemaker(result[i, :], c, i, *selected_args) + return result + + else: + raise NotImplementedError( + f"root tree with {len(argshape)} dims {argshape=}" + ) + + return streamer diff --git a/sharrow/logging.py b/sharrow/logging.py index 4be6c91..5b810a1 100644 --- a/sharrow/logging.py +++ b/sharrow/logging.py @@ -6,7 +6,7 @@ LOGGER_NAME = "sharrow" FILE_LOG_FORMAT = "%(name)s.%(levelname)s: %(message)s" CONSOLE_LOG_FORMAT = "[%(asctime)s] %(name)s.%(levelname)s: %(message)s" -DEFAULT_LOG_LEVEL = logging.DEBUG +DEFAULT_LOG_LEVEL = logging.INFO def timesize_single(t): @@ -37,19 +37,22 @@ def log_to_console(level=None): logger = logging.getLogger(LOGGER_NAME) + if level < logger.level or logger.level == logging.NOTSET: + logger.setLevel(level) + # avoid creation of multiple stream handlers for logging to console for entry in logger.handlers: if (isinstance(entry, logging.StreamHandler)) and ( entry.formatter._fmt == CONSOLE_LOG_FORMAT ): + if level < entry.level: + entry.setLevel(level) return logger console_handler = logging.StreamHandler(stream=sys.stderr) console_handler.setLevel(level) console_handler.setFormatter(logging.Formatter(CONSOLE_LOG_FORMAT)) logger.addHandler(console_handler) - if level < logger.getEffectiveLevel(): - logger.setLevel(level) return logger diff --git a/sharrow/nested_logit.py b/sharrow/nested_logit.py new file mode 100644 index 0000000..452df23 --- /dev/null +++ b/sharrow/nested_logit.py @@ -0,0 +1,194 @@ +from typing import Mapping + +import numba as nb +import numpy as np + + +@nb.njit(error_model="numpy", fastmath=True, cache=True) +def _utility_to_probability( + n_alts, + edges_up, # int input shape=[edges] + edges_dn, # int input shape=[edges] + mu_params, # float input shape=[nests] + start_slots, # int input shape=[nests] + len_slots, # int input shape=[nests] + only_utility, # + utility, # float output shape=[nodes] + logprob, # float output shape=[nodes] + probability, # float output shape=[nodes] +): + + for up in range(n_alts, utility.size): + up_nest = up - n_alts + n_children_for_parent = len_slots[up_nest] + shifter = -np.inf + shifter_position = -1 + mu_up = mu_params[up_nest] + if mu_up: + for n in range(n_children_for_parent): + edge = start_slots[up_nest] + n + dn = edges_dn[edge] + if utility[dn] > -np.inf: + z = utility[dn] / mu_up + if z > shifter: + shifter = z + shifter_position = dn + for n in range(n_children_for_parent): + edge = start_slots[up_nest] + n + dn = edges_dn[edge] + if utility[dn] > -np.inf: + if shifter_position == dn: + utility[up] += 1 + else: + utility[up] += np.exp((utility[dn] / mu_up) - shifter) + utility[up] = (np.log(utility[up]) + shifter) * mu_up + else: # mu_up is zero + for n in range(n_children_for_parent): + edge = start_slots[up_nest] + n + dn = edges_dn[edge] + if utility[dn] > utility[up]: + utility[up] = utility[dn] + + if only_utility: + return + + for s in range(edges_up.size): + dn = edges_dn[s] + up = edges_up[s] + mu_up = mu_params[up - n_alts] + if np.isinf(utility[up]) and utility[up] < 0: + logprob[dn] = -np.inf + else: + logprob[dn] = (utility[dn] - utility[up]) / mu_up + + # logprob becomes conditional_probability + conditional_probability = logprob + for i in range(logprob.size): + conditional_probability[i] = np.exp(logprob[i]) + + # probability + probability[-1] = 1.0 + for s in range(edges_up.size - 1, -1, -1): + dn = edges_dn[s] + up = edges_up[s] + probability[dn] = probability[up] * conditional_probability[dn] + + +@nb.njit +def _utility_to_probability_array( + edges_up, # int input shape=[edges] + edges_dn, # int input shape=[edges] + mu_params, # float input shape=[nests] + start_slots, # int input shape=[nests] + len_slots, # int input shape=[nests] + utility, # float output shape=[nodes] +): + pr = np.zeros_like(utility) + n_nodes = mu_params.size + n_alts = utility.shape[1] + for n in range(utility.shape[0]): + _pr = np.zeros(n_nodes, dtype=np.float32) + _util = np.zeros(n_nodes, dtype=np.float32) + _logpr = np.zeros(n_nodes, dtype=np.float32) + _util[:n_alts] = utility[n, :n_alts] + _utility_to_probability( + n_alts, + edges_up, # int input shape=[edges] + edges_dn, # int input shape=[edges] + mu_params[n_alts:], # float input shape=[nests] + start_slots[n_alts:], # int input shape=[nests] + len_slots[n_alts:], # int input shape=[nests] + False, # + _util, # float output shape=[nodes] + _logpr, # float output shape=[nodes] + _pr, # float output shape=[nodes] + ) + pr[n, :] = _pr[:n_alts] + return pr + + +@nb.njit +def _utility_to_logsums_array( + edges_up, # int input shape=[edges] + edges_dn, # int input shape=[edges] + mu_params, # float input shape=[nests] + start_slots, # int input shape=[nests] + len_slots, # int input shape=[nests] + utility, # float output shape=[nodes] +): + logsums = np.zeros(utility.shape[0], dtype=np.float32) + n_nodes = mu_params.size + n_alts = utility.shape[1] + for n in range(utility.shape[0]): + _pr = np.zeros(n_nodes, dtype=np.float32) + _util = np.zeros(n_nodes, dtype=np.float32) + _logpr = np.zeros(n_nodes, dtype=np.float32) + _util[:n_alts] = utility[n, :n_alts] + _utility_to_probability( + n_alts, + edges_up, # int input shape=[edges] + edges_dn, # int input shape=[edges] + mu_params[n_alts:], # float input shape=[nests] + start_slots[n_alts:], # int input shape=[nests] + len_slots[n_alts:], # int input shape=[nests] + True, # + _util, # float output shape=[nodes] + _logpr, # float output shape=[nodes] + _pr, # float output shape=[nodes] + ) + logsums[n] = _util[-1] + return logsums + + +def construct_nesting_tree(alternatives, nesting_settings): + """ + Construct a larch NestingTree from ActivitySim settings. + + Parameters + ---------- + alternatives : Mapping or Sequence + If given as a Mapping (dict), the keys are the alternative names + as strings, and the values are alternative code numbers to use + in larch. If given as a Sequence, the values are the alternative + names, and unique sequential codes will be created starting from 1. + nesting_settings : Mapping + The 'NESTS' section of the ActivitySim config file. + + Returns + ------- + NestingTree + """ + from larch.model.tree import NestingTree + + if not isinstance(alternatives, Mapping): + alt_names = list(alternatives) + alt_codes = np.arange(1, len(alt_names) + 1) + alternatives = dict(zip(alt_names, alt_codes)) + + tree = NestingTree() + nest_names_to_codes = alternatives.copy() + nest_names_to_codes["root"] = 0 + for alt_name, alt_code in alternatives.items(): + tree.add_node(alt_code, name=alt_name) + + def make_nest(cfg, parent_code=0): + nonlocal nest_names_to_codes + if cfg["name"] != "root": + if cfg["name"] not in nest_names_to_codes: + n = tree.new_node( + name=cfg["name"], + parameter=str(cfg["coefficient"]), + parent=parent_code, + ) + nest_names_to_codes[cfg["name"]] = n + else: + tree.add_edge(parent_code, nest_names_to_codes[cfg["name"]]) + for a in cfg["alternatives"]: + if isinstance(a, str): + tree.add_edge(nest_names_to_codes[cfg["name"]], nest_names_to_codes[a]) + else: + make_nest(a, parent_code=nest_names_to_codes[cfg["name"]]) + + make_nest(nesting_settings) + + return tree diff --git a/sharrow/relationships.py b/sharrow/relationships.py index 6654788..50d49aa 100644 --- a/sharrow/relationships.py +++ b/sharrow/relationships.py @@ -9,6 +9,16 @@ from .dataset import Dataset, construct +try: + from dask.array import Array as dask_array_type +except ModuleNotFoundError: + dask_array_type = () + +try: + from sparse import SparseArray as sparse_array_type +except ModuleNotFoundError: + sparse_array_type = () + try: from ast import unparse except ImportError: @@ -46,15 +56,17 @@ def _require_string(x): def _iat(source, *, _names=None, _load=False, _index_name=None, **idxs): loaders = {} - if _index_name is None: - _index_name = "index" + inum = 0 + + def _ixname(): + if _index_name is not None: + return _index_name + nonlocal inum + inum += 1 + return f"index{inum}" + for k, v in idxs.items(): - if v.ndim == 1: - loaders[k] = xr.DataArray(v, dims=[_index_name]) - else: - loaders[k] = xr.DataArray( - v, dims=[f"{_index_name}{n}" for n in range(v.ndim)] - ) + loaders[k] = xr.DataArray(v, dims=[_ixname() for n in range(v.ndim)]) if _names: ds = source[_names] else: @@ -66,15 +78,17 @@ def _iat(source, *, _names=None, _load=False, _index_name=None, **idxs): def _at(source, *, _names=None, _load=False, _index_name=None, **idxs): loaders = {} - if _index_name is None: - _index_name = "index" + inum = 0 + + def _ixname(): + if _index_name is not None: + return _index_name + nonlocal inum + inum += 1 + return f"index{inum}" + for k, v in idxs.items(): - if v.ndim == 1: - loaders[k] = xr.DataArray(v, dims=[_index_name]) - else: - loaders[k] = xr.DataArray( - v, dims=[f"{_index_name}{n}" for n in range(v.ndim)] - ) + loaders[k] = xr.DataArray(v, dims=[_ixname() for n in range(v.ndim)]) if _names: ds = source[_names] else: @@ -136,6 +150,17 @@ def xgather(source, positions, indexes): return gather(igather(source, positions), indexes) +def _dataarray_to_numpy(self) -> np.ndarray: + """Coerces wrapped data to numpy and returns a numpy.ndarray""" + data = self.data + if isinstance(data, dask_array_type): + data = data.compute() + if isinstance(data, sparse_array_type): + data = data.todense() + data = np.asarray(data) + return data + + class Relationship: """ Defines a linkage between datasets in a `DataTree`. @@ -205,9 +230,11 @@ def from_string(cls, s): if "->" in s: parent, child = s.split("->", 1) i = "position" - elif "@": + elif "@" in s: parent, child = s.split("@", 1) i = "label" + else: + raise ValueError(f"cannot interpret relationship {s!r}") p1, p2 = parent.split(".", 1) c1, c2 = child.split(".", 1) p1 = p1.strip() @@ -335,6 +362,12 @@ def shape(self): self.root_dataset.dims[i] for i in dim_order if i not in self.dim_exclude ) + @property + def root_dims(self): + from .flows import presorted + + return tuple(presorted(self.root_dataset, self.dim_order, self.dim_exclude)) + def __shallow_copy_extras(self): return dict( extra_funcs=self.extra_funcs, @@ -342,6 +375,7 @@ def __shallow_copy_extras(self): aux_vars=self.aux_vars, cache_dir=self.cache_dir, force_digitization=self.force_digitization, + dim_order=self.dim_order, ) def __repr__(self): @@ -366,6 +400,11 @@ def __repr__(self): s += "\n relationships: none" return s + def view_relationships(self, fontname="Arial", fontsize=9): + from .viz import display_svg, make_graph + + return display_svg(make_graph(self, fontname=fontname, fontsize=fontsize)) + def _hash_features(self): h = [] if len(self._graph.nodes): @@ -432,9 +471,11 @@ def add_relationship(self, *args, **kwargs): if "->" in s: parent, child = s.split("->", 1) i = "position" - elif "@": + elif "@" in s: parent, child = s.split("@", 1) i = "label" + else: + raise ValueError(f"cannot interpret relationship {s!r}") p1, p2 = parent.split(".", 1) c1, c2 = child.split(".", 1) p1 = p1.strip() @@ -543,14 +584,61 @@ def _get_relationship(self, edge): ) def __getitem__(self, item): + return self.get(item) + + def get(self, item, default=None, broadcast=True, coords=True): + """ + Access variable(s) from this tree. + + Parameters + ---------- + item : str or Sequence[str] + Each value can be just the name of the variable if that name is unique + within the tree, or use dotted notation ('node_name.var_name') to give + the node name explicitly and resolve ambiguity as necessary. + default + If provided, this default value is used for any missing item(s). + broadcast : bool, default True + Broadcast all arrays up to the dimensions of the root node in the tree. + coords : bool, default True + Attach coordinates from the root node of the tree to the result. + + Returns + ------- + DataArray or Dataset + """ if isinstance(item, (list, tuple)): from .dataset import Dataset - return Dataset({k: self[k] for k in item}) + return Dataset( + { + k: self.get(k, default=default, broadcast=broadcast, coords=coords) + for k in item + } + ) try: - return self._getitem(item) + result = self._getitem(item, dim_names_from_top=True) except KeyError: - return self._getitem(item, include_blank_dims=True) + try: + result = self._getitem( + item, include_blank_dims=True, dim_names_from_top=True + ) + except KeyError: + if default is None: + raise + else: + result = xr.DataArray(default) + root_dataset = self.root_dataset + if result.dims != self.root_dims and broadcast: + result, _ = xr.broadcast(result, root_dataset) + if coords: + add_coords = {} + for i in result.dims: + if i not in result.coords and i in root_dataset.coords: + add_coords[i] = root_dataset.coords[i] + if add_coords: + result = result.assign_coords(add_coords) + return result def finditem(self, item, maybe_in=None): if maybe_in is not None and maybe_in in self._graph.nodes: @@ -560,7 +648,12 @@ def finditem(self, item, maybe_in=None): return self._getitem(item, just_node_name=True) def _getitem( - self, item, include_blank_dims=False, only_dims=False, just_node_name=False + self, + item, + include_blank_dims=False, + only_dims=False, + just_node_name=False, + dim_names_from_top=False, ): if isinstance(item, (list, tuple)): @@ -614,9 +707,25 @@ def _getitem( else: result = dataset[item] dims_in_result = set(result.dims) + top_dim_names = {} for path in nx.algorithms.simple_paths.all_simple_edge_paths( self._graph, self.root_node_name, current_node ): + if dim_names_from_top: + e = path[0] + top_dim_name = self._graph.edges[e].get("parent_name") + root_dataset = self.root_dataset + # deconvert digitized dim names back to native dims + if ( + top_dim_name not in root_dataset.dims + and top_dim_name in root_dataset.variables + ): + if root_dataset.variables[top_dim_name].ndim == 1: + top_dim_name = root_dataset.variables[ + top_dim_name + ].dims[0] + else: + top_dim_name = None path_dim = self._graph.edges[path[-1]].get("child_name") if path_dim not in dims_in_result: continue @@ -633,11 +742,19 @@ def _getitem( ] if r.indexing == "label": t1 = t2.sel( - {r.child_name: t1[r.parent_name].to_numpy()} + { + r.child_name: _dataarray_to_numpy( + t1[r.parent_name] + ) + } ) else: # by position t1 = t2.isel( - {r.child_name: t1[r.parent_name].to_numpy()} + { + r.child_name: _dataarray_to_numpy( + t1[r.parent_name] + ) + } ) # final node in path e = path[-1] @@ -647,18 +764,23 @@ def _getitem( if t1 is None: t1 = self._graph.nodes[r.parent_data].get("dataset") if r.indexing == "label": - _labels[r.child_name] = t1[r.parent_name].to_numpy() + _labels[r.child_name] = _dataarray_to_numpy( + t1[r.parent_name] + ) else: # by position - _idx = t1[r.parent_name].to_numpy() + _idx = _dataarray_to_numpy(t1[r.parent_name]) if not np.issubdtype(_idx.dtype, np.integer): _idx = _idx.astype(np.int64) _positions[r.child_name] = _idx - + if top_dim_name is not None: + top_dim_names[r.child_name] = top_dim_name y = xgather(result, _positions, _labels) if len(result.dims) == 1 and len(y.dims) == 1: y = y.rename({y.dims[0]: result.dims[0]}) elif len(dims_in_result) == len(y.dims): y = y.rename({_i: _j for _i, _j in zip(y.dims, result.dims)}) + if top_dim_names: + y = y.rename(top_dim_names) return y else: examined.add(current_node) @@ -868,7 +990,7 @@ def get_indexes( result[k] = result_k if as_dict: - result = {k: v.to_numpy() for k, v in result.items()} + result = {k: _dataarray_to_numpy(v) for k, v in result.items()} else: result = Dataset(result) if use_cache: @@ -1065,7 +1187,12 @@ def get_named_array(self, mangled_name): return dataset[name2[:-8]].data.indptr elif name2.endswith("__indices"): return dataset[name2[:-9]].data.indices - return dataset[name2].to_numpy() + try: + _d = dataset[name2] + except KeyError as err: + raise KeyError(f"{name1}.{name2}") from err + else: + return _dataarray_to_numpy(_d) _BY_OFFSET = "digitizedOffset" @@ -1107,8 +1234,11 @@ def digitize_relationships(self, inplace=False, redigitize=True): downstream = c_dataset[r.child_name] # vectorize version - mapper = {i: j for (j, i) in enumerate(downstream.to_numpy())} - offsets = xr.apply_ufunc(np.vectorize(mapper.get), upstream) + mapper = {i: j for (j, i) in enumerate(_dataarray_to_numpy(downstream))} + if upstream.size: + offsets = xr.apply_ufunc(np.vectorize(mapper.get), upstream) + else: + offsets = xr.DataArray([], dims=["index"]) if offsets.dtype.kind != "i": warnings.warn( f"detected missing values in digitizing {r.parent_data}.{r.parent_name}", @@ -1222,7 +1352,11 @@ def _arg_tokenizer( upside = ", ".join(unparse(t) for t in upside_ast) except: # noqa: E722 for t in upside_ast: - print(f"t:{t}") + str_t = str(t) + if len(str_t) < 2000: + print(f"t:{str_t}") + else: + print(f"t:{str_t[:200]}...") raise # check for redirection target @@ -1268,3 +1402,51 @@ def copy(self): return type(self)( self._graph.copy(), self.root_node_name, **self.__shallow_copy_extras() ) + + def all_var_names(self, uniquify=False, _duplicated_names=None): + ordered_names = [] + require_unique = _duplicated_names is None and not uniquify + need_second_pass = _duplicated_names is None and uniquify + print(f"{require_unique=}") + discovered_names = set() + duplicated_names = _duplicated_names or set() + for spacename, space in self.subspaces_iter(): + for name in space.variables: + if name in duplicated_names: + if require_unique: + raise ValueError(f"duplicate name {name}") + elif uniquify: + ordered_names.append(f"{spacename}.{name}") + else: + ordered_names.append(name) + elif name in discovered_names: + duplicated_names.add(name) + if require_unique: + raise ValueError(f"duplicate name {name}") + else: + ordered_names.append(name) + else: + discovered_names.add(name) + ordered_names.append(name) + if need_second_pass: + return self.all_var_names(uniquify=True, _duplicated_names=duplicated_names) + return ordered_names + + def merged_dataset(self, columns=None, uniquify=False): + if columns is None: + columns = self.all_var_names(uniquify=uniquify) + if len(self.root_dataset.dims) > 1: + raise NotImplementedError("only single dim root datasets") + dim_name = self.root_dataset.single_dim.dim_name + vx = [] + coords = {} + for k in columns: + v = self._getitem(k).single_dim.rename(dim_name) + if v.name == v.dims[0]: + coords[v.name] = v + else: + vx.append(v) + result = xr.merge(vx, compat="override", join="override") + if coords: + result.assign_coords(coords) + return result diff --git a/sharrow/selectors.py b/sharrow/selectors.py index d28af7e..5fb6bef 100644 --- a/sharrow/selectors.py +++ b/sharrow/selectors.py @@ -271,10 +271,13 @@ def __call__( raw_idxs[k] = np.asarray(v) modified_idxs[k] = v else: - upstream = xr.DataArray(np.asarray(v), dims=["index"]) - downstream = self._obj[k] - mapper = {i: j for (j, i) in enumerate(downstream.to_numpy())} - offsets = xr.apply_ufunc(np.vectorize(mapper.get), upstream) + if v.size: + upstream = xr.DataArray(np.asarray(v), dims=["index"]) + downstream = self._obj[k] + mapper = {i: j for (j, i) in enumerate(downstream.to_numpy())} + offsets = xr.apply_ufunc(np.vectorize(mapper.get), upstream) + else: + offsets = xr.DataArray([], dims=["index"]) raw_idxs[target] = np.asarray(offsets) modified_idxs[target] = self._obj[f"_digitized_{target}_of_{k}"][ offsets diff --git a/sharrow/shared_memory.py b/sharrow/shared_memory.py index 9f92f7d..8b493eb 100644 --- a/sharrow/shared_memory.py +++ b/sharrow/shared_memory.py @@ -248,7 +248,7 @@ def release_shared_memory(self): def delete_shared_memory_files(key): delete_shared_memory_files(key) - def to_shared_memory(self, key=None, mode="r+"): + def to_shared_memory(self, key=None, mode="r+", _dupe=True): """ Load this Dataset into shared memory. @@ -390,7 +390,7 @@ def emit(k, a, is_coord): create_shared_list( [pickle.dumps(self._obj.attrs)] + [pickle.dumps(i) for i in wrappers], key ) - return type(self).from_shared_memory(key, own_data=True, mode=mode) + return type(self).from_shared_memory(key, own_data=mem, mode=mode) @property def shared_memory_key(self): @@ -409,9 +409,10 @@ def from_shared_memory(cls, key, own_data=False, mode="r+"): key : str An identifying key for this shared memory. Use the same key in `from_shared_memory` to recreate this Dataset elsewhere. - own_data : bool, default False + own_data : bool or memmap, default False The returned Dataset object references the shared memory but is - not the "owner" of this data unless this flag is set. + not the "owner" of this data unless this flag is set. Pass a + memmap to reuse an existing buffer. Returns ------- @@ -429,7 +430,12 @@ def from_shared_memory(cls, key, own_data=False, mode="r+"): except AttributeError: # for memmap, list is loaded from pickle, not shared ram pass - mem = open_shared_memory_array(key, mode=mode) + + if own_data and not (own_data is True): + mem = own_data + own_data = True + else: + mem = open_shared_memory_array(key, mode=mode) _shared_memory_objs_.append(mem) if key.startswith("memmap:"): buffer = memoryview(mem) diff --git a/sharrow/tests/test_nesting.py b/sharrow/tests/test_nesting.py new file mode 100644 index 0000000..5059f04 --- /dev/null +++ b/sharrow/tests/test_nesting.py @@ -0,0 +1,254 @@ +import numpy as np +import pytest +import yaml + +pytest.importorskip("larch.model.tree") + + +def test_nesting_arrays(): + nest_yaml = """ + NESTS: + name: root + coefficient: coef_nest_root + alternatives: + - name: AUTO + coefficient: coef_nest_AUTO + alternatives: + - name: DRIVEALONE + coefficient: coef_nest_AUTO_DRIVEALONE + alternatives: + - DRIVEALONEFREE + - DRIVEALONEPAY + - name: SHAREDRIDE2 + coefficient: coef_nest_AUTO_SHAREDRIDE2 + alternatives: + - SHARED2FREE + - SHARED2PAY + - name: SHAREDRIDE3 + coefficient: coef_nest_AUTO_SHAREDRIDE3 + alternatives: + - SHARED3FREE + - SHARED3PAY + - name: NONMOTORIZED + coefficient: coef_nest_NONMOTORIZED + alternatives: + - WALK + - BIKE + - name: TRANSIT + coefficient: coef_nest_TRANSIT + alternatives: + - name: WALKACCESS + coefficient: coef_nest_TRANSIT_WALKACCESS + alternatives: + - WALK_LOC + - WALK_LRF + - WALK_EXP + - WALK_HVY + - WALK_COM + - name: DRIVEACCESS + coefficient: coef_nest_TRANSIT_DRIVEACCESS + alternatives: + - DRIVE_LOC + - DRIVE_LRF + - DRIVE_EXP + - DRIVE_HVY + - DRIVE_COM + - name: RIDEHAIL + coefficient: coef_nest_RIDEHAIL + alternatives: + - TAXI + - TNC_SINGLE + - TNC_SHARED + """ + nests = yaml.safe_load(nest_yaml)["NESTS"] + alternatives = [ + "DRIVEALONEFREE", + "DRIVEALONEPAY", + "SHARED2FREE", + "SHARED2PAY", + "SHARED3FREE", + "SHARED3PAY", + "WALK", + "BIKE", + "WALK_LOC", + "WALK_LRF", + "WALK_EXP", + "WALK_HVY", + "WALK_COM", + "DRIVE_LOC", + "DRIVE_LRF", + "DRIVE_EXP", + "DRIVE_HVY", + "DRIVE_COM", + "TAXI", + "TNC_SINGLE", + "TNC_SHARED", + ] + from ..nested_logit import construct_nesting_tree + + tree = construct_nesting_tree(alternatives, nests) + arrs = tree.as_arrays( + trim=True, + parameter_dict={ + "coef_nest_AUTO_DRIVEALONE": 0.3, + "coef_nest_AUTO_SHAREDRIDE2": 0.4, + "coef_nest_AUTO_SHAREDRIDE3": 0.4, + "coef_nest_AUTO": 0.6, + "coef_nest_NONMOTORIZED": 0.72, + "coef_nest_TRANSIT": 0.72, + "coef_nest_TRANSIT_WALKACCESS": 0.5, + "coef_nest_TRANSIT_DRIVEACCESS": 0.5, + "coef_nest_RIDEHAIL": 0.36, + }, + ) + expected = { + "n_nodes": 31, + "n_alts": 21, + "edges_up": np.array( + [ + 21, + 21, + 22, + 22, + 23, + 23, + 24, + 24, + 24, + 25, + 25, + 26, + 26, + 26, + 26, + 26, + 27, + 27, + 27, + 27, + 27, + 28, + 28, + 29, + 29, + 29, + 30, + 30, + 30, + 30, + ], + dtype=np.int32, + ), + "edges_dn": np.array( + [ + 0, + 1, + 2, + 3, + 4, + 5, + 21, + 22, + 23, + 6, + 7, + 8, + 9, + 10, + 11, + 12, + 13, + 14, + 15, + 16, + 17, + 26, + 27, + 18, + 19, + 20, + 24, + 25, + 28, + 29, + ], + dtype=np.int32, + ), + "edges_1st": np.array( + [ + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + 1, + ], + dtype=np.int32, + ), + "edges_alloc": np.array( + [ + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + -1, + ], + dtype=np.int32, + ), + "mu_params": np.array( + [0.3, 0.4, 0.4, 0.6, 0.72, 0.5, 0.5, 0.72, 0.36, 1.0], dtype=np.float32 + ), + "start_slots": np.array([0, 2, 4, 6, 9, 11, 16, 21, 23, 26], dtype=np.int32), + "len_slots": np.array([2, 2, 2, 3, 2, 5, 5, 2, 3, 4], dtype=np.int32), + } + for k, v in expected.items(): + assert arrs[k] == pytest.approx(v), f"bad {k!r}" diff --git a/sharrow/tests/test_relationships.py b/sharrow/tests/test_relationships.py index 216fc7b..f2add2b 100644 --- a/sharrow/tests/test_relationships.py +++ b/sharrow/tests/test_relationships.py @@ -3,26 +3,33 @@ import numpy as np import pandas as pd +import xarray as xr from numpy.random import SeedSequence, default_rng -from pytest import approx, mark, raises +from pytest import approx, fixture, mark, raises import sharrow from sharrow import Dataset, DataTree, example_data from sharrow.dataset import from_named_objects -def test_shared_data(dataframe_regression): - - data = example_data.get_data() - skims = data["skims"] - households = data["hhs"] - +@fixture +def households(): + households = example_data.get_households() prng = default_rng(SeedSequence(42)) households["otaz_idx"] = households["TAZ"] - 1 households["dtaz_idx"] = prng.choice(np.arange(25), 5000) households["timeperiod5"] = prng.choice(np.arange(5), 5000) households["timeperiod3"] = np.clip(households["timeperiod5"], 1, 3) - 1 households["rownum"] = np.arange(len(households)) + return households + + +@fixture +def skims(): + return example_data.get_skims() + + +def test_shared_data(dataframe_regression, households, skims): tree = DataTree( base=households, @@ -67,18 +74,7 @@ def test_shared_data(dataframe_regression): dataframe_regression.check(result2, basename="test_shared_data_2") -def test_shared_data_reversible(dataframe_regression): - - data = example_data.get_data() - skims = data["skims"] - households = data["hhs"] - - prng = default_rng(SeedSequence(42)) - households["otaz_idx"] = households["TAZ"] - 1 - households["dtaz_idx"] = prng.choice(np.arange(25), 5000) - households["timeperiod5"] = prng.choice(np.arange(5), 5000) - households["timeperiod3"] = np.clip(households["timeperiod5"], 1, 3) - 1 - households["rownum"] = np.arange(len(households)) +def test_shared_data_reversible(dataframe_regression, households, skims): tree = DataTree( base=households, @@ -185,7 +181,6 @@ def test_with_2d_base(dataframe_regression): households["otaz"] = households["TAZ"] households["otaz_idx"] = households["TAZ"] - 1 households["dtaz"] = prng.choice(np.arange(1, 26), 5000) - # households['dtaz_idx'] = prng.choice(np.arange(25), 5000) households["timeperiod5"] = prng.choice(np.arange(5), 5000) households["timeperiod3"] = np.clip(households["timeperiod5"], 1, 3) - 1 households["rownum"] = np.arange(len(households)) @@ -245,17 +240,7 @@ def test_with_2d_base(dataframe_regression): np.testing.assert_array_almost_equal(check_vs, dot_result.to_numpy()) -def test_mixed_dtypes(dataframe_regression): - data = example_data.get_data() - skims = data["skims"] - households = data["hhs"] - - prng = default_rng(SeedSequence(42)) - households["otaz_idx"] = households["TAZ"] - 1 - households["dtaz_idx"] = prng.choice(np.arange(25), 5000) - households["timeperiod5"] = prng.choice(np.arange(5), 5000) - households["timeperiod3"] = np.clip(households["timeperiod5"], 1, 3) - 1 - households["rownum"] = np.arange(len(households)) +def test_mixed_dtypes(dataframe_regression, households, skims): tree = DataTree( base=households, @@ -288,17 +273,7 @@ def test_mixed_dtypes(dataframe_regression): dataframe_regression.check(result) -def test_tuple_slice(dataframe_regression): - data = example_data.get_data() - skims = data["skims"] - households = data["hhs"] - - prng = default_rng(SeedSequence(42)) - households["otaz_idx"] = households["TAZ"] - 1 - households["dtaz_idx"] = prng.choice(np.arange(25), 5000) - households["timeperiod5"] = prng.choice(np.arange(5), 5000) - households["timeperiod3"] = np.clip(households["timeperiod5"], 1, 3) - 1 - households["rownum"] = np.arange(len(households)) +def test_tuple_slice(dataframe_regression, households, skims): tree = DataTree( base=households, skims=skims, @@ -317,17 +292,7 @@ def test_tuple_slice(dataframe_regression): dataframe_regression.check(result) -def test_isin(dataframe_regression): - data = example_data.get_data() - skims = data["skims"] - households = data["hhs"] - - prng = default_rng(SeedSequence(42)) - households["otaz_idx"] = households["TAZ"] - 1 - households["dtaz_idx"] = prng.choice(np.arange(25), 5000) - households["timeperiod5"] = prng.choice(np.arange(5), 5000) - households["timeperiod3"] = np.clip(households["timeperiod5"], 1, 3) - 1 - households["rownum"] = np.arange(len(households)) +def test_isin(dataframe_regression, households, skims): tree = DataTree( base=households, skims=skims, @@ -360,9 +325,8 @@ def _get_target(q, token): @mark.skipif( sys.version_info < (3, 8), reason="shared memory requires python3.8 or higher" ) -def test_shared_memory(): +def test_shared_memory(skims): - skims = example_data.get_skims() token = "skims" + secrets.token_hex(5) skims_2 = skims.shm.to_shared_memory(token) @@ -399,17 +363,7 @@ def test_relationship_init(): assert r.indexing == "label" -def test_replacement_filters(dataframe_regression): - data = example_data.get_data() - skims = data["skims"] - households = data["hhs"] - - prng = default_rng(SeedSequence(42)) - households["otaz_idx"] = households["TAZ"] - 1 - households["dtaz_idx"] = prng.choice(np.arange(25), 5000) - households["timeperiod5"] = prng.choice(np.arange(5), 5000) - households["timeperiod3"] = np.clip(households["timeperiod5"], 1, 3) - 1 - households["rownum"] = np.arange(len(households)) +def test_replacement_filters(dataframe_regression, households, skims): tree = DataTree( base=households, @@ -447,17 +401,7 @@ def rename_jncome(x): dataframe_regression.check(result, basename="test_shared_data") -def test_name_in_wrong_subspace(dataframe_regression): - data = example_data.get_data() - skims = data["skims"] - households = data["hhs"] - - prng = default_rng(SeedSequence(42)) - households["otaz_idx"] = households["TAZ"] - 1 - households["dtaz_idx"] = prng.choice(np.arange(25), 5000) - households["timeperiod5"] = prng.choice(np.arange(5), 5000) - households["timeperiod3"] = np.clip(households["timeperiod5"], 1, 3) - 1 - households["rownum"] = np.arange(len(households)) +def test_name_in_wrong_subspace(dataframe_regression, households, skims): tree = DataTree( base=households, @@ -526,18 +470,8 @@ def test_name_in_wrong_subspace(dataframe_regression): dataframe_regression.check(result, basename="test_shared_data") -def test_shared_data_encoded(dataframe_regression): - - data = example_data.get_data() - skims = data["skims"] - households = data["hhs"] +def test_shared_data_encoded(dataframe_regression, households, skims): - prng = default_rng(SeedSequence(42)) - households["otaz_idx"] = households["TAZ"] - 1 - households["dtaz_idx"] = prng.choice(np.arange(25), 5000) - households["timeperiod5"] = prng.choice(np.arange(5), 5000) - households["timeperiod3"] = np.clip(households["timeperiod5"], 1, 3) - 1 - households["rownum"] = np.arange(len(households)) households = sharrow.dataset.construct(households).digital_encoding.set( "income", bitwidth=32, @@ -566,9 +500,7 @@ def test_shared_data_encoded(dataframe_regression): dataframe_regression.check(result, basename="test_shared_data") -def test_dict_encoded(dataframe_regression): - data = example_data.get_data() - skims = data["skims"] +def test_dict_encoded(dataframe_regression, skims): pairs = pd.DataFrame({"orig": [0, 0, 0, 1, 1, 1], "dest": [0, 1, 2, 0, 1, 2]}) skims1 = skims.digital_encoding.set("WLK_LOC_WLK_FAR", bitwidth=8, by_dict=True) tree1 = DataTree( @@ -589,9 +521,7 @@ def test_dict_encoded(dataframe_regression): dataframe_regression.check(arr1) -def test_joint_dict_encoded(dataframe_regression): - data = example_data.get_data() - skims = data["skims"] +def test_joint_dict_encoded(dataframe_regression, skims): pairs = pd.DataFrame({"orig": [0, 0, 0, 1, 1, 1], "dest": [0, 1, 2, 0, 1, 2]}) skims1 = skims.digital_encoding.set( "WLK_LOC_WLK_FAR", @@ -683,6 +613,36 @@ def test_isin_and_between(dataframe_regression): ) dataframe_regression.check(result) + # test masking + mask = (persons.index % 2) == 0 + + result = ss.load_dataframe(tree, mask=mask) + pd.testing.assert_series_equal( + result["pt"].isin([1, 5]).astype(np.float32).where(mask, np.nan), + result["pt_in_15"], + check_names=False, + ) + pd.testing.assert_series_equal( + result["pt"].isin([3, 4]).astype(np.float32).where(mask, np.nan), + result["pt_in_34"], + check_names=False, + ) + pd.testing.assert_series_equal( + result["pt"].between(1, 5).astype(np.float32).where(mask, np.nan), + result["pt_tween_15"], + check_names=False, + ) + pd.testing.assert_series_equal( + result["pt"].between(2, 5).astype(np.float32).where(mask, np.nan), + result["pt_tween_25"], + check_names=False, + ) + pd.testing.assert_series_equal( + result["pt"].between(3, 5).astype(np.float32).where(mask, np.nan), + result["pt_tween_35"], + check_names=False, + ) + def test_nested_where(dataframe_regression): @@ -804,3 +764,191 @@ def test_isna(): ) result = qf.load() assert result == approx(np.asarray([[0, 0, 1, 1]]).T) + + +def test_get(dataframe_regression, households, skims): + + tree = DataTree( + base=households, + skims=skims, + relationships=( + "base.otaz_idx->skims.otaz", + "base.dtaz_idx->skims.dtaz", + "base.timeperiod5->skims.time_period", + ), + ) + + ss = tree.setup_flow( + { + "income": "base.get('income', 0)", + "sov_time_by_income": "skims.SOV_TIME/base.get('income', 0)", + "missing_data": "base.get('missing_data', -1)", + "missing_skim": "skims.get('missing_core', -2)", + "sov_time_by_income_2": "skims.get('SOV_TIME')/base.income", + "sov_cost_by_income_2": "skims.get('HOV3_TIME', 999)", + }, + ) + result = ss._load(tree, as_dataframe=True) + dataframe_regression.check(result) + + s2 = tree.setup_flow( + { + "income": "base.get('income', default=0)", + "sov_time_by_income": "skims.SOV_TIME/base.get('income', default=0)", + "missing_data": "base.get('missing_data', default=-1)", + "missing_skim": "skims.get('missing_core', default=-2)", + "sov_time_by_income_2": "skims.get('SOV_TIME', default=0)/base.income", + "sov_cost_by_income_2": "skims.get('HOV3_TIME', default=999)", + }, + ) + result = s2._load(tree, as_dataframe=True) + + assert s2.flow_hash != ss.flow_hash + + dataframe_regression.check(result) + + +def test_get_native(): + data = example_data.get_data() + skims = data["skims"] + households = data["hhs"] + + prng = default_rng(SeedSequence(42)) + households["otaz"] = households["TAZ"] + households["otaz_idx"] = households["TAZ"] - 1 + households["dtaz"] = prng.choice(np.arange(1, 26), 5000) + households["timeperiod5"] = prng.choice(np.arange(5), 5000) + households["timeperiod3"] = np.clip(households["timeperiod5"], 1, 3) - 1 + households["rownum"] = np.arange(len(households)) + households["time5"] = prng.choice(["EA", "AM", "MD", "PM", "EV"], 5000) + households["time3"] = prng.choice(["AM", "MD", "PM"], 5000) + + blank = from_named_objects(households.index, skims["dtaz"]) + assert sorted(blank.coords) == ["HHID", "dtaz"] + assert blank.coords["HHID"].dims == ("HHID",) + assert blank.coords["dtaz"].dims == ("dtaz",) + + tree = DataTree( + root_node_name="base", + base=blank, + hh=households, + odt_skims=skims.rename({"otaz": "ptaz", "dtaz": "ataz"}), + dot_skims=skims.rename({"otaz": "ataz", "dtaz": "ptaz"}), + relationships=( + "base.HHID @ hh.HHID", + "base.dtaz @ odt_skims.ataz", + "base.dtaz @ dot_skims.ataz", + "hh.otaz @ odt_skims.ptaz", + "hh.time5 @ odt_skims.time_period", + "hh.otaz @ dot_skims.ptaz", + "hh.time5 @ dot_skims.time_period", + ), + force_digitization=True, + ) + + i = tree.get("missingname", 123) + assert i.dims == ("HHID", "dtaz") + assert i.shape == (5000, 25) + assert (i == 123).all() + + i = tree["income"] + assert isinstance(i, xr.DataArray) + assert i.dims == ("HHID", "dtaz") + assert i.shape == (5000, 25) + assert i.std("dtaz").max() == 0 + + i = tree.get(["income", "PERSONS"], broadcast=False) + assert isinstance(i, xr.Dataset) + assert "HHID" in i.coords + assert i.dims == {"HHID": 5000} + + i = tree.get("income", broadcast=False) + assert "HHID" in i.coords + assert i.dims == ("HHID",) + assert i.shape == (5000,) + + i = tree.get("income", broadcast=False, coords=False) + assert not i.coords + assert i.dims == ("HHID",) + assert i.shape == (5000,) + + i = tree.get("odt_skims.DIST") + assert i.dims == ("HHID", "dtaz") + assert i.shape == (5000, 25) + assert (tree.get_expr("odt_skims.DIST", allow_native=False) == i.load()).all() + + with raises(KeyError): + tree.get("xxxx.income") + with raises(KeyError): + tree.get("base.xxxx") + with raises(KeyError): + tree.get("xxxx") + with raises(KeyError): + tree.get("base.DIST") + + +def test_streaming(households, skims): + tree = DataTree( + base=households, + skims=skims, + relationships=( + "base.otaz_idx->skims.otaz", + "base.dtaz_idx->skims.dtaz", + "base.timeperiod5->skims.time_period", + ), + ) + ss = tree.setup_flow( + { + "income": "base.income", + "sov_time_by_income": "skims.SOV_TIME/base.income", + "sov_cost_by_income": "skims.HOV3_TIME", + } + ) + result = ss.load(tree) + streamer = ss.init_streamer(tree) + for i in range(len(households)): + assert result[i] == approx(streamer(i)) + + +def test_streaming_2d(households, skims): + blank = from_named_objects(households.index, skims["dtaz"]) + assert sorted(blank.coords) == ["HHID", "dtaz"] + assert blank.coords["HHID"].dims == ("HHID",) + assert blank.coords["dtaz"].dims == ("dtaz",) + + tree = DataTree( + root_node_name="base", + base=blank, + hh=households, + odt_skims=skims.rename({"otaz": "ptaz", "dtaz": "ataz"}), + dot_skims=skims.rename({"otaz": "ataz", "dtaz": "ptaz"}), + relationships=( + "base.HHID @ hh.HHID", + "base.dtaz @ odt_skims.ataz", + "base.dtaz @ dot_skims.ataz", + "hh.otaz_idx -> odt_skims.ptaz", + "hh.timeperiod5 -> odt_skims.time_period", + "hh.otaz_idx -> dot_skims.ptaz", + "hh.timeperiod5 -> dot_skims.time_period", + ), + force_digitization=True, + ) + + ss = tree.setup_flow( + { + "income": "hh.income", + "sov_time_by_income": "odt_skims.SOV_TIME/hh.income", + "round_trip_hov3_time": "dot_skims.HOV3_TIME + odt_skims.HOV3_TIME", + "double_hov3_time": "odt_skims.HOV3_TIME * 2", + "a_trip_hov3_time": "dot_skims.HOV3_TIME", + "b_trip_hov3_time": "odt_skims.HOV3_TIME", + } + ) + result = ss.load_dataarray(tree) + assert result.dims == ("HHID", "dtaz", "expressions") + assert result.shape == (5000, 25, 6) + result = result.to_numpy() + streamer = ss.init_streamer(tree) + assert streamer(0).shape == (25, 6) + for i in range(len(households)): + assert (result[i] == streamer(i)).all() diff --git a/sharrow/tests/test_relationships/test_get.csv b/sharrow/tests/test_relationships/test_get.csv new file mode 100644 index 0000000..d023433 --- /dev/null +++ b/sharrow/tests/test_relationships/test_get.csv @@ -0,0 +1,5001 @@ +,income,sov_time_by_income,missing_data,missing_skim,sov_time_by_income_2,sov_cost_by_income_2 +0,361000,5.1523547881515697e-06,-1,-2,5.1523547881515697e-06,1.8600000143051147 +1,59220,7.0753121690358967e-05,-1,-2,7.0753121690358967e-05,4.190000057220459 +2,197000,2.5634519261075184e-05,-1,-2,2.5634519261075184e-05,5.0500001907348633 +3,2200,0.0016409090021625161,-1,-2,0.0016409090021625161,3.6099998950958252 +4,16500,8.1818179751280695e-05,-1,-2,8.1818179751280695e-05,1.3500000238418579 +5,11200,0.00056785717606544495,-1,-2,0.00056785717606544495,6.3600001335144043 +6,9000,0.00029666666523553431,-1,-2,0.00029666666523553431,2.6700000762939453 +7,24000,0.00014333333820104599,-1,-2,0.00014333333820104599,3.440000057220459 +8,16800,0.00023511904873885214,-1,-2,0.00023511904873885214,3.9500000476837158 +9,650000,4.1538460209267214e-06,-1,-2,4.1538460209267214e-06,2.7000000476837158 +10,24000,0.00021083332831040025,-1,-2,0.00021083332831040025,5.059999942779541 +11,351000,1.7720796677167527e-05,-1,-2,1.7720796677167527e-05,6.2199997901916504 +12,27980,3.1451036193175241e-05,-1,-2,3.1451036193175241e-05,0.87999999523162842 +13,22100,0.00016742081788834184,-1,-2,0.00016742081788834184,3.7000000476837158 +14,9200,0.00039673913852311671,-1,-2,0.00039673913852311671,3.6500000953674316 +15,8504,0.00043508937233127654,-1,-2,0.00043508937233127654,3.7000000476837158 +16,109500,2.5022831323440187e-05,-1,-2,2.5022831323440187e-05,2.7400000095367432 +17,100820,1.2299146874283906e-05,-1,-2,1.2299146874283906e-05,1.2400000095367432 +18,3400,0.00092352944193407893,-1,-2,0.00092352944193407893,3.1400001049041748 +19,9600,0.00028854166157543659,-1,-2,0.00028854166157543659,2.7699999809265137 +20,30000,0.00010533333261264488,-1,-2,0.00010533333261264488,3.1600000858306885 +21,0,inf,-1,-2,inf,2.2699999809265137 +22,13900,0.00021438849216792732,-1,-2,0.00021438849216792732,2.9800000190734863 +23,0,inf,-1,-2,inf,4.4200000762939453 +24,9200,0.00014130433555692434,-1,-2,0.00014130433555692434,1.2999999523162842 +25,233640,7.4473550739639904e-06,-1,-2,7.4473550739639904e-06,1.7400000095367432 +26,4400,0.0007363636395893991,-1,-2,0.0007363636395893991,3.2400000095367432 +27,325000,1.310769312112825e-05,-1,-2,1.310769312112825e-05,4.2600002288818359 +28,11500,0.00031043478520587087,-1,-2,0.00031043478520587087,3.5699999332427979 +29,69700,2.4103299438138492e-05,-1,-2,2.4103299438138492e-05,1.6799999475479126 +30,37500,8.800000068731606e-05,-1,-2,8.800000068731606e-05,3.2999999523162842 +31,8100,0.00033456791425123811,-1,-2,0.00033456791425123811,2.7100000381469727 +32,209600,2.3234731997945346e-05,-1,-2,2.3234731997945346e-05,4.869999885559082 +33,27800,9.6762589237187058e-05,-1,-2,9.6762589237187058e-05,2.690000057220459 +34,21600,0.00017314814613200724,-1,-2,0.00017314814613200724,3.7400000095367432 +35,40500,0.00010691357601899654,-1,-2,0.00010691357601899654,4.3299999237060547 +36,90700,5.8875415561487898e-05,-1,-2,5.8875415561487898e-05,5.3400001525878906 +37,12400,0.00023306452203541994,-1,-2,0.00023306452203541994,2.8900001049041748 +38,37000,6.0540540289366618e-05,-1,-2,6.0540540289366618e-05,2.2400000095367432 +39,76000,7.3684209382918198e-06,-1,-2,7.3684209382918198e-06,0.56000000238418579 +40,0,inf,-1,-2,inf,1.8700000047683716 +41,39400,0.00012817259994335473,-1,-2,0.00012817259994335473,5.0500001907348633 +42,0,inf,-1,-2,inf,4.1500000953674316 +43,0,inf,-1,-2,inf,4.429999828338623 +44,79000,2.5443037884542719e-05,-1,-2,2.5443037884542719e-05,2.0099999904632568 +45,23510,0.00025138238561339676,-1,-2,0.00025138238561339676,5.9099998474121094 +46,13100,0.0003091603284701705,-1,-2,0.0003091603284701705,4.0500001907348633 +47,22500,0.00025244444259442389,-1,-2,0.00025244444259442389,5.679999828338623 +48,0,inf,-1,-2,inf,1.6200000047683716 +49,4310,0.00071229698369279504,-1,-2,0.00071229698369279504,3.0699999332427979 +50,0,inf,-1,-2,inf,4.179999828338623 +51,50000,1.9400000383029692e-05,-1,-2,1.9400000383029692e-05,0.97000002861022949 +52,20004,3.2493499020347372e-05,-1,-2,3.2493499020347372e-05,0.64999997615814209 +53,325000,8.184615580830723e-06,-1,-2,8.184615580830723e-06,2.6600000858306885 +54,90000,8.7777780208853073e-06,-1,-2,8.7777780208853073e-06,0.79000002145767212 +55,16500,8.4848485130351037e-05,-1,-2,8.4848485130351037e-05,1.3999999761581421 +56,8100,0.00034074074937961996,-1,-2,0.00034074074937961996,2.7599999904632568 +57,0,inf,-1,-2,inf,3.5799999237060547 +58,0,inf,-1,-2,inf,4.1700000762939453 +59,44680,0.0001230975758517161,-1,-2,0.0001230975758517161,5.5 +60,13500,0.00031629629665985703,-1,-2,0.00031629629665985703,4.2699999809265137 +61,57600,4.1493058233754709e-05,-1,-2,4.1493058233754709e-05,2.3900001049041748 +62,32000,3.3437499951105565e-05,-1,-2,3.3437499951105565e-05,1.0700000524520874 +63,75100,4.2077230318682268e-05,-1,-2,4.2077230318682268e-05,3.1600000858306885 +64,16000,0.00012562499614432454,-1,-2,0.00012562499614432454,2.0099999904632568 +65,19700,0.00012233502638991922,-1,-2,0.00012233502638991922,2.4100000858306885 +66,19780,0.00036804855335503817,-1,-2,0.00036804855335503817,7.2800002098083496 +67,14500,0.00015448275371454656,-1,-2,0.00015448275371454656,2.2400000095367432 +68,94900,3.3719705243129283e-05,-1,-2,3.3719705243129283e-05,3.2000000476837158 +69,24050,6.9022869865875691e-05,-1,-2,6.9022869865875691e-05,1.6599999666213989 +70,22200,0.00021936936536803842,-1,-2,0.00021936936536803842,4.869999885559082 +71,2800,0.0011928571620956063,-1,-2,0.0011928571620956063,3.3399999141693115 +72,7700,0.00052337662782520056,-1,-2,0.00052337662782520056,4.0300002098083496 +73,9000,0.00030777778010815382,-1,-2,0.00030777778010815382,2.7699999809265137 +74,18000,0.00020555555238388479,-1,-2,0.00020555555238388479,3.7000000476837158 +75,75000,3.7599998904624954e-05,-1,-2,3.7599998904624954e-05,2.8199999332427979 +76,13900,0.00024748200667090714,-1,-2,0.00024748200667090714,3.440000057220459 +77,122500,2.2122449081507511e-05,-1,-2,2.2122449081507511e-05,2.7100000381469727 +78,69900,4.949928552377969e-05,-1,-2,4.949928552377969e-05,3.4600000381469727 +79,30000,0.00015433333464898169,-1,-2,0.00015433333464898169,4.630000114440918 +80,27900,0.00010215053771389648,-1,-2,0.00010215053771389648,2.8499999046325684 +81,19700,0.00018172588897868991,-1,-2,0.00018172588897868991,3.5799999237060547 +82,11620,0.00035197936813347042,-1,-2,0.00035197936813347042,4.0900001525878906 +83,200000,3.35000004270114e-06,-1,-2,3.35000004270114e-06,0.67000001668930054 +84,15200,0.00012565789802465588,-1,-2,0.00012565789802465588,1.9099999666213989 +85,5660,0.00047173147322610021,-1,-2,0.00047173147322610021,2.6700000762939453 +86,57500,8.9739129180088639e-05,-1,-2,8.9739129180088639e-05,5.1599998474121094 +87,10200,0.00016274509835056961,-1,-2,0.00016274509835056961,1.6599999666213989 +88,0,inf,-1,-2,inf,2.6700000762939453 +89,8300,0.00037590358988381922,-1,-2,0.00037590358988381922,3.119999885559082 +90,28990,0.00012176612654002383,-1,-2,0.00012176612654002383,3.5299999713897705 +91,8400,8.0952384450938553e-05,-1,-2,8.0952384450938553e-05,0.68000000715255737 +92,7900,0.00050886074313893914,-1,-2,0.00050886074313893914,4.0199999809265137 +93,0,inf,-1,-2,inf,2.25 +94,14000,0.00036000000545755029,-1,-2,0.00036000000545755029,5.0399999618530273 +95,6690,0.00063976086676120758,-1,-2,0.00063976086676120758,4.2800002098083496 +96,99160,2.7430416594143026e-05,-1,-2,2.7430416594143026e-05,2.7200000286102295 +97,25300,0.00014545454178005457,-1,-2,0.00014545454178005457,3.6800000667572021 +98,0,inf,-1,-2,inf,0.51999998092651367 +99,9300,0.00048279567272402346,-1,-2,0.00048279567272402346,4.4899997711181641 +100,299200,1.517379678261932e-05,-1,-2,1.517379678261932e-05,4.5399999618530273 +101,66300,5.0377071602270007e-05,-1,-2,5.0377071602270007e-05,3.3399999141693115 +102,60000,4.3333333451300859e-05,-1,-2,4.3333333451300859e-05,2.5999999046325684 +103,49000,0.00010163265687879175,-1,-2,0.00010163265687879175,4.9800000190734863 +104,0,inf,-1,-2,inf,3.8499999046325684 +105,0,inf,-1,-2,inf,0.69999998807907104 +106,0,inf,-1,-2,inf,3.0999999046325684 +107,49000,1.6530611901544034e-05,-1,-2,1.6530611901544034e-05,0.81000000238418579 +108,3100,0.0013096773764118552,-1,-2,0.0013096773764118552,4.059999942779541 +109,174500,9.2836680778418668e-06,-1,-2,9.2836680778418668e-06,1.6200000047683716 +110,9000,0.00033222223282791674,-1,-2,0.00033222223282791674,2.9900000095367432 +111,70000,5.5285712733166292e-05,-1,-2,5.5285712733166292e-05,3.869999885559082 +112,0,inf,-1,-2,inf,4.7800002098083496 +113,8400,0.00033214286668226123,-1,-2,0.00033214286668226123,2.7899999618530273 +114,0,inf,-1,-2,inf,1.5199999809265137 +115,15500,0.0001793548435671255,-1,-2,0.0001793548435671255,2.7799999713897705 +116,140100,2.2269807232078165e-05,-1,-2,2.2269807232078165e-05,3.119999885559082 +117,9600,0.00041979170055128634,-1,-2,0.00041979170055128634,4.0300002098083496 +118,45000,1.7333331925328821e-05,-1,-2,1.7333331925328821e-05,0.77999997138977051 +119,40000,0.00010375000420026481,-1,-2,0.00010375000420026481,4.1500000953674316 +120,12000,0.00016749999485909939,-1,-2,0.00016749999485909939,2.0099999904632568 +121,127900,6.4112587097042706e-06,-1,-2,6.4112587097042706e-06,0.81999999284744263 +122,100000,3.859999924316071e-05,-1,-2,3.859999924316071e-05,3.8599998950958252 +123,0,inf,-1,-2,inf,3.869999885559082 +124,21320,0.00018386491865385324,-1,-2,0.00018386491865385324,3.9200000762939453 +125,33450,0.00013243647117633373,-1,-2,0.00013243647117633373,4.429999828338623 +126,11500,0.00030173914274200797,-1,-2,0.00030173914274200797,3.4700000286102295 +127,18000,0.00014888889563735574,-1,-2,0.00014888889563735574,2.6800000667572021 +128,0,inf,-1,-2,inf,4.0100002288818359 +129,163000,2.1656442186213098e-05,-1,-2,2.1656442186213098e-05,3.5299999713897705 +130,14500,0.00033517242991365492,-1,-2,0.00033517242991365492,4.8600001335144043 +131,8050,0.0005391304730437696,-1,-2,0.0005391304730437696,4.3400001525878906 +132,32000,9.5937495643738657e-05,-1,-2,9.5937495643738657e-05,3.0699999332427979 +133,69800,3.8538681110367179e-05,-1,-2,3.8538681110367179e-05,2.690000057220459 +134,32600,3.9877300878288224e-05,-1,-2,3.9877300878288224e-05,1.2999999523162842 +135,89950,3.0683713703183457e-05,-1,-2,3.0683713703183457e-05,2.7599999904632568 +136,20000,0.00010750000365078449,-1,-2,0.00010750000365078449,2.1500000953674316 +137,0,inf,-1,-2,inf,3.5799999237060547 +138,35000,7.885714148869738e-05,-1,-2,7.885714148869738e-05,2.7599999904632568 +139,12600,0.00019365080515854061,-1,-2,0.00019365080515854061,2.440000057220459 +140,0,inf,-1,-2,inf,3.7400000095367432 +141,12100,0.0003900826268363744,-1,-2,0.0003900826268363744,4.7199997901916504 +142,56000,7.6249998528510332e-05,-1,-2,7.6249998528510332e-05,4.2699999809265137 +143,35500,5.6338027206948027e-05,-1,-2,5.6338027206948027e-05,2 +144,116000,3.6034482036484405e-05,-1,-2,3.6034482036484405e-05,4.179999828338623 +145,0,inf,-1,-2,inf,5.9000000953674316 +146,14340,0.00014714086137246341,-1,-2,0.00014714086137246341,2.1099998950958252 +147,0,inf,-1,-2,inf,1.3300000429153442 +148,35410,8.1332960689906031e-05,-1,-2,8.1332960689906031e-05,2.880000114440918 +149,129500,1.6061774658737704e-05,-1,-2,1.6061774658737704e-05,2.0799999237060547 +150,80000,5.6749999203020707e-05,-1,-2,5.6749999203020707e-05,4.5399999618530273 +151,182500,9.0958901637350209e-06,-1,-2,9.0958901637350209e-06,1.6599999666213989 +152,10100,0.00068316829856485128,-1,-2,0.00068316829856485128,6.9000000953674316 +153,50000,3.3199998142663389e-05,-1,-2,3.3199998142663389e-05,1.6599999666213989 +154,18000,0.0001094444451155141,-1,-2,0.0001094444451155141,1.9700000286102295 +155,77300,6.0025871789548546e-05,-1,-2,6.0025871789548546e-05,4.6399998664855957 +156,39400,0.0001007614191621542,-1,-2,0.0001007614191621542,3.9700000286102295 +157,26500,0.0001256603718502447,-1,-2,0.0001256603718502447,3.3299999237060547 +158,15900,0.00014213836402632296,-1,-2,0.00014213836402632296,2.2599999904632568 +159,0,inf,-1,-2,inf,6.2699999809265137 +160,114000,5.1842103857779875e-05,-1,-2,5.1842103857779875e-05,5.9099998474121094 +161,37000,0.00012540540774352849,-1,-2,0.00012540540774352849,4.6399998664855957 +162,188500,1.0557028872426599e-05,-1,-2,1.0557028872426599e-05,1.9900000095367432 +163,8000,0.00024625001242384315,-1,-2,0.00024625001242384315,1.9700000286102295 +164,30480,6.5288717451039702e-05,-1,-2,6.5288717451039702e-05,1.9900000095367432 +165,10000,0.0003060000017285347,-1,-2,0.0003060000017285347,3.059999942779541 +166,25000,6.6399996285326779e-05,-1,-2,6.6399996285326779e-05,1.6599999666213989 +167,50400,7.1825394115876406e-05,-1,-2,7.1825394115876406e-05,3.619999885559082 +168,370,0.0063513512723147869,-1,-2,0.0063513512723147869,2.3499999046325684 +169,14500,0.00010689655027817935,-1,-2,0.00010689655027817935,1.5499999523162842 +170,49300,5.3549698350252584e-05,-1,-2,5.3549698350252584e-05,2.6400001049041748 +171,11030,0.00045874886563979089,-1,-2,0.00045874886563979089,5.059999942779541 +172,84800,4.3632076994981617e-05,-1,-2,4.3632076994981617e-05,3.7000000476837158 +173,68900,7.2859213105402887e-05,-1,-2,7.2859213105402887e-05,5.0199999809265137 +174,110100,2.4250681235571392e-05,-1,-2,2.4250681235571392e-05,2.6700000762939453 +175,48110,8.3142795119783841e-06,-1,-2,8.3142795119783841e-06,0.40000000596046448 +176,0,inf,-1,-2,inf,2.9600000381469727 +177,0,inf,-1,-2,inf,1.4500000476837158 +178,5700,0.0011754385195672512,-1,-2,0.0011754385195672512,6.6999998092651367 +179,9104,0.0005382249946705997,-1,-2,0.0005382249946705997,4.9000000953674316 +180,110000,3.8999998650979251e-05,-1,-2,3.8999998650979251e-05,4.2899999618530273 +181,9100,0.0002582417509984225,-1,-2,0.0002582417509984225,2.3499999046325684 +182,28320,0.0001193502830574289,-1,-2,0.0001193502830574289,3.380000114440918 +183,80370,4.2802043026313186e-05,-1,-2,4.2802043026313186e-05,3.440000057220459 +184,5300,0.00027547171339392662,-1,-2,0.00027547171339392662,1.4600000381469727 +185,29000,9.5517243607901037e-05,-1,-2,9.5517243607901037e-05,2.7699999809265137 +186,74980,3.0408107704715803e-05,-1,-2,3.0408107704715803e-05,2.2799999713897705 +187,7000,0.00031999999191612005,-1,-2,0.00031999999191612005,2.2400000095367432 +188,6200,0.00043709677993319929,-1,-2,0.00043709677993319929,2.7100000381469727 +189,245000,1.783673360478133e-05,-1,-2,1.783673360478133e-05,4.369999885559082 +190,12700,0.00029448818531818688,-1,-2,0.00029448818531818688,3.7400000095367432 +191,205400,1.5043816347315442e-05,-1,-2,1.5043816347315442e-05,3.0899999141693115 +192,66300,6.455505354097113e-05,-1,-2,6.455505354097113e-05,4.2800002098083496 +193,10200,0.00013627450971398503,-1,-2,0.00013627450971398503,1.3899999856948853 +194,0,inf,-1,-2,inf,4.3000001907348633 +195,0,inf,-1,-2,inf,4.070000171661377 +196,0,inf,-1,-2,inf,1.5299999713897705 +197,120000,2.166666672565043e-05,-1,-2,2.166666672565043e-05,2.5999999046325684 +198,174500,3.3352436730638146e-05,-1,-2,3.3352436730638146e-05,5.820000171661377 +199,18000,0.00028222223045304418,-1,-2,0.00028222223045304418,5.0799999237060547 +200,0,inf,-1,-2,inf,2.2699999809265137 +201,29000,0.00020517240045592189,-1,-2,0.00020517240045592189,5.9499998092651367 +202,40400,1.9554456230252981e-05,-1,-2,1.9554456230252981e-05,0.79000002145767212 +203,17400,0.00013850575487595052,-1,-2,0.00013850575487595052,2.4100000858306885 +204,0,inf,-1,-2,inf,1.7000000476837158 +205,8400,0.00035595239023678005,-1,-2,0.00035595239023678005,2.9900000095367432 +206,144100,3.4142958611482754e-05,-1,-2,3.4142958611482754e-05,4.9200000762939453 +207,8000,0.0005662500043399632,-1,-2,0.0005662500043399632,4.5300002098083496 +208,8420,0.00035510689485818148,-1,-2,0.00035510689485818148,2.9900000095367432 +209,163000,1.8834354705177248e-05,-1,-2,1.8834354705177248e-05,3.0699999332427979 +210,12400,0.00023951612820383161,-1,-2,0.00023951612820383161,2.9700000286102295 +211,66300,2.4434390070382506e-05,-1,-2,2.4434390070382506e-05,1.6200000047683716 +212,17400,0.00017816091713029891,-1,-2,0.00017816091713029891,3.0999999046325684 +213,0,inf,-1,-2,inf,3.309999942779541 +214,0,inf,-1,-2,inf,4.1599998474121094 +215,17210,0.00018651946447789669,-1,-2,0.00018651946447789669,3.2100000381469727 +216,34200,8.7719301518518478e-05,-1,-2,8.7719301518518478e-05,3 +217,24000,0.00020458332437556237,-1,-2,0.00020458332437556237,4.9099998474121094 +218,94100,2.2422953406930901e-05,-1,-2,2.2422953406930901e-05,2.1099998950958252 +219,115000,4.3217391066718847e-05,-1,-2,4.3217391066718847e-05,4.9699997901916504 +220,18100,0.00024806629517115653,-1,-2,0.00024806629517115653,4.4899997711181641 +221,4200,0.00096190476324409246,-1,-2,0.00096190476324409246,4.0399999618530273 +222,10000,0.00036800000816583633,-1,-2,0.00036800000816583633,3.6800000667572021 +223,32000,8.4687504568137228e-05,-1,-2,8.4687504568137228e-05,2.7100000381469727 +224,205000,1.165853700513253e-05,-1,-2,1.165853700513253e-05,2.3900001049041748 +225,200000,8.3499999163905159e-06,-1,-2,8.3499999163905159e-06,1.6699999570846558 +226,12290,0.00047355575952678919,-1,-2,0.00047355575952678919,5.820000171661377 +227,320,0.013843749649822712,-1,-2,0.013843749649822712,4.429999828338623 +228,0,inf,-1,-2,inf,5.429999828338623 +229,7600,0.00039210525574162602,-1,-2,0.00039210525574162602,2.9800000190734863 +230,14800,0.00012297298235353082,-1,-2,0.00012297298235353082,1.8200000524520874 +231,29000,0.00010793103865580633,-1,-2,0.00010793103865580633,3.130000114440918 +232,259900,8.041553883231245e-06,-1,-2,8.041553883231245e-06,2.0899999141693115 +233,25900,0.0001146718132076785,-1,-2,0.0001146718132076785,2.9700000286102295 +234,0,inf,-1,-2,inf,1.5199999809265137 +235,8800,0.00040227273711934686,-1,-2,0.00040227273711934686,3.5399999618530273 +236,8000,0.00062750000506639481,-1,-2,0.00062750000506639481,5.0199999809265137 +237,100010,4.2895710066659376e-05,-1,-2,4.2895710066659376e-05,4.2899999618530273 +238,161300,1.3019218386034481e-05,-1,-2,1.3019218386034481e-05,2.0999999046325684 +239,25800,0.00017403099627699703,-1,-2,0.00017403099627699703,4.4899997711181641 +240,0,inf,-1,-2,inf,3.8399999141693115 +241,14000,0.0001435714220860973,-1,-2,0.0001435714220860973,2.0099999904632568 +242,0,inf,-1,-2,inf,4.1500000953674316 +243,16200,0.00029814813751727343,-1,-2,0.00029814813751727343,4.8299999237060547 +244,12600,0.00025873017148114741,-1,-2,0.00025873017148114741,3.2599999904632568 +245,27000,0.00010000000474974513,-1,-2,0.00010000000474974513,2.7000000476837158 +246,15400,0.00033116881968453526,-1,-2,0.00033116881968453526,5.0999999046325684 +247,70900,4.9788435717346147e-05,-1,-2,4.9788435717346147e-05,3.5299999713897705 +248,12600,0.00049761903937906027,-1,-2,0.00049761903937906027,6.2699999809265137 +249,17300,0.00012023121234960854,-1,-2,0.00012023121234960854,2.0799999237060547 +250,25000,9.1199995949864388e-05,-1,-2,9.1199995949864388e-05,2.2799999713897705 +251,0,inf,-1,-2,inf,3.559999942779541 +252,14200,0.00020985915034543723,-1,-2,0.00020985915034543723,2.9800000190734863 +253,20000,8.5500003478955477e-05,-1,-2,8.5500003478955477e-05,1.7100000381469727 +254,51000,8.6666666902601719e-05,-1,-2,8.6666666902601719e-05,4.4200000762939453 +255,20300,0.00022118225751910359,-1,-2,0.00022118225751910359,4.4899997711181641 +256,61200,7.6143791375216097e-05,-1,-2,7.6143791375216097e-05,4.6599998474121094 +257,15000,0.00018000000272877514,-1,-2,0.00018000000272877514,2.7000000476837158 +258,45000,4.1555555071681738e-05,-1,-2,4.1555555071681738e-05,1.8700000047683716 +259,35720,0.00012206047540530562,-1,-2,0.00012206047540530562,4.3600001335144043 +260,50000,7.4000003223773092e-05,-1,-2,7.4000003223773092e-05,3.7000000476837158 +261,9500,0.00028315788949839771,-1,-2,0.00028315788949839771,2.690000057220459 +262,7700,0.00020779221085831523,-1,-2,0.00020779221085831523,1.6000000238418579 +263,9600,0.00035416666651144624,-1,-2,0.00035416666651144624,3.4000000953674316 +264,33200,1.2951807548233774e-05,-1,-2,1.2951807548233774e-05,0.43000000715255737 +265,388000,1.0154639312531799e-05,-1,-2,1.0154639312531799e-05,3.940000057220459 +266,38000,8.1052632594946772e-05,-1,-2,8.1052632594946772e-05,3.0799999237060547 +267,417400,1.3847628906660248e-05,-1,-2,1.3847628906660248e-05,5.7800002098083496 +268,84000,3.8928570575080812e-05,-1,-2,3.8928570575080812e-05,3.2699999809265137 +269,29000,0.00014413792814593762,-1,-2,0.00014413792814593762,4.179999828338623 +270,8000,0.00020500000391621143,-1,-2,0.00020500000391621143,1.6399999856948853 +271,81000,6.1481485317926854e-05,-1,-2,6.1481485317926854e-05,4.9800000190734863 +272,100000,2.3499998860643245e-05,-1,-2,2.3499998860643245e-05,2.3499999046325684 +273,10000,0.00039999998989515007,-1,-2,0.00039999998989515007,4 +274,25400,0.00010354330879636109,-1,-2,0.00010354330879636109,2.630000114440918 +275,13600,0.0001727941125864163,-1,-2,0.0001727941125864163,2.3499999046325684 +276,24000,0.00011416666529839858,-1,-2,0.00011416666529839858,2.7400000095367432 +277,50400,4.3253970943624154e-05,-1,-2,4.3253970943624154e-05,2.1800000667572021 +278,14500,0.00031310343183577061,-1,-2,0.00031310343183577061,4.5399999618530273 +279,100000,2.3299999156733975e-05,-1,-2,2.3299999156733975e-05,2.3299999237060547 +280,74300,5.4508749599335715e-05,-1,-2,5.4508749599335715e-05,4.0500001907348633 +281,36220,5.93594741076231e-05,-1,-2,5.93594741076231e-05,2.1500000953674316 +282,8300,0.00042048192699439824,-1,-2,0.00042048192699439824,3.4900000095367432 +283,36000,8.3611113950610161e-05,-1,-2,8.3611113950610161e-05,3.0099999904632568 +284,103000,1.3689320439880248e-05,-1,-2,1.3689320439880248e-05,1.4099999666213989 +285,8000,0.00050000002374872565,-1,-2,0.00050000002374872565,4 +286,42000,9.8809527116827667e-05,-1,-2,9.8809527116827667e-05,4.1500000953674316 +287,1890,0.0023068783339112997,-1,-2,0.0023068783339112997,4.3600001335144043 +288,36000,0.00011027777509298176,-1,-2,0.00011027777509298176,3.9700000286102295 +289,14400,0.00019166666606906801,-1,-2,0.00019166666606906801,2.7599999904632568 +290,20040,7.9840319813229144e-05,-1,-2,7.9840319813229144e-05,1.6000000238418579 +291,40700,2.6535628421697766e-05,-1,-2,2.6535628421697766e-05,1.0800000429153442 +292,18450,0.00015447153418790549,-1,-2,0.00015447153418790549,2.8499999046325684 +293,48500,0.00011917525989701971,-1,-2,0.00011917525989701971,5.7800002098083496 +294,128600,2.2239501049625687e-05,-1,-2,2.2239501049625687e-05,2.8599998950958252 +295,351000,7.8632474469486624e-06,-1,-2,7.8632474469486624e-06,2.7599999904632568 +296,39100,0.00011534527584444731,-1,-2,0.00011534527584444731,4.5100002288818359 +297,0,inf,-1,-2,inf,2.5999999046325684 +298,112000,3.8750000385334715e-05,-1,-2,3.8750000385334715e-05,4.3400001525878906 +299,4200,0.00074285711161792278,-1,-2,0.00074285711161792278,3.119999885559082 +300,17850,0.00018823529535438865,-1,-2,0.00018823529535438865,3.3599998950958252 +301,0,inf,-1,-2,inf,2.6400001049041748 +302,0,inf,-1,-2,inf,3.119999885559082 +303,15500,0.00046967744128778577,-1,-2,0.00046967744128778577,7.2800002098083496 +304,59500,5.6806726206559688e-05,-1,-2,5.6806726206559688e-05,3.380000114440918 +305,50000,4.3600000935839489e-05,-1,-2,4.3600000935839489e-05,2.1800000667572021 +306,0,inf,-1,-2,inf,4.369999885559082 +307,8300,0.00034939759643748403,-1,-2,0.00034939759643748403,2.9000000953674316 +308,0,inf,-1,-2,inf,1.8700000047683716 +309,77970,5.2840834541711956e-05,-1,-2,5.2840834541711956e-05,4.119999885559082 +310,70000,2.4857143216650002e-05,-1,-2,2.4857143216650002e-05,1.7400000095367432 +311,0,inf,-1,-2,inf,4.320000171661377 +312,31000,9.8387092293705791e-05,-1,-2,9.8387092293705791e-05,3.0499999523162842 +313,23100,0.00018917748820967972,-1,-2,0.00018917748820967972,4.369999885559082 +314,3000,0.00026000000070780516,-1,-2,0.00026000000070780516,0.77999997138977051 +315,216700,2.3304108253796585e-05,-1,-2,2.3304108253796585e-05,5.0500001907348633 +316,0,inf,-1,-2,inf,4.179999828338623 +317,0,inf,-1,-2,inf,2.380000114440918 +318,7000,0.00075714290142059326,-1,-2,0.00075714290142059326,5.3000001907348633 +319,8860,0.00014672685938421637,-1,-2,0.00014672685938421637,1.2999999523162842 +320,58000,2.8448275770642795e-05,-1,-2,2.8448275770642795e-05,1.6499999761581421 +321,0,inf,-1,-2,inf,4.0100002288818359 +322,10000,0.00041300000157207251,-1,-2,0.00041300000157207251,4.130000114440918 +323,9550,0.00079162302426993847,-1,-2,0.00079162302426993847,7.559999942779541 +324,4200,0.0012095237616449594,-1,-2,0.0012095237616449594,5.0799999237060547 +325,3400,0.00079705886309966445,-1,-2,0.00079705886309966445,2.7100000381469727 +326,35400,0.00010988700523739681,-1,-2,0.00010988700523739681,3.8900001049041748 +327,18000,0.00026166666066274047,-1,-2,0.00026166666066274047,4.7100000381469727 +328,70000,2.9571427148766816e-05,-1,-2,2.9571427148766816e-05,2.0699999332427979 +329,4600,0.00090869562700390816,-1,-2,0.00090869562700390816,4.179999828338623 +330,38500,7.6103897299617529e-05,-1,-2,7.6103897299617529e-05,2.9300000667572021 +331,18800,0.00011968085163971409,-1,-2,0.00011968085163971409,2.25 +332,8100,0.00053950614528730512,-1,-2,0.00053950614528730512,4.369999885559082 +333,10000,0.00026000000070780516,-1,-2,0.00026000000070780516,2.5999999046325684 +334,0,inf,-1,-2,inf,3.309999942779541 +335,25000,0.00010399999882793054,-1,-2,0.00010399999882793054,2.5999999046325684 +336,6200,0.00056935485918074846,-1,-2,0.00056935485918074846,3.5299999713897705 +337,16000,0.00022687501041218638,-1,-2,0.00022687501041218638,3.630000114440918 +338,325000,1.0153846687899204e-06,-1,-2,1.0153846687899204e-06,0.33000001311302185 +339,12000,0.0004708333290182054,-1,-2,0.0004708333290182054,5.6500000953674316 +340,9000,0.00050333334365859628,-1,-2,0.00050333334365859628,4.5300002098083496 +341,20000,0.00022850000823382288,-1,-2,0.00022850000823382288,4.570000171661377 +342,6690,0.00067713006865233183,-1,-2,0.00067713006865233183,4.5300002098083496 +343,150000,2.3733333364361897e-05,-1,-2,2.3733333364361897e-05,3.559999942779541 +344,1300,0.0058153844438493252,-1,-2,0.0058153844438493252,7.559999942779541 +345,22000,0.00017545453738421202,-1,-2,0.00017545453738421202,3.8599998950958252 +346,44600,0.00011502242705319077,-1,-2,0.00011502242705319077,5.130000114440918 +347,0,inf,-1,-2,inf,4.4200000762939453 +348,0,inf,-1,-2,inf,3.3299999237060547 +349,10180,0.00024165029753930867,-1,-2,0.00024165029753930867,2.4600000381469727 +350,0,inf,-1,-2,inf,3.9700000286102295 +351,104000,3.4519231121521443e-05,-1,-2,3.4519231121521443e-05,3.5899999141693115 +352,8200,0.00017195122200064361,-1,-2,0.00017195122200064361,1.4099999666213989 +353,39000,9.256409975932911e-05,-1,-2,9.256409975932911e-05,3.6099998950958252 +354,0,inf,-1,-2,inf,3.8599998950958252 +355,205400,1.5335930584114976e-05,-1,-2,1.5335930584114976e-05,3.1500000953674316 +356,24000,9.0833338617812842e-05,-1,-2,9.0833338617812842e-05,2.1800000667572021 +357,26030,0.00019170186715200543,-1,-2,0.00019170186715200543,4.9899997711181641 +358,6690,0.00062032887944951653,-1,-2,0.00062032887944951653,4.1500000953674316 +359,0,inf,-1,-2,inf,5.0199999809265137 +360,19400,0.00024123711045831442,-1,-2,0.00024123711045831442,4.679999828338623 +361,110100,6.0944596043555066e-05,-1,-2,6.0944596043555066e-05,6.7100000381469727 +362,158000,2.9810127671225928e-05,-1,-2,2.9810127671225928e-05,4.7100000381469727 +363,163000,3.4907974622910842e-05,-1,-2,3.4907974622910842e-05,5.690000057220459 +364,6900,0.00070579710882157087,-1,-2,0.00070579710882157087,4.869999885559082 +365,326700,9.6724825198180042e-06,-1,-2,9.6724825198180042e-06,3.1600000858306885 +366,0,inf,-1,-2,inf,3.8499999046325684 +367,33700,1.1572699804673903e-05,-1,-2,1.1572699804673903e-05,0.38999998569488525 +368,103000,3.3592234103707597e-05,-1,-2,3.3592234103707597e-05,3.4600000381469727 +369,20100,0.00024577113799750805,-1,-2,0.00024577113799750805,4.940000057220459 +370,12000,0.00048166667693294585,-1,-2,0.00048166667693294585,5.7800002098083496 +371,0,inf,-1,-2,inf,3.8599998950958252 +372,230,0.015565217472612858,-1,-2,0.015565217472612858,3.5799999237060547 +373,160800,1.3992536878504325e-05,-1,-2,1.3992536878504325e-05,2.25 +374,3500,0.0010742857120931149,-1,-2,0.0010742857120931149,3.7599999904632568 +375,12000,0.00025416666176170111,-1,-2,0.00025416666176170111,3.0499999523162842 +376,23800,8.4453778981696814e-05,-1,-2,8.4453778981696814e-05,2.0099999904632568 +377,8000,0.00080124998930841684,-1,-2,0.00080124998930841684,6.4099998474121094 +378,13100,0.00035343511262908578,-1,-2,0.00035343511262908578,4.630000114440918 +379,160000,2.7500000214786269e-05,-1,-2,2.7500000214786269e-05,4.4000000953674316 +380,310000,1.6741934814490378e-05,-1,-2,1.6741934814490378e-05,5.190000057220459 +381,0,inf,-1,-2,inf,3.3199999332427979 +382,8110,0.00012207152030896395,-1,-2,0.00012207152030896395,0.99000000953674316 +383,63000,4.3968255340587348e-05,-1,-2,4.3968255340587348e-05,2.7699999809265137 +384,9600,0.00035208335611969233,-1,-2,0.00035208335611969233,3.380000114440918 +385,435000,5.011494522477733e-06,-1,-2,5.011494522477733e-06,2.1800000667572021 +386,8300,0.00054698792519047856,-1,-2,0.00054698792519047856,4.5399999618530273 +387,28100,9.3238428235054016e-05,-1,-2,9.3238428235054016e-05,2.619999885559082 +388,16000,0.00037812499795109034,-1,-2,0.00037812499795109034,6.0500001907348633 +389,82500,3.345454388181679e-05,-1,-2,3.345454388181679e-05,2.7599999904632568 +390,11900,0.00041848738328553736,-1,-2,0.00041848738328553736,4.9800000190734863 +391,62000,6.596774619538337e-05,-1,-2,6.596774619538337e-05,4.0900001525878906 +392,10600,0.00041226414032280445,-1,-2,0.00041226414032280445,4.369999885559082 +393,17000,0.00016294117085635662,-1,-2,0.00016294117085635662,2.7699999809265137 +394,7600,0.00035131580079905689,-1,-2,0.00035131580079905689,2.6700000762939453 +395,83000,7.6506024925038218e-05,-1,-2,7.6506024925038218e-05,6.3499999046325684 +396,0,inf,-1,-2,inf,2.9200000762939453 +397,10000,0.00029799999902024865,-1,-2,0.00029799999902024865,2.9800000190734863 +398,8800,0.00030795455677434802,-1,-2,0.00030795455677434802,2.7100000381469727 +399,42500,0.00010235294030280784,-1,-2,0.00010235294030280784,4.3499999046325684 +400,0,inf,-1,-2,inf,1.7000000476837158 +401,6500,0.00019999999494757503,-1,-2,0.00019999999494757503,1.2999999523162842 +402,34100,0.00010498533811187372,-1,-2,0.00010498533811187372,3.5799999237060547 +403,457400,1.3751639926340431e-05,-1,-2,1.3751639926340431e-05,6.2899999618530273 +404,5100,0.00061960786115378141,-1,-2,0.00061960786115378141,3.1600000858306885 +405,19700,0.00022436548897530884,-1,-2,0.00022436548897530884,4.4200000762939453 +406,0,inf,-1,-2,inf,2.5999999046325684 +407,0,inf,-1,-2,inf,2.0699999332427979 +408,5500,0.00061818183166906238,-1,-2,0.00061818183166906238,3.4000000953674316 +409,35300,9.716713975649327e-05,-1,-2,9.716713975649327e-05,3.4300000667572021 +410,47000,7.7021271863486618e-05,-1,-2,7.7021271863486618e-05,3.619999885559082 +411,32000,0.00012125000648666173,-1,-2,0.00012125000648666173,3.880000114440918 +412,62530,7.0366222644224763e-05,-1,-2,7.0366222644224763e-05,4.4000000953674316 +413,29710,0.00012722988321911544,-1,-2,0.00012722988321911544,3.7799999713897705 +414,145020,1.1377740520401858e-05,-1,-2,1.1377740520401858e-05,1.6499999761581421 +415,28990,0.00015246636758092791,-1,-2,0.00015246636758092791,4.4200000762939453 +416,9500,0.00047789473319426179,-1,-2,0.00047789473319426179,4.5399999618530273 +417,11200,0.00017321428458672017,-1,-2,0.00017321428458672017,1.940000057220459 +418,15000,0.00030733333551324904,-1,-2,0.00030733333551324904,4.6100001335144043 +419,26500,0.0001116981147788465,-1,-2,0.0001116981147788465,2.9600000381469727 +420,0,inf,-1,-2,inf,3.3199999332427979 +421,14600,0.00010753425158327445,-1,-2,0.00010753425158327445,1.5700000524520874 +422,101500,4.8177338612731546e-05,-1,-2,4.8177338612731546e-05,4.8899998664855957 +423,4600,0.001056521781720221,-1,-2,0.001056521781720221,4.8600001335144043 +424,4300,0.00042093021329492331,-1,-2,0.00042093021329492331,1.809999942779541 +425,106000,3.1415092962561175e-05,-1,-2,3.1415092962561175e-05,3.3299999237060547 +426,141200,2.2946176613913849e-05,-1,-2,2.2946176613913849e-05,3.2400000095367432 +427,0,inf,-1,-2,inf,2.6400001049041748 +428,11600,0.00025258620735257864,-1,-2,0.00025258620735257864,2.9300000667572021 +429,38100,0.00013648293679580092,-1,-2,0.00013648293679580092,5.1999998092651367 +430,16800,0.00015476190310437232,-1,-2,0.00015476190310437232,2.5999999046325684 +431,67000,4.0447761421091855e-05,-1,-2,4.0447761421091855e-05,2.7100000381469727 +432,75000,3.9466667658416554e-05,-1,-2,3.9466667658416554e-05,2.9600000381469727 +433,200000,2.0150000636931509e-05,-1,-2,2.0150000636931509e-05,4.0300002098083496 +434,58050,6.1670973082073033e-05,-1,-2,6.1670973082073033e-05,3.5799999237060547 +435,34100,8.093841461231932e-05,-1,-2,8.093841461231932e-05,2.7599999904632568 +436,18000,0.00032666666083969176,-1,-2,0.00032666666083969176,5.880000114440918 +437,77970,5.2327817684272304e-05,-1,-2,5.2327817684272304e-05,4.0799999237060547 +438,42450,9.5877505373209715e-05,-1,-2,9.5877505373209715e-05,4.070000171661377 +439,13000,0.00043999997433274984,-1,-2,0.00043999997433274984,5.7199997901916504 +440,20000,0.00025650000316090882,-1,-2,0.00025650000316090882,5.130000114440918 +441,9000,0.00049444445176050067,-1,-2,0.00049444445176050067,4.4499998092651367 +442,15000,0.00018400000408291817,-1,-2,0.00018400000408291817,2.7599999904632568 +443,77970,3.8861100620124489e-05,-1,-2,3.8861100620124489e-05,3.0299999713897705 +444,20200,7.5247524364385754e-05,-1,-2,7.5247524364385754e-05,1.5199999809265137 +445,22000,0.00011181818263139576,-1,-2,0.00011181818263139576,2.4600000381469727 +446,46000,9.9347831564955413e-05,-1,-2,9.9347831564955413e-05,4.570000171661377 +447,0,inf,-1,-2,inf,3.4000000953674316 +448,101500,2.7290639991406351e-05,-1,-2,2.7290639991406351e-05,2.7699999809265137 +449,141200,3.0736544431420043e-05,-1,-2,3.0736544431420043e-05,4.3400001525878906 +450,21500,0.00014697674487251788,-1,-2,0.00014697674487251788,3.1600000858306885 +451,18450,0.00022113820887170732,-1,-2,0.00022113820887170732,4.0799999237060547 +452,12700,0.00032913385075516999,-1,-2,0.00032913385075516999,4.179999828338623 +453,9300,0.00033978495048359036,-1,-2,0.00033978495048359036,3.1600000858306885 +454,0,inf,-1,-2,inf,4.4800000190734863 +455,4000,0.00069000001531094313,-1,-2,0.00069000001531094313,2.7599999904632568 +456,97000,2.8453609047573991e-05,-1,-2,2.8453609047573991e-05,2.7599999904632568 +457,23000,0.00019652173796202987,-1,-2,0.00019652173796202987,4.5199999809265137 +458,54900,3.8433514419011772e-05,-1,-2,3.8433514419011772e-05,2.1099998950958252 +459,0,inf,-1,-2,inf,2.9700000286102295 +460,106000,3.018867937498726e-05,-1,-2,3.018867937498726e-05,3.2000000476837158 +461,12700,0.00034881889587268233,-1,-2,0.00034881889587268233,4.429999828338623 +462,50500,9.1089110355824232e-05,-1,-2,9.1089110355824232e-05,4.5999999046325684 +463,0,inf,-1,-2,inf,1.9900000095367432 +464,120250,7.0686073740944266e-06,-1,-2,7.0686073740944266e-06,0.85000002384185791 +465,0,inf,-1,-2,inf,3.7400000095367432 +466,18000,0.00016000001050997525,-1,-2,0.00016000001050997525,2.880000114440918 +467,64200,6.9781934143975377e-05,-1,-2,6.9781934143975377e-05,4.4800000190734863 +468,12720,0.00029795596492476761,-1,-2,0.00029795596492476761,3.7899999618530273 +469,25000,0.00011399999493733048,-1,-2,0.00011399999493733048,2.8499999046325684 +470,4600,0.00065217394148930907,-1,-2,0.00065217394148930907,3 +471,60000,4.8166668420890346e-05,-1,-2,4.8166668420890346e-05,2.8900001049041748 +472,23400,5.7692308473633602e-05,-1,-2,5.7692308473633602e-05,1.3500000238418579 +473,11200,0.00024107143690343946,-1,-2,0.00024107143690343946,2.7000000476837158 +474,32000,6.4374995417892933e-05,-1,-2,6.4374995417892933e-05,2.059999942779541 +475,432000,7.1759259299142286e-06,-1,-2,7.1759259299142286e-06,3.0999999046325684 +476,15000,0.00031133333686739206,-1,-2,0.00031133333686739206,4.6700000762939453 +477,15700,0.00021847133757546544,-1,-2,0.00021847133757546544,3.4300000667572021 +478,23900,0.00014602510782424361,-1,-2,0.00014602510782424361,3.4900000095367432 +479,19700,0.00020913705520797521,-1,-2,0.00020913705520797521,4.119999885559082 +480,105000,4.0666665881872177e-05,-1,-2,4.0666665881872177e-05,4.2699999809265137 +481,0,inf,-1,-2,inf,2.9000000953674316 +482,14000,3.2142856071004644e-05,-1,-2,3.2142856071004644e-05,0.44999998807907104 +483,32000,0.00012062499445164576,-1,-2,0.00012062499445164576,3.8599998950958252 +484,144400,1.9390581655898131e-05,-1,-2,1.9390581655898131e-05,2.7999999523162842 +485,16400,0.00019878048624377698,-1,-2,0.00019878048624377698,3.2599999904632568 +486,102160,5.1879401326004881e-06,-1,-2,5.1879401326004881e-06,0.52999997138977051 +487,0,inf,-1,-2,inf,2.7599999904632568 +488,42000,0.00011642857134575024,-1,-2,0.00011642857134575024,4.8899998664855957 +489,70000,7.9999999798019417e-06,-1,-2,7.9999999798019417e-06,0.56000000238418579 +490,41800,0.00010406698129372671,-1,-2,0.00010406698129372671,4.3499999046325684 +491,45700,8.8402623077854514e-05,-1,-2,8.8402623077854514e-05,4.0399999618530273 +492,99430,2.926682100223843e-05,-1,-2,2.926682100223843e-05,2.9100000858306885 +493,0,inf,-1,-2,inf,4.3400001525878906 +494,15000,0.00014600000577047467,-1,-2,0.00014600000577047467,2.190000057220459 +495,23000,0.00015304348198696971,-1,-2,0.00015304348198696971,3.5199999809265137 +496,52000,3.7500001781154424e-05,-1,-2,3.7500001781154424e-05,1.9500000476837158 +497,11000,0.00028545456007122993,-1,-2,0.00028545456007122993,3.1400001049041748 +498,9340,0.00043683082913048565,-1,-2,0.00043683082913048565,4.0799999237060547 +499,5050,0.00038613862125203013,-1,-2,0.00038613862125203013,1.9500000476837158 +500,55000,4.7272726078517735e-05,-1,-2,4.7272726078517735e-05,2.5999999046325684 +501,9500,0.00018315789930056781,-1,-2,0.00018315789930056781,1.7400000095367432 +502,9200,0.00072717393049970269,-1,-2,0.00072717393049970269,6.690000057220459 +503,149000,2.7114094336866401e-05,-1,-2,2.7114094336866401e-05,4.0399999618530273 +504,109600,3.6313867894932628e-05,-1,-2,3.6313867894932628e-05,3.9800000190734863 +505,0,inf,-1,-2,inf,2.7599999904632568 +506,0,inf,-1,-2,inf,3.75 +507,7200,0.00044583334238268435,-1,-2,0.00044583334238268435,3.2100000381469727 +508,75000,5.9999997574777808e-06,-1,-2,5.9999997574777808e-06,0.44999998807907104 +509,19200,0.00013385416241362691,-1,-2,0.00013385416241362691,2.5699999332427979 +510,83530,5.5309468734776601e-05,-1,-2,5.5309468734776601e-05,4.619999885559082 +511,7300,0.00072739727329462767,-1,-2,0.00072739727329462767,5.309999942779541 +512,39000,0.00014615383406635374,-1,-2,0.00014615383406635374,5.6999998092651367 +513,8100,0.00035432097502052784,-1,-2,0.00035432097502052784,2.869999885559082 +514,149000,2.9664430257980712e-05,-1,-2,2.9664430257980712e-05,4.4200000762939453 +515,115200,3.5156252124579623e-05,-1,-2,3.5156252124579623e-05,4.0500001907348633 +516,28300,0.00016183745174203068,-1,-2,0.00016183745174203068,4.5799999237060547 +517,118500,3.6033754440722987e-05,-1,-2,3.6033754440722987e-05,4.2699999809265137 +518,173960,9.7723614089773037e-06,-1,-2,9.7723614089773037e-06,1.7000000476837158 +519,14000,0.00041642857831902802,-1,-2,0.00041642857831902802,5.8299999237060547 +520,74000,7.297297543118475e-06,-1,-2,7.297297543118475e-06,0.54000002145767212 +521,0,inf,-1,-2,inf,2.1800000667572021 +522,245000,9.5918367151170969e-06,-1,-2,9.5918367151170969e-06,2.3499999046325684 +523,56500,5.4159292631084099e-05,-1,-2,5.4159292631084099e-05,3.059999942779541 +524,100000,4.6299999667098746e-05,-1,-2,4.6299999667098746e-05,4.630000114440918 +525,0,inf,-1,-2,inf,2.1400001049041748 +526,11500,0.00025130435824394226,-1,-2,0.00025130435824394226,2.8900001049041748 +527,41400,5.6763281463645399e-05,-1,-2,5.6763281463645399e-05,2.3499999046325684 +528,0,inf,-1,-2,inf,4.929999828338623 +529,30480,0.00013385826605372131,-1,-2,0.00013385826605372131,4.0799999237060547 +530,41400,0.00010845409997273237,-1,-2,0.00010845409997273237,4.4899997711181641 +531,432000,5.2083332775509916e-06,-1,-2,5.2083332775509916e-06,2.25 +532,68400,2.6169589546043426e-05,-1,-2,2.6169589546043426e-05,1.7899999618530273 +533,109000,1.4678898878628388e-05,-1,-2,1.4678898878628388e-05,1.6000000238418579 +534,43700,0.0001228832988999784,-1,-2,0.0001228832988999784,5.369999885559082 +535,66000,3.5606059100246057e-05,-1,-2,3.5606059100246057e-05,2.3499999046325684 +536,0,inf,-1,-2,inf,1.6599999666213989 +537,26600,0.00018082706083077937,-1,-2,0.00018082706083077937,4.809999942779541 +538,15000,0.00018400000408291817,-1,-2,0.00018400000408291817,2.7599999904632568 +539,193000,2.3471504391636699e-05,-1,-2,2.3471504391636699e-05,4.5300002098083496 +540,0,inf,-1,-2,inf,3.7100000381469727 +541,17000,0.00018705883121583611,-1,-2,0.00018705883121583611,3.1800000667572021 +542,86500,2.6589594199322164e-05,-1,-2,2.6589594199322164e-05,2.2999999523162842 +543,161300,8.9894610937335528e-06,-1,-2,8.9894610937335528e-06,1.4500000476837158 +544,144100,1.9986122424597852e-05,-1,-2,1.9986122424597852e-05,2.880000114440918 +545,14000,0.00032500000088475645,-1,-2,0.00032500000088475645,4.5500001907348633 +546,16000,0.00012312500621192157,-1,-2,0.00012312500621192157,1.9700000286102295 +547,56000,4.9464284529676661e-05,-1,-2,4.9464284529676661e-05,2.7699999809265137 +548,95900,7.7163713285699487e-06,-1,-2,7.7163713285699487e-06,0.74000000953674316 +549,4500,0.00083111110143363476,-1,-2,0.00083111110143363476,3.7400000095367432 +550,5600,0.00046428569476120174,-1,-2,0.00046428569476120174,2.5999999046325684 +551,27600,8.1521742686163634e-05,-1,-2,8.1521742686163634e-05,2.25 +552,8100,0.00040987654938362539,-1,-2,0.00040987654938362539,3.3199999332427979 +553,0,inf,-1,-2,inf,0.38999998569488525 +554,75200,4.9734044296201319e-05,-1,-2,4.9734044296201319e-05,3.7400000095367432 +555,22300,0.0001596412475919351,-1,-2,0.0001596412475919351,3.559999942779541 +556,77700,6.4092666434589773e-05,-1,-2,6.4092666434589773e-05,4.9800000190734863 +557,0,inf,-1,-2,inf,4.4000000953674316 +558,9500,0.00040105261723510921,-1,-2,0.00040105261723510921,3.809999942779541 +559,223900,2.5413131879759021e-05,-1,-2,2.5413131879759021e-05,5.690000057220459 +560,25940,0.00015921358135528862,-1,-2,0.00015921358135528862,4.130000114440918 +561,3500,0.0014342856593430042,-1,-2,0.0014342856593430042,5.0199999809265137 +562,41500,7.1325302997138351e-05,-1,-2,7.1325302997138351e-05,2.9600000381469727 +563,1380,0.0021956521086394787,-1,-2,0.0021956521086394787,3.0299999713897705 +564,63070,0.00010623117123031989,-1,-2,0.00010623117123031989,6.6999998092651367 +565,20500,1.6097561456263065e-05,-1,-2,1.6097561456263065e-05,0.33000001311302185 +566,158000,2.4493670935044065e-05,-1,-2,2.4493670935044065e-05,3.869999885559082 +567,22200,0.00015270270523615181,-1,-2,0.00015270270523615181,3.3900001049041748 +568,79150,1.0233733519271482e-05,-1,-2,1.0233733519271482e-05,0.81000000238418579 +569,23100,0.00024588743690401316,-1,-2,0.00024588743690401316,5.679999828338623 +570,0,inf,-1,-2,inf,4.309999942779541 +571,32500,7.4153846071567386e-05,-1,-2,7.4153846071567386e-05,2.4100000858306885 +572,18800,0.000232446807785891,-1,-2,0.000232446807785891,4.369999885559082 +573,22000,0.00014999999257270247,-1,-2,0.00014999999257270247,3.2999999523162842 +574,0,inf,-1,-2,inf,5.3400001525878906 +575,51000,1.2745097592414822e-05,-1,-2,1.2745097592414822e-05,0.64999997615814209 +576,77970,5.476465230458416e-05,-1,-2,5.476465230458416e-05,4.2699999809265137 +577,0,inf,-1,-2,inf,2.869999885559082 +578,64000,0.00012406249879859388,-1,-2,0.00012406249879859388,7.940000057220459 +579,14300,0.00034055943251587451,-1,-2,0.00034055943251587451,4.869999885559082 +580,560,0.0090357139706611633,-1,-2,0.0090357139706611633,5.059999942779541 +581,6430,0.00024883358855731785,-1,-2,0.00024883358855731785,1.6000000238418579 +582,9600,0.00051145831821486354,-1,-2,0.00051145831821486354,4.9099998474121094 +583,39700,4.7858942707534879e-05,-1,-2,4.7858942707534879e-05,1.8999999761581421 +584,49300,4.969574001734145e-05,-1,-2,4.969574001734145e-05,2.4500000476837158 +585,78000,4.3076921429019421e-05,-1,-2,4.3076921429019421e-05,3.3599998950958252 +586,34400,0.00012063953909091651,-1,-2,0.00012063953909091651,4.1500000953674316 +587,28800,9.0277775598224252e-05,-1,-2,9.0277775598224252e-05,2.5999999046325684 +588,104650,1.5289058865164407e-05,-1,-2,1.5289058865164407e-05,1.6000000238418579 +589,112000,4.1964285628637299e-06,-1,-2,4.1964285628637299e-06,0.4699999988079071 +590,9000,0.00035222223959863186,-1,-2,0.00035222223959863186,3.1700000762939453 +591,5600,0.0010053571313619614,-1,-2,0.0010053571313619614,5.630000114440918 +592,12000,0.00023000000510364771,-1,-2,0.00023000000510364771,2.7599999904632568 +593,60420,5.8424360759090632e-05,-1,-2,5.8424360759090632e-05,3.5299999713897705 +594,35500,0.00020140846027061343,-1,-2,0.00020140846027061343,7.1500000953674316 +595,450000,6.8666663537442219e-06,-1,-2,6.8666663537442219e-06,3.0899999141693115 +596,68070,8.6381667642854154e-05,-1,-2,8.6381667642854154e-05,5.880000114440918 +597,20100,0.0001925373071571812,-1,-2,0.0001925373071571812,3.869999885559082 +598,9220,5.6399130698991939e-05,-1,-2,5.6399130698991939e-05,0.51999998092651367 +599,33500,0.00010746268526418135,-1,-2,0.00010746268526418135,3.5999999046325684 +600,49300,9.1886417067144066e-05,-1,-2,9.1886417067144066e-05,4.5300002098083496 +601,79000,1.6455695003969595e-05,-1,-2,1.6455695003969595e-05,1.2999999523162842 +602,10200,0.00049509806558489799,-1,-2,0.00049509806558489799,5.0500001907348633 +603,100000,1.4400000509340316e-05,-1,-2,1.4400000509340316e-05,1.440000057220459 +604,45000,0.00010533332533668727,-1,-2,0.00010533332533668727,4.7399997711181641 +605,18100,5.7458561059320346e-05,-1,-2,5.7458561059320346e-05,1.0399999618530273 +606,327000,7.3394498940615449e-06,-1,-2,7.3394498940615449e-06,2.4000000953674316 +607,19400,7.6804120908491313e-05,-1,-2,7.6804120908491313e-05,1.4900000095367432 +608,88000,7.1363640017807484e-05,-1,-2,7.1363640017807484e-05,6.2800002098083496 +609,56500,7.5398231274448335e-05,-1,-2,7.5398231274448335e-05,4.2600002288818359 +610,86000,3.0581395549234003e-05,-1,-2,3.0581395549234003e-05,2.630000114440918 +611,0,inf,-1,-2,inf,4.130000114440918 +612,20000,6.5000000176951289e-05,-1,-2,6.5000000176951289e-05,1.2999999523162842 +613,17000,0.00031588235287927091,-1,-2,0.00031588235287927091,5.369999885559082 +614,48110,8.8962799054570496e-05,-1,-2,8.8962799054570496e-05,4.2800002098083496 +615,0,inf,-1,-2,inf,4.5199999809265137 +616,0,inf,-1,-2,inf,0.44999998807907104 +617,26050,0.00010441459016874433,-1,-2,0.00010441459016874433,2.7200000286102295 +618,8100,0.00024814813514240086,-1,-2,0.00024814813514240086,2.0099999904632568 +619,20250,0.00010222222044831142,-1,-2,0.00010222222044831142,2.0699999332427979 +620,44500,3.0112360036582686e-05,-1,-2,3.0112360036582686e-05,1.3400000333786011 +621,112000,3.5982146073365584e-05,-1,-2,3.5982146073365584e-05,4.0300002098083496 +622,27100,5.3505536925513297e-05,-1,-2,5.3505536925513297e-05,1.4500000476837158 +623,9500,0.00020736842998303473,-1,-2,0.00020736842998303473,1.9700000286102295 +624,8000,0.00040749998879618943,-1,-2,0.00040749998879618943,3.2599999904632568 +625,0,inf,-1,-2,inf,1.3300000429153442 +626,21000,2.571428740338888e-05,-1,-2,2.571428740338888e-05,0.54000002145767212 +627,150000,2.9066666684229858e-05,-1,-2,2.9066666684229858e-05,4.3600001335144043 +628,90000,2.4111111997626722e-05,-1,-2,2.4111111997626722e-05,2.1700000762939453 +629,130000,4.0846152842277661e-05,-1,-2,4.0846152842277661e-05,5.309999942779541 +630,148500,2.8148146157036535e-05,-1,-2,2.8148146157036535e-05,4.179999828338623 +631,100000,2.7699999918695539e-05,-1,-2,2.7699999918695539e-05,2.7699999809265137 +632,15000,0.00016333333041984588,-1,-2,0.00016333333041984588,2.4500000476837158 +633,6400,0.00045156251871958375,-1,-2,0.00045156251871958375,2.8900001049041748 +634,25640,0.00016497660544700921,-1,-2,0.00016497660544700921,4.2300000190734863 +635,43300,8.6836029367987067e-05,-1,-2,8.6836029367987067e-05,3.7599999904632568 +636,1700,0.0019470588304102421,-1,-2,0.0019470588304102421,3.309999942779541 +637,60000,2.7833331841975451e-05,-1,-2,2.7833331841975451e-05,1.6699999570846558 +638,20000,0.00010900000052060932,-1,-2,0.00010900000052060932,2.1800000667572021 +639,37000,0.00011594594252528623,-1,-2,0.00011594594252528623,4.2899999618530273 +640,7200,0.00068194442428648472,-1,-2,0.00068194442428648472,4.9099998474121094 +641,6500,0.0010615384671837091,-1,-2,0.0010615384671837091,6.9000000953674316 +642,0,inf,-1,-2,inf,4.380000114440918 +643,28000,5.2142859203740954e-05,-1,-2,5.2142859203740954e-05,1.4600000381469727 +644,53000,7.30188621673733e-05,-1,-2,7.30188621673733e-05,3.869999885559082 +645,34400,4.7965117119019851e-05,-1,-2,4.7965117119019851e-05,1.6499999761581421 +646,22100,0.00012036199768772349,-1,-2,0.00012036199768772349,2.6600000858306885 +647,10000,0.00047800003085285425,-1,-2,0.00047800003085285425,4.7800002098083496 +648,60000,7.1666668191028293e-06,-1,-2,7.1666668191028293e-06,0.43000000715255737 +649,0,inf,-1,-2,inf,4.679999828338623 +650,12000,0.00038583335117436945,-1,-2,0.00038583335117436945,4.630000114440918 +651,22900,7.6419215474743396e-05,-1,-2,7.6419215474743396e-05,1.75 +652,59800,5.5183950280479621e-06,-1,-2,5.5183950280479621e-06,0.33000001311302185 +653,107000,5.6822427723091096e-05,-1,-2,5.6822427723091096e-05,6.0799999237060547 +654,18900,0.00028253969503566623,-1,-2,0.00028253969503566623,5.3400001525878906 +655,70000,5.0714286771835759e-05,-1,-2,5.0714286771835759e-05,3.5499999523162842 +656,112000,1.9732142391148955e-05,-1,-2,1.9732142391148955e-05,2.2100000381469727 +657,45000,0.00010999999358318746,-1,-2,0.00010999999358318746,4.9499998092651367 +658,163000,1.2453987437766045e-05,-1,-2,1.2453987437766045e-05,2.0299999713897705 +659,37000,0.00012513513502199203,-1,-2,0.00012513513502199203,4.630000114440918 +660,158200,2.0796460376004688e-05,-1,-2,2.0796460376004688e-05,3.2899999618530273 +661,0,inf,-1,-2,inf,4.1700000762939453 +662,0,inf,-1,-2,inf,2.940000057220459 +663,5300,0.00073207548120990396,-1,-2,0.00073207548120990396,3.880000114440918 +664,9500,0.00047263156739063561,-1,-2,0.00047263156739063561,4.4899997711181641 +665,7700,0.00021168831153772771,-1,-2,0.00021168831153772771,1.6299999952316284 +666,205400,1.630963924981188e-05,-1,-2,1.630963924981188e-05,3.3499999046325684 +667,9000,0.00052000000141561031,-1,-2,0.00052000000141561031,4.679999828338623 +668,75700,7.5429328717291355e-05,-1,-2,7.5429328717291355e-05,5.7100000381469727 +669,67900,3.0191456971806474e-05,-1,-2,3.0191456971806474e-05,2.0499999523162842 +670,15700,0.00033694267040118575,-1,-2,0.00033694267040118575,5.2899999618530273 +671,48800,9.0983608970418572e-05,-1,-2,9.0983608970418572e-05,4.440000057220459 +672,49300,0.00010040567576652393,-1,-2,0.00010040567576652393,4.9499998092651367 +673,195000,2.0769231923623011e-05,-1,-2,2.0769231923623011e-05,4.0500001907348633 +674,38000,5.499999679159373e-05,-1,-2,5.499999679159373e-05,2.0899999141693115 +675,12000,0.00024833332281559706,-1,-2,0.00024833332281559706,2.9800000190734863 +676,0,inf,-1,-2,inf,4.179999828338623 +677,64200,4.205607547191903e-05,-1,-2,4.205607547191903e-05,2.7000000476837158 +678,15000,0.00035200000274926424,-1,-2,0.00035200000274926424,5.2800002098083496 +679,15200,0.00024078947899397463,-1,-2,0.00024078947899397463,3.6600000858306885 +680,0,inf,-1,-2,inf,2.9700000286102295 +681,0,inf,-1,-2,inf,3.6700000762939453 +682,10800,0.00050370371900498867,-1,-2,0.00050370371900498867,5.440000057220459 +683,57000,5.1052633352810517e-05,-1,-2,5.1052633352810517e-05,2.9100000858306885 +684,55700,5.0807899242499843e-05,-1,-2,5.0807899242499843e-05,2.8299999237060547 +685,129400,2.4034001398831606e-05,-1,-2,2.4034001398831606e-05,3.1099998950958252 +686,125400,1.9218501620343886e-05,-1,-2,1.9218501620343886e-05,2.4100000858306885 +687,0,inf,-1,-2,inf,2.7799999713897705 +688,123000,2.2276422896538861e-05,-1,-2,2.2276422896538861e-05,2.7400000095367432 +689,21000,0.00023523809795733541,-1,-2,0.00023523809795733541,4.940000057220459 +690,72000,8.2083330198656768e-05,-1,-2,8.2083330198656768e-05,5.9099998474121094 +691,30000,0.00014033332990948111,-1,-2,0.00014033332990948111,4.2100000381469727 +692,13000,0.00044307694770395756,-1,-2,0.00044307694770395756,5.7600002288818359 +693,50000,2.9999999242136255e-05,-1,-2,2.9999999242136255e-05,1.5 +694,10000,0.00030699998023919761,-1,-2,0.00030699998023919761,3.0699999332427979 +695,14500,0.00018758620717562735,-1,-2,0.00018758620717562735,2.7200000286102295 +696,16580,0.0002503015857655555,-1,-2,0.0002503015857655555,4.1500000953674316 +697,8300,0.00036024095606990159,-1,-2,0.00036024095606990159,2.9900000095367432 +698,360,0.0068611111491918564,-1,-2,0.0068611111491918564,2.4700000286102295 +699,20500,2.1463414668687619e-05,-1,-2,2.1463414668687619e-05,0.43999999761581421 +700,61000,8.3606559201143682e-05,-1,-2,8.3606559201143682e-05,5.0999999046325684 +701,30480,0.00013517060142476112,-1,-2,0.00013517060142476112,4.119999885559082 +702,0,inf,-1,-2,inf,1.8700000047683716 +703,66850,5.2505609346553683e-05,-1,-2,5.2505609346553683e-05,3.5099999904632568 +704,29600,7.331080996664241e-05,-1,-2,7.331080996664241e-05,2.1700000762939453 +705,423100,6.5469157561892644e-06,-1,-2,6.5469157561892644e-06,2.7699999809265137 +706,0,inf,-1,-2,inf,4.9800000190734863 +707,18800,7.8723402111791074e-05,-1,-2,7.8723402111791074e-05,1.4800000190734863 +708,14800,0.00012432433140929788,-1,-2,0.00012432433140929788,1.8400000333786011 +709,0,inf,-1,-2,inf,2.7699999809265137 +710,35500,0.00012450704525690526,-1,-2,0.00012450704525690526,4.4200000762939453 +711,14200,0.0002352112642256543,-1,-2,0.0002352112642256543,3.3399999141693115 +712,16600,0.00040903614717535675,-1,-2,0.00040903614717535675,6.7899999618530273 +713,14000,0.00035142857814207673,-1,-2,0.00035142857814207673,4.9200000762939453 +714,14400,0.00040000001899898052,-1,-2,0.00040000001899898052,5.7600002288818359 +715,34000,0.00012529412924777716,-1,-2,0.00012529412924777716,4.2600002288818359 +716,36020,8.3842307503800839e-05,-1,-2,8.3842307503800839e-05,3.0199999809265137 +717,350000,8.7714279288775288e-06,-1,-2,8.7714279288775288e-06,3.0699999332427979 +718,14100,0.00027659576153382659,-1,-2,0.00027659576153382659,3.9000000953674316 +719,8200,0.00042682926869019866,-1,-2,0.00042682926869019866,3.5 +720,0,inf,-1,-2,inf,2.1800000667572021 +721,101000,5.2574258006643504e-05,-1,-2,5.2574258006643504e-05,5.309999942779541 +722,14000,0.00028857143479399383,-1,-2,0.00028857143479399383,4.0399999618530273 +723,0,inf,-1,-2,inf,1.9700000286102295 +724,104000,2.0961539121344686e-05,-1,-2,2.0961539121344686e-05,2.1800000667572021 +725,44510,9.0990790340583771e-05,-1,-2,9.0990790340583771e-05,4.0500001907348633 +726,25700,0.000116731520392932,-1,-2,0.000116731520392932,3 +727,6000,0.00050500000361353159,-1,-2,0.00050500000361353159,3.0299999713897705 +728,140000,1.5499999790336005e-05,-1,-2,1.5499999790336005e-05,2.1700000762939453 +729,0,inf,-1,-2,inf,5.0199999809265137 +730,34900,0.000175071632838808,-1,-2,0.000175071632838808,6.1100001335144043 +731,39700,4.9622165533946827e-05,-1,-2,4.9622165533946827e-05,1.9700000286102295 +732,650000,4.2153847061854322e-06,-1,-2,4.2153847061854322e-06,2.7400000095367432 +733,2000,0.0019400001037865877,-1,-2,0.0019400001037865877,3.880000114440918 +734,5050,0.00078217824921011925,-1,-2,0.00078217824921011925,3.9500000476837158 +735,7300,0.00052739726379513741,-1,-2,0.00052739726379513741,3.8499999046325684 +736,20100,9.2039801529608667e-05,-1,-2,9.2039801529608667e-05,1.8500000238418579 +737,49800,4.7188754251692444e-05,-1,-2,4.7188754251692444e-05,2.3499999046325684 +738,31000,9.6129035227932036e-05,-1,-2,9.6129035227932036e-05,2.9800000190734863 +739,160000,3.2937499781837687e-05,-1,-2,3.2937499781837687e-05,5.2699999809265137 +740,11900,0.00026386554236523807,-1,-2,0.00026386554236523807,3.1400001049041748 +741,0,inf,-1,-2,inf,1.8999999761581421 +742,14800,0.00023581081768497825,-1,-2,0.00023581081768497825,3.4900000095367432 +743,34400,1.3081395081826486e-05,-1,-2,1.3081395081826486e-05,0.44999998807907104 +744,8300,0.00044578313827514648,-1,-2,0.00044578313827514648,3.7000000476837158 +745,133480,3.2664069294696674e-05,-1,-2,3.2664069294696674e-05,4.3600001335144043 +746,20000,0.00026549998437985778,-1,-2,0.00026549998437985778,5.309999942779541 +747,0,inf,-1,-2,inf,0.38999998569488525 +748,5050,0.00032475247280672193,-1,-2,0.00032475247280672193,1.6399999856948853 +749,0,inf,-1,-2,inf,3.5799999237060547 +750,177000,3.5197739634895697e-05,-1,-2,3.5197739634895697e-05,6.2300000190734863 +751,117000,1.1880341844516806e-05,-1,-2,1.1880341844516806e-05,1.3899999856948853 +752,141200,2.8399435905157588e-05,-1,-2,2.8399435905157588e-05,4.0100002288818359 +753,72600,5.5922864703461528e-05,-1,-2,5.5922864703461528e-05,4.059999942779541 +754,10000,0.00054300000192597508,-1,-2,0.00054300000192597508,5.429999828338623 +755,18000,0.00024333334295079112,-1,-2,0.00024333334295079112,4.380000114440918 +756,8500,0.0005905882571823895,-1,-2,0.0005905882571823895,5.0199999809265137 +757,36220,0.00016731087816879153,-1,-2,0.00016731087816879153,6.059999942779541 +758,19000,0.00011368421837687492,-1,-2,0.00011368421837687492,2.1600000858306885 +759,64000,3.7187503039604053e-05,-1,-2,3.7187503039604053e-05,2.380000114440918 +760,37000,3.9189191738842055e-05,-1,-2,3.9189191738842055e-05,1.4500000476837158 +761,29000,9.5172414148692042e-05,-1,-2,9.5172414148692042e-05,2.7599999904632568 +762,8200,7.439024921040982e-05,-1,-2,7.439024921040982e-05,0.61000001430511475 +763,20040,0.00018263472884427756,-1,-2,0.00018263472884427756,3.6600000858306885 +764,8400,0.00012619046901818365,-1,-2,0.00012619046901818365,1.059999942779541 +765,7600,0.00065131578594446182,-1,-2,0.00065131578594446182,4.9499998092651367 +766,134100,2.8187918360345066e-05,-1,-2,2.8187918360345066e-05,3.7799999713897705 +767,73390,3.7334786611609161e-05,-1,-2,3.7334786611609161e-05,2.7400000095367432 +768,30000,9.0000001364387572e-05,-1,-2,9.0000001364387572e-05,2.7000000476837158 +769,25000,4.3200001528020948e-05,-1,-2,4.3200001528020948e-05,1.0800000429153442 +770,9300,0.00047526881098747253,-1,-2,0.00047526881098747253,4.4200000762939453 +771,1560,0.0016987180570140481,-1,-2,0.0016987180570140481,2.6500000953674316 +772,70900,4.6967557864263654e-05,-1,-2,4.6967557864263654e-05,3.3299999237060547 +773,307100,1.9472485291771591e-05,-1,-2,1.9472485291771591e-05,5.9800000190734863 +774,9500,0.00065789476502686739,-1,-2,0.00065789476502686739,6.25 +775,0,inf,-1,-2,inf,4.0799999237060547 +776,690,0.0062028989195823669,-1,-2,0.0062028989195823669,4.2800002098083496 +777,53000,8.1886792031582445e-05,-1,-2,8.1886792031582445e-05,4.3400001525878906 +778,18900,0.00014338624896481633,-1,-2,0.00014338624896481633,2.7100000381469727 +779,12000,0.00055833329679444432,-1,-2,0.00055833329679444432,6.6999998092651367 +780,32500,1.4461538739851676e-05,-1,-2,1.4461538739851676e-05,0.4699999988079071 +781,8100,0.0005543209845200181,-1,-2,0.0005543209845200181,4.4899997711181641 +782,0,inf,-1,-2,inf,3.7799999713897705 +783,0,inf,-1,-2,inf,4.7800002098083496 +784,14300,0.00028531468706205487,-1,-2,0.00028531468706205487,4.0799999237060547 +785,83000,4.83132571389433e-05,-1,-2,4.83132571389433e-05,4.0100002288818359 +786,13400,0.00011791045108111575,-1,-2,0.00011791045108111575,1.5800000429153442 +787,5200,0.00083653844194486737,-1,-2,0.00083653844194486737,4.3499999046325684 +788,63440,1.6708700059098192e-05,-1,-2,1.6708700059098192e-05,1.059999942779541 +789,41550,8.1347774539608508e-05,-1,-2,8.1347774539608508e-05,3.380000114440918 +790,6000,0.000295000005280599,-1,-2,0.000295000005280599,1.7699999809265137 +791,114000,2.6666666599339806e-05,-1,-2,2.6666666599339806e-05,3.0399999618530273 +792,0,inf,-1,-2,inf,4.1700000762939453 +793,18100,0.00016077348846010864,-1,-2,0.00016077348846010864,2.9100000858306885 +794,18000,0.00013611112080980092,-1,-2,0.00013611112080980092,2.4500000476837158 +795,99500,2.1608040697174147e-05,-1,-2,2.1608040697174147e-05,2.1500000953674316 +796,0,inf,-1,-2,inf,4.130000114440918 +797,8400,0.00039404761628247797,-1,-2,0.00039404761628247797,3.309999942779541 +798,44000,3.6363635445013642e-05,-1,-2,3.6363635445013642e-05,1.6000000238418579 +799,57300,4.8516580136492848e-05,-1,-2,4.8516580136492848e-05,2.7799999713897705 +800,35500,8.2535210822243243e-05,-1,-2,8.2535210822243243e-05,2.9300000667572021 +801,19700,0.00012233502638991922,-1,-2,0.00012233502638991922,2.4100000858306885 +802,26000,5.7307694078190252e-05,-1,-2,5.7307694078190252e-05,1.4900000095367432 +803,0,inf,-1,-2,inf,5.690000057220459 +804,7200,0.00033194446587003767,-1,-2,0.00033194446587003767,2.3900001049041748 +805,36400,5.9890113334404305e-05,-1,-2,5.9890113334404305e-05,2.1800000667572021 +806,40000,0.00013524999667424709,-1,-2,0.00013524999667424709,5.4099998474121094 +807,27000,0.00015370370238088071,-1,-2,0.00015370370238088071,4.1500000953674316 +808,9000,7.2222217568196356e-05,-1,-2,7.2222217568196356e-05,0.64999997615814209 +809,87200,3.0389908715733327e-05,-1,-2,3.0389908715733327e-05,2.6500000953674316 +810,38200,3.6649213143391535e-05,-1,-2,3.6649213143391535e-05,1.3999999761581421 +811,99700,3.1293879146687686e-05,-1,-2,3.1293879146687686e-05,3.119999885559082 +812,48500,7.5257732532918453e-05,-1,-2,7.5257732532918453e-05,3.6500000953674316 +813,0,inf,-1,-2,inf,2.7599999904632568 +814,105150,4.7075605834834278e-05,-1,-2,4.7075605834834278e-05,4.9499998092651367 +815,70100,6.1055638070683926e-05,-1,-2,6.1055638070683926e-05,4.2800002098083496 +816,41600,7.6201926276553422e-05,-1,-2,7.6201926276553422e-05,3.1700000762939453 +817,8100,0.00032222221489064395,-1,-2,0.00032222221489064395,2.6099998950958252 +818,0,inf,-1,-2,inf,4.8499999046325684 +819,8300,0.0007168674492277205,-1,-2,0.0007168674492277205,5.9499998092651367 +820,19400,0.00027525774203240871,-1,-2,0.00027525774203240871,5.3400001525878906 +821,28000,0.00015892856754362583,-1,-2,0.00015892856754362583,4.4499998092651367 +822,20200,0.00013663366553373635,-1,-2,0.00013663366553373635,2.7599999904632568 +823,61000,4.7540983359795064e-05,-1,-2,4.7540983359795064e-05,2.9000000953674316 +824,115400,4.3674175685737282e-05,-1,-2,4.3674175685737282e-05,5.0399999618530273 +825,13000,0.00023615383543074131,-1,-2,0.00023615383543074131,3.0699999332427979 +826,8680,0.00039631337858736515,-1,-2,0.00039631337858736515,3.440000057220459 +827,21500,0.00032279070001095533,-1,-2,0.00032279070001095533,6.940000057220459 +828,8300,0.00048433736083097756,-1,-2,0.00048433736083097756,4.0199999809265137 +829,0,inf,-1,-2,inf,3.75 +830,0,inf,-1,-2,inf,2.7699999809265137 +831,21800,3.5779816244030371e-05,-1,-2,3.5779816244030371e-05,0.77999997138977051 +832,650000,4.1538460209267214e-06,-1,-2,4.1538460209267214e-06,2.7000000476837158 +833,27900,0.00016093188605736941,-1,-2,0.00016093188605736941,4.4899997711181641 +834,15000,0.00020866667910013348,-1,-2,0.00020866667910013348,3.130000114440918 +835,45000,1.5555555364699103e-05,-1,-2,1.5555555364699103e-05,0.69999998807907104 +836,0,inf,-1,-2,inf,1.6000000238418579 +837,15000,0.00029666666523553431,-1,-2,0.00029666666523553431,4.4499998092651367 +838,12300,0.0002398374053882435,-1,-2,0.0002398374053882435,2.9500000476837158 +839,15000,0.00047066665138117969,-1,-2,0.00047066665138117969,7.059999942779541 +840,0,inf,-1,-2,inf,3.619999885559082 +841,36500,0.00013643834972754121,-1,-2,0.00013643834972754121,4.9800000190734863 +842,12000,0.00066166667966172099,-1,-2,0.00066166667966172099,7.940000057220459 +843,31500,9.8095231805928051e-05,-1,-2,9.8095231805928051e-05,3.0899999141693115 +844,13500,0.00014222221216186881,-1,-2,0.00014222221216186881,1.9199999570846558 +845,14400,0.00024374999338760972,-1,-2,0.00024374999338760972,3.5099999904632568 +846,41200,5.6796114222379401e-05,-1,-2,5.6796114222379401e-05,2.3399999141693115 +847,0,inf,-1,-2,inf,2.4700000286102295 +848,8300,8.0722893471829593e-05,-1,-2,8.0722893471829593e-05,0.67000001668930054 +849,7800,0.00063461536774411798,-1,-2,0.00063461536774411798,4.9499998092651367 +850,0,inf,-1,-2,inf,6.690000057220459 +851,41500,6.4819279941730201e-05,-1,-2,6.4819279941730201e-05,2.690000057220459 +852,3600,0.0010388889349997044,-1,-2,0.0010388889349997044,3.7400000095367432 +853,70000,3.8857142499182373e-05,-1,-2,3.8857142499182373e-05,2.7200000286102295 +854,112000,3.0714287277078256e-05,-1,-2,3.0714287277078256e-05,3.440000057220459 +855,30000,0.00020833333837799728,-1,-2,0.00020833333837799728,6.25 +856,74100,3.657220077002421e-05,-1,-2,3.657220077002421e-05,2.7100000381469727 +857,16500,0.00031515149748884141,-1,-2,0.00031515149748884141,5.1999998092651367 +858,152000,3.1776315154274926e-05,-1,-2,3.1776315154274926e-05,4.8299999237060547 +859,35300,3.8243626477196813e-05,-1,-2,3.8243626477196813e-05,1.3500000238418579 +860,26000,0.00026038460782729089,-1,-2,0.00026038460782729089,6.7699999809265137 +861,25300,0.00011501976405270398,-1,-2,0.00011501976405270398,2.9100000858306885 +862,35030,0.00011504425492603332,-1,-2,0.00011504425492603332,4.0300002098083496 +863,137000,2.7080292056780308e-05,-1,-2,2.7080292056780308e-05,3.7100000381469727 +864,80000,7.3625000368338078e-05,-1,-2,7.3625000368338078e-05,5.8899998664855957 +865,0,inf,-1,-2,inf,3.7400000095367432 +866,19000,7.1052629209589213e-05,-1,-2,7.1052629209589213e-05,1.3500000238418579 +867,34400,0.00012470930232666433,-1,-2,0.00012470930232666433,4.2899999618530273 +868,0,inf,-1,-2,inf,4.0799999237060547 +869,14600,0.00023424657410942018,-1,-2,0.00023424657410942018,3.4200000762939453 +870,224000,1.2232142580614891e-05,-1,-2,1.2232142580614891e-05,2.7400000095367432 +871,8900,0.00033483144943602383,-1,-2,0.00033483144943602383,2.9800000190734863 +872,17700,0.00016892654821276665,-1,-2,0.00016892654821276665,2.9900000095367432 +873,77970,2.783121817628853e-05,-1,-2,2.783121817628853e-05,2.1700000762939453 +874,22000,0.00019772726227529347,-1,-2,0.00019772726227529347,4.3499999046325684 +875,0,inf,-1,-2,inf,2.8499999046325684 +876,0,inf,-1,-2,inf,3.7599999904632568 +877,133000,3.9022557757562026e-05,-1,-2,3.9022557757562026e-05,5.190000057220459 +878,14400,0.00019166666606906801,-1,-2,0.00019166666606906801,2.7599999904632568 +879,295100,9.0816674855886959e-06,-1,-2,9.0816674855886959e-06,2.6800000667572021 +880,700,0.0043285712599754333,-1,-2,0.0043285712599754333,3.0299999713897705 +881,14500,0.00031379310530610383,-1,-2,0.00031379310530610383,4.5500001907348633 +882,11000,0.00036727273254655302,-1,-2,0.00036727273254655302,4.0399999618530273 +883,23900,0.0001096234263968654,-1,-2,0.0001096234263968654,2.619999885559082 +884,23400,0.00013076922914478928,-1,-2,0.00013076922914478928,3.059999942779541 +885,10000,0.00050600001122802496,-1,-2,0.00050600001122802496,5.059999942779541 +886,55000,5.3090909204911441e-05,-1,-2,5.3090909204911441e-05,2.9200000762939453 +887,108000,1.2962962500751019e-05,-1,-2,1.2962962500751019e-05,1.3999999761581421 +888,19200,0.00017864583060145378,-1,-2,0.00017864583060145378,3.4300000667572021 +889,25000,0.00013559999933931977,-1,-2,0.00013559999933931977,3.3900001049041748 +890,13000,0.00037769228219985962,-1,-2,0.00037769228219985962,4.9099998474121094 +891,35030,0.00010676562669686973,-1,-2,0.00010676562669686973,3.7400000095367432 +892,38000,7.5526309956330806e-05,-1,-2,7.5526309956330806e-05,2.869999885559082 +893,61900,9.5476571004837751e-05,-1,-2,9.5476571004837751e-05,5.9099998474121094 +894,20000,0.0001500000071246177,-1,-2,0.0001500000071246177,3 +895,128200,2.8237129299668595e-05,-1,-2,2.8237129299668595e-05,3.619999885559082 +896,26300,5.4752854339312762e-05,-1,-2,5.4752854339312762e-05,1.440000057220459 +897,16500,0.0001218181787407957,-1,-2,0.0001218181787407957,2.0099999904632568 +898,10000,0.00037500000325962901,-1,-2,0.00037500000325962901,3.75 +899,24900,8.35341343190521e-05,-1,-2,8.35341343190521e-05,2.0799999237060547 +900,74600,4.7184985305648297e-05,-1,-2,4.7184985305648297e-05,3.5199999809265137 +901,10000,0.00033399998210370541,-1,-2,0.00033399998210370541,3.3399999141693115 +902,0,inf,-1,-2,inf,4.320000171661377 +903,13600,0.00055882352171465755,-1,-2,0.00055882352171465755,7.5999999046325684 +904,8300,0.0003192771109752357,-1,-2,0.0003192771109752357,2.6500000953674316 +905,172000,2.1511628801818006e-05,-1,-2,2.1511628801818006e-05,3.7000000476837158 +906,0,inf,-1,-2,inf,4.2300000190734863 +907,0,inf,-1,-2,inf,1.8700000047683716 +908,150000,2.5133333110716194e-05,-1,-2,2.5133333110716194e-05,3.7699999809265137 +909,44500,0.00011730336700566113,-1,-2,0.00011730336700566113,5.2199997901916504 +910,31500,0.00019873016572091728,-1,-2,0.00019873016572091728,6.2600002288818359 +911,64000,6.48437489871867e-05,-1,-2,6.48437489871867e-05,4.1500000953674316 +912,0,inf,-1,-2,inf,1.0700000524520874 +913,15900,0.00039119494613260031,-1,-2,0.00039119494613260031,6.2199997901916504 +914,31000,0.00013935484457761049,-1,-2,0.00013935484457761049,4.320000171661377 +915,0,inf,-1,-2,inf,2.7599999904632568 +916,57500,7.5478266808204353e-05,-1,-2,7.5478266808204353e-05,4.3400001525878906 +917,165000,4.7272729716496542e-05,-1,-2,4.7272729716496542e-05,7.8000001907348633 +918,22890,0.00014941023255232722,-1,-2,0.00014941023255232722,3.4200000762939453 +919,28900,0.0001553633192088455,-1,-2,0.0001553633192088455,4.4899997711181641 +920,54800,8.5766423580935225e-06,-1,-2,8.5766423580935225e-06,0.4699999988079071 +921,94900,2.9188619009801187e-05,-1,-2,2.9188619009801187e-05,2.7699999809265137 +922,261000,1.0191571163886692e-05,-1,-2,1.0191571163886692e-05,2.6600000858306885 +923,103370,2.2637128495262004e-05,-1,-2,2.2637128495262004e-05,2.3399999141693115 +924,8300,0.00026987952878698707,-1,-2,0.00026987952878698707,2.2400000095367432 +925,10100,0.00038712873356416821,-1,-2,0.00038712873356416821,3.9100000858306885 +926,19500,0.00026153845828957856,-1,-2,0.00026153845828957856,5.0999999046325684 +927,61900,4.5395798224490136e-05,-1,-2,4.5395798224490136e-05,2.809999942779541 +928,10100,0.00024158415908459574,-1,-2,0.00024158415908459574,2.440000057220459 +929,20000,0.00015249999705702066,-1,-2,0.00015249999705702066,3.0499999523162842 +930,18000,0.00015944443293847144,-1,-2,0.00015944443293847144,2.869999885559082 +931,57400,4.198606256977655e-05,-1,-2,4.198606256977655e-05,2.4100000858306885 +932,13000,0.00032461536466144025,-1,-2,0.00032461536466144025,4.2199997901916504 +933,632600,5.5169143706734758e-06,-1,-2,5.5169143706734758e-06,3.4900000095367432 +934,54800,5.1094888476654887e-05,-1,-2,5.1094888476654887e-05,2.7999999523162842 +935,4300,0.000883720931597054,-1,-2,0.000883720931597054,3.7999999523162842 +936,76100,2.6018396965810098e-05,-1,-2,2.6018396965810098e-05,1.9800000190734863 +937,5660,0.0004204947326797992,-1,-2,0.0004204947326797992,2.380000114440918 +938,14000,2.8571428629220463e-05,-1,-2,2.8571428629220463e-05,0.40000000596046448 +939,0,inf,-1,-2,inf,2.8499999046325684 +940,20800,0.00017692307301331311,-1,-2,0.00017692307301331311,3.6800000667572021 +941,8200,0.00025121949147433043,-1,-2,0.00025121949147433043,2.059999942779541 +942,11030,0.00044696280383504927,-1,-2,0.00044696280383504927,4.929999828338623 +943,69900,3.9198854210553691e-05,-1,-2,3.9198854210553691e-05,2.7400000095367432 +944,144100,2.5468425519648008e-05,-1,-2,2.5468425519648008e-05,3.6700000762939453 +945,24700,0.00010526315600145608,-1,-2,0.00010526315600145608,2.5999999046325684 +946,25000,0.00025079998886212707,-1,-2,0.00025079998886212707,6.2699999809265137 +947,73390,4.9461781600257382e-05,-1,-2,4.9461781600257382e-05,3.630000114440918 +948,101000,3.62376231350936e-05,-1,-2,3.62376231350936e-05,3.6600000858306885 +949,145450,1.5262976376106963e-05,-1,-2,1.5262976376106963e-05,2.2200000286102295 +950,85900,3.5157157981302589e-05,-1,-2,3.5157157981302589e-05,3.0199999809265137 +951,44000,3.7272726331138983e-05,-1,-2,3.7272726331138983e-05,1.6399999856948853 +952,40400,0.00012252475426066667,-1,-2,0.00012252475426066667,4.9499998092651367 +953,13100,0.00015419846749864519,-1,-2,0.00015419846749864519,2.0199999809265137 +954,116000,1.6379310181946494e-05,-1,-2,1.6379310181946494e-05,1.8999999761581421 +955,15000,3.4666663850657642e-05,-1,-2,3.4666663850657642e-05,0.51999998092651367 +956,35500,7.2957744123414159e-05,-1,-2,7.2957744123414159e-05,2.5899999141693115 +957,84000,2.4761904569459148e-05,-1,-2,2.4761904569459148e-05,2.0799999237060547 +958,195700,1.5022994375613052e-05,-1,-2,1.5022994375613052e-05,2.940000057220459 +959,15000,0.00012066666386090219,-1,-2,0.00012066666386090219,1.809999942779541 +960,0,inf,-1,-2,inf,2.0699999332427979 +961,4000,0.00060999998822808266,-1,-2,0.00060999998822808266,2.440000057220459 +962,12100,0.00038677683915011585,-1,-2,0.00038677683915011585,4.679999828338623 +963,14800,0.0002608108043204993,-1,-2,0.0002608108043204993,3.8599998950958252 +964,26700,5.6179775128839538e-05,-1,-2,5.6179775128839538e-05,1.5 +965,0,inf,-1,-2,inf,4.3600001335144043 +966,28600,0.00015804196300450712,-1,-2,0.00015804196300450712,4.5199999809265137 +967,25000,0.00011159999849041924,-1,-2,0.00011159999849041924,2.7899999618530273 +968,15400,0.00037337662070058286,-1,-2,0.00037337662070058286,5.75 +969,7100,0.00049436622066423297,-1,-2,0.00049436622066423297,3.5099999904632568 +970,25640,6.0452417528722435e-05,-1,-2,6.0452417528722435e-05,1.5499999523162842 +971,26640,0.00016141141531988978,-1,-2,0.00016141141531988978,4.3000001907348633 +972,44000,6.1136364820413291e-05,-1,-2,6.1136364820413291e-05,2.690000057220459 +973,20000,0.00020150000636931509,-1,-2,0.00020150000636931509,4.0300002098083496 +974,161000,1.2857142792199738e-05,-1,-2,1.2857142792199738e-05,2.0699999332427979 +975,87600,4.0410959627479315e-05,-1,-2,4.0410959627479315e-05,3.5399999618530273 +976,9600,0.00050104164984077215,-1,-2,0.00050104164984077215,4.809999942779541 +977,80300,4.7073473979253322e-05,-1,-2,4.7073473979253322e-05,3.7799999713897705 +978,0,inf,-1,-2,inf,1.6399999856948853 +979,5660,0.00066961132688447833,-1,-2,0.00066961132688447833,3.7899999618530273 +980,0,inf,-1,-2,inf,3.4800000190734863 +981,17000,0.00022000000171829015,-1,-2,0.00022000000171829015,3.7400000095367432 +982,14900,0.00019261744455434382,-1,-2,0.00019261744455434382,2.869999885559082 +983,311000,1.4919613931851927e-05,-1,-2,1.4919613931851927e-05,4.6399998664855957 +984,16700,0.0001203592837555334,-1,-2,0.0001203592837555334,2.0099999904632568 +985,65000,7.4615381890907884e-05,-1,-2,7.4615381890907884e-05,4.8499999046325684 +986,17300,0.00012254335160832852,-1,-2,0.00012254335160832852,2.119999885559082 +987,25000,0.00018440000712871552,-1,-2,0.00018440000712871552,4.6100001335144043 +988,17200,0.00018662790535017848,-1,-2,0.00018662790535017848,3.2100000381469727 +989,6400,0.00099531246814876795,-1,-2,0.00099531246814876795,6.369999885559082 +990,54500,4.5871558540966362e-05,-1,-2,4.5871558540966362e-05,2.5 +991,4990,0.0008276553126052022,-1,-2,0.0008276553126052022,4.130000114440918 +992,110000,2.6272728064213879e-05,-1,-2,2.6272728064213879e-05,2.8900001049041748 +993,0,inf,-1,-2,inf,2.0099999904632568 +994,128200,3.3151325624203309e-05,-1,-2,3.3151325624203309e-05,4.25 +995,8100,0.00055802467977628112,-1,-2,0.00055802467977628112,4.5199999809265137 +996,105050,3.1794381357030943e-05,-1,-2,3.1794381357030943e-05,3.3399999141693115 +997,26030,0.0001678832049947232,-1,-2,0.0001678832049947232,4.369999885559082 +998,223900,2.4966502678580582e-05,-1,-2,2.4966502678580582e-05,5.5900001525878906 +999,37700,7.2679045842960477e-05,-1,-2,7.2679045842960477e-05,2.7400000095367432 +1000,6300,0.00045873018098063767,-1,-2,0.00045873018098063767,2.8900001049041748 +1001,8200,0.00035609756014309824,-1,-2,0.00035609756014309824,2.9200000762939453 +1002,0,inf,-1,-2,inf,4 +1003,27700,0.00020902526739519089,-1,-2,0.00020902526739519089,5.7899999618530273 +1004,325000,6.7076925915898755e-06,-1,-2,6.7076925915898755e-06,2.1800000667572021 +1005,51000,0.00010372549149906263,-1,-2,0.00010372549149906263,5.2899999618530273 +1006,146220,3.2964027923299e-05,-1,-2,3.2964027923299e-05,4.820000171661377 +1007,0,inf,-1,-2,inf,2.9600000381469727 +1008,14000,0.00029642856679856777,-1,-2,0.00029642856679856777,4.1500000953674316 +1009,35000,0.00015514285769313574,-1,-2,0.00015514285769313574,5.429999828338623 +1010,9000,0.00027333333855494857,-1,-2,0.00027333333855494857,2.4600000381469727 +1011,32500,9.5384610176552087e-05,-1,-2,9.5384610176552087e-05,3.0999999046325684 +1012,14600,0.00014794521848671138,-1,-2,0.00014794521848671138,2.1600000858306885 +1013,41000,9.7560972790233791e-05,-1,-2,9.7560972790233791e-05,4 +1014,87000,5.5057469580788165e-05,-1,-2,5.5057469580788165e-05,4.7899999618530273 +1015,45600,5.7017543440451846e-05,-1,-2,5.7017543440451846e-05,2.5999999046325684 +1016,0,inf,-1,-2,inf,4.5100002288818359 +1017,8300,0.00034337348188273609,-1,-2,0.00034337348188273609,2.8499999046325684 +1018,42450,7.7738513937219977e-05,-1,-2,7.7738513937219977e-05,3.2999999523162842 +1019,45500,6.6373628214932978e-05,-1,-2,6.6373628214932978e-05,3.0199999809265137 +1020,0,inf,-1,-2,inf,3.0499999523162842 +1021,690,0.003594202920794487,-1,-2,0.003594202920794487,2.4800000190734863 +1022,8100,0.00057654321426525712,-1,-2,0.00057654321426525712,4.6700000762939453 +1023,60000,9.4999995781108737e-05,-1,-2,9.4999995781108737e-05,5.6999998092651367 +1024,43300,7.2055423515848815e-05,-1,-2,7.2055423515848815e-05,3.119999885559082 +1025,20040,0.00022554889437742531,-1,-2,0.00022554889437742531,4.5199999809265137 +1026,0,inf,-1,-2,inf,3.4900000095367432 +1027,8800,4.4318181608105078e-05,-1,-2,4.4318181608105078e-05,0.38999998569488525 +1028,61000,6.2295082898344845e-05,-1,-2,6.2295082898344845e-05,3.7999999523162842 +1029,17000,0.00020235293777659535,-1,-2,0.00020235293777659535,3.440000057220459 +1030,92000,5.0326088967267424e-05,-1,-2,5.0326088967267424e-05,4.630000114440918 +1031,50400,1.2301587048568763e-05,-1,-2,1.2301587048568763e-05,0.62000000476837158 +1032,0,inf,-1,-2,inf,4.5999999046325684 +1033,165000,9.939393748936709e-06,-1,-2,9.939393748936709e-06,1.6399999856948853 +1034,9300,0.00022688170429319143,-1,-2,0.00022688170429319143,2.1099998950958252 +1035,8300,0.00053132529137656093,-1,-2,0.00053132529137656093,4.4099998474121094 +1036,137000,2.2992700905888341e-05,-1,-2,2.2992700905888341e-05,3.1500000953674316 +1037,18000,9.1666668595280498e-05,-1,-2,9.1666668595280498e-05,1.6499999761581421 +1038,31360,0.00013966836559120566,-1,-2,0.00013966836559120566,4.380000114440918 +1039,0,inf,-1,-2,inf,2.6500000953674316 +1040,7000,0.00052142859203740954,-1,-2,0.00052142859203740954,3.6500000953674316 +1041,0,inf,-1,-2,inf,4.820000171661377 +1042,52000,3.8653844967484474e-05,-1,-2,3.8653844967484474e-05,2.0099999904632568 +1043,58000,9.2241374659352005e-05,-1,-2,9.2241374659352005e-05,5.3499999046325684 +1044,7600,0.00049999996554106474,-1,-2,0.00049999996554106474,3.7999999523162842 +1045,0,inf,-1,-2,inf,2.1800000667572021 +1046,74100,5.8299596275901422e-05,-1,-2,5.8299596275901422e-05,4.320000171661377 +1047,0,inf,-1,-2,inf,4.2800002098083496 +1048,14600,0.00016780821897555143,-1,-2,0.00016780821897555143,2.4500000476837158 +1049,15000,0.00027000001864507794,-1,-2,0.00027000001864507794,4.0500001907348633 +1050,128200,2.0982839487260208e-05,-1,-2,2.0982839487260208e-05,2.690000057220459 +1051,62000,8.9838715211953968e-05,-1,-2,8.9838715211953968e-05,5.570000171661377 +1052,23100,6.5800864831544459e-05,-1,-2,6.5800864831544459e-05,1.5199999809265137 +1053,117000,3.2478630600962788e-05,-1,-2,3.2478630600962788e-05,3.7999999523162842 +1054,90000,4.1555555071681738e-05,-1,-2,4.1555555071681738e-05,3.7400000095367432 +1055,7900,0.00052278483053669333,-1,-2,0.00052278483053669333,4.130000114440918 +1056,54400,5.5882352171465755e-05,-1,-2,5.5882352171465755e-05,3.0399999618530273 +1057,220000,1.9181818061042577e-05,-1,-2,1.9181818061042577e-05,4.2199997901916504 +1058,15400,8.7662338046357036e-05,-1,-2,8.7662338046357036e-05,1.3500000238418579 +1059,45700,3.4792123187799007e-05,-1,-2,3.4792123187799007e-05,1.5900000333786011 +1060,70000,7.0714282628614455e-05,-1,-2,7.0714282628614455e-05,4.9499998092651367 +1061,30000,2.7000000045518391e-05,-1,-2,2.7000000045518391e-05,0.81000000238418579 +1062,70000,3.3571428502909839e-05,-1,-2,3.3571428502909839e-05,2.3499999046325684 +1063,8800,0.00040113634895533323,-1,-2,0.00040113634895533323,3.5299999713897705 +1064,24600,0.00018048781203106046,-1,-2,0.00018048781203106046,4.440000057220459 +1065,11000,5.9090907598147169e-05,-1,-2,5.9090907598147169e-05,0.64999997615814209 +1066,60000,2.4999999368446879e-05,-1,-2,2.4999999368446879e-05,1.5 +1067,200,0.0087000001221895218,-1,-2,0.0087000001221895218,1.7400000095367432 +1068,22500,7.3333329055458307e-05,-1,-2,7.3333329055458307e-05,1.6499999761581421 +1069,64000,8.1250000221189111e-05,-1,-2,8.1250000221189111e-05,5.1999998092651367 +1070,4000,0.0012050000950694084,-1,-2,0.0012050000950694084,4.820000171661377 +1071,110000,3.2090909371618181e-05,-1,-2,3.2090909371618181e-05,3.5299999713897705 +1072,0,inf,-1,-2,inf,3.2200000286102295 +1073,21000,0.00024285713152494282,-1,-2,0.00024285713152494282,5.0999999046325684 +1074,75000,2.8133332307334058e-05,-1,-2,2.8133332307334058e-05,2.1099998950958252 +1075,62000,5.3548385039903224e-05,-1,-2,5.3548385039903224e-05,3.3199999332427979 +1076,55000,4.3818185076816007e-05,-1,-2,4.3818185076816007e-05,2.4100000858306885 +1077,3700,0.00077837839489802718,-1,-2,0.00077837839489802718,2.880000114440918 +1078,8500,0.00024235293676611036,-1,-2,0.00024235293676611036,2.059999942779541 +1079,16000,0.00020749999384861439,-1,-2,0.00020749999384861439,3.3199999332427979 +1080,117000,4.9230769946007058e-05,-1,-2,4.9230769946007058e-05,5.7600002288818359 +1081,5050,0.00084158417303115129,-1,-2,0.00084158417303115129,4.25 +1082,150750,2.6932006221613847e-05,-1,-2,2.6932006221613847e-05,4.059999942779541 +1083,19200,0.00014375000318977982,-1,-2,0.00014375000318977982,2.7599999904632568 +1084,100000,3.5299999581184238e-05,-1,-2,3.5299999581184238e-05,3.5299999713897705 +1085,4300,0.00077209301525726914,-1,-2,0.00077209301525726914,3.3199999332427979 +1086,8200,0.00033536585397087038,-1,-2,0.00033536585397087038,2.75 +1087,29000,0.0001972413738258183,-1,-2,0.0001972413738258183,5.7199997901916504 +1088,0,inf,-1,-2,inf,4.8499999046325684 +1089,74100,6.4912281231954694e-05,-1,-2,6.4912281231954694e-05,4.809999942779541 +1090,16000,9.4999995781108737e-05,-1,-2,9.4999995781108737e-05,1.5199999809265137 +1091,62000,3.4032254916382954e-05,-1,-2,3.4032254916382954e-05,2.1099998950958252 +1092,14700,0.00028979592025279999,-1,-2,0.00028979592025279999,4.2600002288818359 +1093,0,inf,-1,-2,inf,5.380000114440918 +1094,0,inf,-1,-2,inf,3.4900000095367432 +1095,87200,3.0275230528786778e-05,-1,-2,3.0275230528786778e-05,2.6400001049041748 +1096,43300,6.674365431535989e-05,-1,-2,6.674365431535989e-05,2.8900001049041748 +1097,49000,6.0612244851654395e-05,-1,-2,6.0612244851654395e-05,2.9700000286102295 +1098,250,0.0081599997356534004,-1,-2,0.0081599997356534004,2.0399999618530273 +1099,15600,0.00022948718105908483,-1,-2,0.00022948718105908483,3.5799999237060547 +1100,22500,0.00011911111505469307,-1,-2,0.00011911111505469307,2.6800000667572021 +1101,148500,1.7777778339223005e-05,-1,-2,1.7777778339223005e-05,2.6400001049041748 +1102,0,inf,-1,-2,inf,5.0399999618530273 +1103,27030,0.00016389196389354765,-1,-2,0.00016389196389354765,4.429999828338623 +1104,250,0.0056399996392428875,-1,-2,0.0056399996392428875,1.4099999666213989 +1105,80600,5.5955337302293628e-05,-1,-2,5.5955337302293628e-05,4.5100002288818359 +1106,1300,0.0026000000070780516,-1,-2,0.0026000000070780516,3.380000114440918 +1107,0,inf,-1,-2,inf,5.4099998474121094 +1108,28900,9.7923875728156418e-05,-1,-2,9.7923875728156418e-05,2.8299999237060547 +1109,35400,0.00014632768579758704,-1,-2,0.00014632768579758704,5.179999828338623 +1110,11900,0.00041596638038754463,-1,-2,0.00041596638038754463,4.9499998092651367 +1111,8100,0.00049382715951651335,-1,-2,0.00049382715951651335,4 +1112,0,inf,-1,-2,inf,2.4100000858306885 +1113,134000,3.4029850212391466e-05,-1,-2,3.4029850212391466e-05,4.559999942779541 +1114,44500,6.8089888372924179e-05,-1,-2,6.8089888372924179e-05,3.0299999713897705 +1115,18810,7.6555028499569744e-05,-1,-2,7.6555028499569744e-05,1.440000057220459 +1116,0,inf,-1,-2,inf,3.7000000476837158 +1117,3900,0.0014230769593268633,-1,-2,0.0014230769593268633,5.5500001907348633 +1118,45000,9.288888395531103e-05,-1,-2,9.288888395531103e-05,4.179999828338623 +1119,101400,3.3037475077435374e-05,-1,-2,3.3037475077435374e-05,3.3499999046325684 +1120,30040,0.00015679094940423965,-1,-2,0.00015679094940423965,4.7100000381469727 +1121,0,inf,-1,-2,inf,1.9700000286102295 +1122,52000,5.9038458857685328e-05,-1,-2,5.9038458857685328e-05,3.0699999332427979 +1123,133000,3.3834585337899625e-06,-1,-2,3.3834585337899625e-06,0.44999998807907104 +1124,75000,4.1333332774229348e-05,-1,-2,4.1333332774229348e-05,3.0999999046325684 +1125,38300,0.0001707571791484952,-1,-2,0.0001707571791484952,6.5399999618530273 +1126,141200,1.7209631550940685e-05,-1,-2,1.7209631550940685e-05,2.4300000667572021 +1127,43700,9.2448513896670192e-05,-1,-2,9.2448513896670192e-05,4.0399999618530273 +1128,0,inf,-1,-2,inf,3.9700000286102295 +1129,25000,0.0001939999929163605,-1,-2,0.0001939999929163605,4.8499999046325684 +1130,28000,0.00012821427662856877,-1,-2,0.00012821427662856877,3.5899999141693115 +1131,0,inf,-1,-2,inf,0.81999999284744263 +1132,29000,2.4137931177392602e-05,-1,-2,2.4137931177392602e-05,0.69999998807907104 +1133,35400,6.2994353356771171e-05,-1,-2,6.2994353356771171e-05,2.2300000190734863 +1134,25000,0.00010800000018207356,-1,-2,0.00010800000018207356,2.7000000476837158 +1135,62000,6.0322581703076139e-05,-1,-2,6.0322581703076139e-05,3.7400000095367432 +1136,18000,4.8888887249631807e-05,-1,-2,4.8888887249631807e-05,0.87999999523162842 +1137,290,0.018448276445269585,-1,-2,0.018448276445269585,5.3499999046325684 +1138,15100,0.00015761589747853577,-1,-2,0.00015761589747853577,2.380000114440918 +1139,36000,0.00015027777408249676,-1,-2,0.00015027777408249676,5.4099998474121094 +1140,14500,0.00052137929014861584,-1,-2,0.00052137929014861584,7.559999942779541 +1141,9600,0.00015937499119900167,-1,-2,0.00015937499119900167,1.5299999713897705 +1142,14500,0.00038965517887845635,-1,-2,0.00038965517887845635,5.6500000953674316 +1143,9000,0.00034444444463588297,-1,-2,0.00034444444463588297,3.0999999046325684 +1144,40050,8.4394509030971676e-05,-1,-2,8.4394509030971676e-05,3.380000114440918 +1145,25000,0.00016719999257475138,-1,-2,0.00016719999257475138,4.179999828338623 +1146,14800,7.1621616370975971e-05,-1,-2,7.1621616370975971e-05,1.059999942779541 +1147,158200,8.2174456110806204e-06,-1,-2,8.2174456110806204e-06,1.2999999523162842 +1148,0,inf,-1,-2,inf,2.6600000858306885 +1149,78800,7.4746189056895673e-05,-1,-2,7.4746189056895673e-05,5.8899998664855957 +1150,31400,9.1401270765345544e-05,-1,-2,9.1401270765345544e-05,2.869999885559082 +1151,8400,0.00032619046396575868,-1,-2,0.00032619046396575868,2.7400000095367432 +1152,220000,3.0454546049440978e-06,-1,-2,3.0454546049440978e-06,0.67000001668930054 +1153,0,inf,-1,-2,inf,5.8299999237060547 +1154,333000,1.2762762708007358e-05,-1,-2,1.2762762708007358e-05,4.25 +1155,7500,0.00036933334195055068,-1,-2,0.00036933334195055068,2.7699999809265137 +1156,0,inf,-1,-2,inf,3.630000114440918 +1157,50000,8.7600004917476326e-05,-1,-2,8.7600004917476326e-05,4.380000114440918 +1158,24600,2.6422763767186552e-05,-1,-2,2.6422763767186552e-05,0.64999997615814209 +1159,0,inf,-1,-2,inf,2.7699999809265137 +1160,9900,0.0004909090930595994,-1,-2,0.0004909090930595994,4.8600001335144043 +1161,8700,0.00042873562779277563,-1,-2,0.00042873562779277563,3.7300000190734863 +1162,22600,0.00026061947573907673,-1,-2,0.00026061947573907673,5.8899998664855957 +1163,0,inf,-1,-2,inf,3.75 +1164,31400,0.00010668789764167741,-1,-2,0.00010668789764167741,3.3499999046325684 +1165,200000,2.0250001398380846e-05,-1,-2,2.0250001398380846e-05,4.0500001907348633 +1166,83000,6.4698797359596938e-05,-1,-2,6.4698797359596938e-05,5.369999885559082 +1167,19100,0.00031518324976786971,-1,-2,0.00031518324976786971,6.0199999809265137 +1168,9100,0.0003769230970647186,-1,-2,0.0003769230970647186,3.4300000667572021 +1169,81500,8.5153376858215779e-05,-1,-2,8.5153376858215779e-05,6.940000057220459 +1170,0,inf,-1,-2,inf,4.6999998092651367 +1171,16800,3.3333333703922108e-05,-1,-2,3.3333333703922108e-05,0.56000000238418579 +1172,100500,2.0995023078285158e-05,-1,-2,2.0995023078285158e-05,2.1099998950958252 +1173,6000,0.00031166666303761303,-1,-2,0.00031166666303761303,1.8700000047683716 +1174,58000,2.7758620490203612e-05,-1,-2,2.7758620490203612e-05,1.6100000143051147 +1175,13000,0.00012769229942932725,-1,-2,0.00012769229942932725,1.6599999666213989 +1176,9400,0.00029680851730518043,-1,-2,0.00029680851730518043,2.7899999618530273 +1177,17500,0.00017314284923486412,-1,-2,0.00017314284923486412,3.0299999713897705 +1178,95900,2.3461940145352855e-05,-1,-2,2.3461940145352855e-05,2.25 +1179,0,inf,-1,-2,inf,3.119999885559082 +1180,0,inf,-1,-2,inf,4.3400001525878906 +1181,137000,2.875912468880415e-05,-1,-2,2.875912468880415e-05,3.940000057220459 +1182,0,inf,-1,-2,inf,3.7000000476837158 +1183,23100,9.9567099823616445e-05,-1,-2,9.9567099823616445e-05,2.2999999523162842 +1184,9300,0.00046021508751437068,-1,-2,0.00046021508751437068,4.2800002098083496 +1185,910,0.0015494505641981959,-1,-2,0.0015494505641981959,1.4099999666213989 +1186,99500,4.0100501792039722e-05,-1,-2,4.0100501792039722e-05,3.9900000095367432 +1187,14900,0.00011476510553620756,-1,-2,0.00011476510553620756,1.7100000381469727 +1188,145020,3.7029374652775005e-05,-1,-2,3.7029374652775005e-05,5.369999885559082 +1189,89900,5.3948831919115037e-05,-1,-2,5.3948831919115037e-05,4.8499999046325684 +1190,7000,0.00050428573740646243,-1,-2,0.00050428573740646243,3.5299999713897705 +1191,35000,3.0857143428875133e-05,-1,-2,3.0857143428875133e-05,1.0800000429153442 +1192,74000,4.4324322516331449e-05,-1,-2,4.4324322516331449e-05,3.2799999713897705 +1193,110100,3.3333333703922108e-05,-1,-2,3.3333333703922108e-05,3.6700000762939453 +1194,45000,7.5111114711035043e-05,-1,-2,7.5111114711035043e-05,3.380000114440918 +1195,44500,0.00010157303040614352,-1,-2,0.00010157303040614352,4.5199999809265137 +1196,39700,0.00010957178892567754,-1,-2,0.00010957178892567754,4.3499999046325684 +1197,63000,7.2539682150818408e-05,-1,-2,7.2539682150818408e-05,4.570000171661377 +1198,143600,1.838440221035853e-05,-1,-2,1.838440221035853e-05,2.6400001049041748 +1199,4000,0.00013000000035390258,-1,-2,0.00013000000035390258,0.51999998092651367 +1200,25640,0.00024804993881843984,-1,-2,0.00024804993881843984,6.3600001335144043 +1201,23700,0.00017046413267962635,-1,-2,0.00017046413267962635,4.0399999618530273 +1202,56500,0.00010460176417836919,-1,-2,0.00010460176417836919,5.9099998474121094 +1203,69540,4.4147251173853874e-05,-1,-2,4.4147251173853874e-05,3.0699999332427979 +1204,80370,5.4995645768940449e-05,-1,-2,5.4995645768940449e-05,4.4200000762939453 +1205,17000,0.0003252941241953522,-1,-2,0.0003252941241953522,5.5300002098083496 +1206,9100,0.00022857141448184848,-1,-2,0.00022857141448184848,2.0799999237060547 +1207,75000,4.2933334043482319e-05,-1,-2,4.2933334043482319e-05,3.2200000286102295 +1208,66850,3.2161558920051903e-05,-1,-2,3.2161558920051903e-05,2.1500000953674316 +1209,125400,4.0829345380188897e-05,-1,-2,4.0829345380188897e-05,5.119999885559082 +1210,116000,3.8706893974449486e-05,-1,-2,3.8706893974449486e-05,4.4899997711181641 +1211,0,inf,-1,-2,inf,4.2199997901916504 +1212,51100,7.9843441199045628e-05,-1,-2,7.9843441199045628e-05,4.0799999237060547 +1213,51200,4.1210936615243554e-05,-1,-2,4.1210936615243554e-05,2.1099998950958252 +1214,0,inf,-1,-2,inf,3.4200000762939453 +1215,8320,0.00022355769760906696,-1,-2,0.00022355769760906696,1.8600000143051147 +1216,18000,5.6111111916834489e-05,-1,-2,5.6111111916834489e-05,1.0099999904632568 +1217,65300,7.6263400842435658e-05,-1,-2,7.6263400842435658e-05,4.9800000190734863 +1218,87200,3.5091743484372273e-05,-1,-2,3.5091743484372273e-05,3.059999942779541 +1219,1300,0.0033307692501693964,-1,-2,0.0033307692501693964,4.3299999237060547 +1220,84400,9.5971563496277668e-06,-1,-2,9.5971563496277668e-06,0.81000000238418579 +1221,0,inf,-1,-2,inf,3.9700000286102295 +1222,32500,0.00012861538561992347,-1,-2,0.00012861538561992347,4.179999828338623 +1223,4000,0.0011050000321120024,-1,-2,0.0011050000321120024,4.4200000762939453 +1224,0,inf,-1,-2,inf,2.440000057220459 +1225,0,inf,-1,-2,inf,3.7300000190734863 +1226,106120,3.8352809497155249e-05,-1,-2,3.8352809497155249e-05,4.070000171661377 +1227,103400,4.9516438593855128e-05,-1,-2,4.9516438593855128e-05,5.119999885559082 +1228,10300,0.00026796114980243146,-1,-2,0.00026796114980243146,2.7599999904632568 +1229,18200,0.00013076924369670451,-1,-2,0.00013076924369670451,2.380000114440918 +1230,4000,0.00067249999847263098,-1,-2,0.00067249999847263098,2.690000057220459 +1231,6780,0.0007640117546543479,-1,-2,0.0007640117546543479,5.179999828338623 +1232,20200,0.00027425741427578032,-1,-2,0.00027425741427578032,5.5399999618530273 +1233,17600,0.00028693184140138328,-1,-2,0.00028693184140138328,5.0500001907348633 +1234,18000,2.8888887754874304e-05,-1,-2,2.8888887754874304e-05,0.51999998092651367 +1235,57500,4.6260869567049667e-05,-1,-2,4.6260869567049667e-05,2.6600000858306885 +1236,150000,2.8933334760949947e-05,-1,-2,2.8933334760949947e-05,4.3400001525878906 +1237,8500,0.00046941175241954625,-1,-2,0.00046941175241954625,3.9900000095367432 +1238,18700,0.00023262031027115881,-1,-2,0.00023262031027115881,4.3499999046325684 +1239,35300,9.4900846306700259e-05,-1,-2,9.4900846306700259e-05,3.3499999046325684 +1240,41550,5.8243083913112059e-05,-1,-2,5.8243083913112059e-05,2.4200000762939453 +1241,8400,0.00022499999613501132,-1,-2,0.00022499999613501132,1.8899999856948853 +1242,47000,4.3404255848145112e-05,-1,-2,4.3404255848145112e-05,2.0399999618530273 +1243,8000,0.00036624999484047294,-1,-2,0.00036624999484047294,2.9300000667572021 +1244,19200,0.00016145833069458604,-1,-2,0.00016145833069458604,3.0999999046325684 +1245,26050,0.0001631477935006842,-1,-2,0.0001631477935006842,4.25 +1246,0,inf,-1,-2,inf,4.8000001907348633 +1247,8860,0.00048307000542990863,-1,-2,0.00048307000542990863,4.2800002098083496 +1248,18000,9.1666668595280498e-05,-1,-2,9.1666668595280498e-05,1.6499999761581421 +1249,0,inf,-1,-2,inf,2.5999999046325684 +1250,94400,2.3834745661588386e-05,-1,-2,2.3834745661588386e-05,2.25 +1251,61000,5.8852456277236342e-05,-1,-2,5.8852456277236342e-05,3.5899999141693115 +1252,24000,0.00018916666158474982,-1,-2,0.00018916666158474982,4.5399999618530273 +1253,39980,0.0001550775341456756,-1,-2,0.0001550775341456756,6.1999998092651367 +1254,0,inf,-1,-2,inf,4.8499999046325684 +1255,8100,0.00059382716426625848,-1,-2,0.00059382716426625848,4.809999942779541 +1256,13600,0.00014485293650068343,-1,-2,0.00014485293650068343,1.9700000286102295 +1257,23510,0.00022458529565483332,-1,-2,0.00022458529565483332,5.2800002098083496 +1258,13900,0.00018489208014216274,-1,-2,0.00018489208014216274,2.5699999332427979 +1259,77000,3.3766231354093179e-05,-1,-2,3.3766231354093179e-05,2.5999999046325684 +1260,36000,2.166666672565043e-05,-1,-2,2.166666672565043e-05,0.77999997138977051 +1261,12600,0.00050079362699761987,-1,-2,0.00050079362699761987,6.309999942779541 +1262,75000,3.6800000088987872e-05,-1,-2,3.6800000088987872e-05,2.7599999904632568 +1263,102800,2.7918285923078656e-05,-1,-2,2.7918285923078656e-05,2.869999885559082 +1264,86400,2.2800926672061905e-05,-1,-2,2.2800926672061905e-05,1.9700000286102295 +1265,19000,0.00023842106747906655,-1,-2,0.00023842106747906655,4.5300002098083496 +1266,66400,5.1506023737601936e-05,-1,-2,5.1506023737601936e-05,3.4200000762939453 +1267,14000,0.00031142859370447695,-1,-2,0.00031142859370447695,4.3600001335144043 +1268,24400,0.00016639343812130392,-1,-2,0.00016639343812130392,4.059999942779541 +1269,8990,0.00041713015525601804,-1,-2,0.00041713015525601804,3.75 +1270,0,inf,-1,-2,inf,4.630000114440918 +1271,0,inf,-1,-2,inf,2.9900000095367432 +1272,30,0.21033333241939545,-1,-2,0.21033333241939545,6.309999942779541 +1273,8300,0.00046024096081964672,-1,-2,0.00046024096081964672,3.8199999332427979 +1274,2800,0.00078214285895228386,-1,-2,0.00078214285895228386,2.190000057220459 +1275,8400,0.00028571428265422583,-1,-2,0.00028571428265422583,2.4000000953674316 +1276,0,inf,-1,-2,inf,4.6399998664855957 +1277,28900,7.5778545578941703e-05,-1,-2,7.5778545578941703e-05,2.190000057220459 +1278,39700,8.8413100456818938e-05,-1,-2,8.8413100456818938e-05,3.5099999904632568 +1279,10800,0.00055925926426425576,-1,-2,0.00055925926426425576,6.0399999618530273 +1280,23100,0.00010303031012881547,-1,-2,0.00010303031012881547,2.380000114440918 +1281,8860,0.00030586909269914031,-1,-2,0.00030586909269914031,2.7100000381469727 +1282,25600,0.00021015625679865479,-1,-2,0.00021015625679865479,5.380000114440918 +1283,8900,0.00032584270229563117,-1,-2,0.00032584270229563117,2.9000000953674316 +1284,20000,0.0003009999927598983,-1,-2,0.0003009999927598983,6.0199999809265137 +1285,85700,2.34539093071362e-05,-1,-2,2.34539093071362e-05,2.0099999904632568 +1286,109500,3.8721460441593081e-05,-1,-2,3.8721460441593081e-05,4.2399997711181641 +1287,52000,5.7307694078190252e-05,-1,-2,5.7307694078190252e-05,2.9800000190734863 +1288,11200,0.00017500000831205398,-1,-2,0.00017500000831205398,1.9600000381469727 +1289,40400,9.9999997473787516e-05,-1,-2,9.9999997473787516e-05,4.0399999618530273 +1290,130000,2.0923076590406708e-05,-1,-2,2.0923076590406708e-05,2.7200000286102295 +1291,21000,0.00014857141650281847,-1,-2,0.00014857141650281847,3.119999885559082 +1292,14800,0.00018648648983798921,-1,-2,0.00018648648983798921,2.7599999904632568 +1293,1700,0.0027588235680013895,-1,-2,0.0027588235680013895,4.690000057220459 +1294,8300,0.0004746988124679774,-1,-2,0.0004746988124679774,3.940000057220459 +1295,1500,0.001973333302885294,-1,-2,0.001973333302885294,2.9600000381469727 +1296,15200,7.1052636485546827e-05,-1,-2,7.1052636485546827e-05,1.0800000429153442 +1297,22600,0.00021725663100369275,-1,-2,0.00021725663100369275,4.9099998474121094 +1298,18000,0.0001877777831396088,-1,-2,0.0001877777831396088,3.380000114440918 +1299,8400,0.00053928571287542582,-1,-2,0.00053928571287542582,4.5300002098083496 +1300,61500,3.0081300792517141e-05,-1,-2,3.0081300792517141e-05,1.8500000238418579 +1301,13900,0.00017553957877680659,-1,-2,0.00017553957877680659,2.440000057220459 +1302,24600,9.7560980066191405e-05,-1,-2,9.7560980066191405e-05,2.4000000953674316 +1303,79000,5.9620255342451856e-05,-1,-2,5.9620255342451856e-05,4.7100000381469727 +1304,59000,7.6610165706370026e-05,-1,-2,7.6610165706370026e-05,4.5199999809265137 +1305,21000,0.00017047618166543543,-1,-2,0.00017047618166543543,3.5799999237060547 +1306,0,inf,-1,-2,inf,4.1399998664855957 +1307,7600,0.00033815787173807621,-1,-2,0.00033815787173807621,2.5699999332427979 +1308,0,inf,-1,-2,inf,2.630000114440918 +1309,0,inf,-1,-2,inf,5.690000057220459 +1310,0,inf,-1,-2,inf,2.7699999809265137 +1311,75000,3.1333333026850596e-05,-1,-2,3.1333333026850596e-05,2.3499999046325684 +1312,660,0.0063484851270914078,-1,-2,0.0063484851270914078,4.190000057220459 +1313,68000,6.8823530455119908e-05,-1,-2,6.8823530455119908e-05,4.679999828338623 +1314,7200,0.00079027778701856732,-1,-2,0.00079027778701856732,5.690000057220459 +1315,45500,3.4285712899873033e-05,-1,-2,3.4285712899873033e-05,1.559999942779541 +1316,65600,6.4024388848338276e-05,-1,-2,6.4024388848338276e-05,4.1999998092651367 +1317,64500,2.6511628675507382e-05,-1,-2,2.6511628675507382e-05,1.7100000381469727 +1318,115000,2.6782607164932415e-05,-1,-2,2.6782607164932415e-05,3.0799999237060547 +1319,3100,0.0014548387844115496,-1,-2,0.0014548387844115496,4.5100002288818359 +1320,174500,2.286532981088385e-05,-1,-2,2.286532981088385e-05,3.9900000095367432 +1321,0,inf,-1,-2,inf,0.77999997138977051 +1322,45000,3.4222222893731669e-05,-1,-2,3.4222222893731669e-05,1.5399999618530273 +1323,24900,0.00021164659119676799,-1,-2,0.00021164659119676799,5.2699999809265137 +1324,70000,9.085714555112645e-05,-1,-2,9.085714555112645e-05,6.3600001335144043 +1325,185450,2.3941764084156603e-05,-1,-2,2.3941764084156603e-05,4.440000057220459 +1326,16500,0.00026181820430792868,-1,-2,0.00026181820430792868,4.320000171661377 +1327,0,inf,-1,-2,inf,4.25 +1328,28000,0.00013642857084050775,-1,-2,0.00013642857084050775,3.8199999332427979 +1329,13370,0.00026776365120895207,-1,-2,0.00026776365120895207,3.5799999237060547 +1330,3500,0.00087428570259362459,-1,-2,0.00087428570259362459,3.059999942779541 +1331,0,inf,-1,-2,inf,3.7300000190734863 +1332,18000,0.00019888888346031308,-1,-2,0.00019888888346031308,3.5799999237060547 +1333,11700,0.00026153845828957856,-1,-2,0.00026153845828957856,3.059999942779541 +1334,163000,2.3006134142633528e-05,-1,-2,2.3006134142633528e-05,3.75 +1335,37700,6.8965513492003083e-05,-1,-2,6.8965513492003083e-05,2.5999999046325684 +1336,125000,3.4240001696161926e-05,-1,-2,3.4240001696161926e-05,4.2800002098083496 +1337,145020,2.9926906790933572e-05,-1,-2,2.9926906790933572e-05,4.3400001525878906 +1338,0,inf,-1,-2,inf,3.0699999332427979 +1339,8400,0.00021547618962358683,-1,-2,0.00021547618962358683,1.809999942779541 +1340,22200,0.0002270270197186619,-1,-2,0.0002270270197186619,5.0399999618530273 +1341,7700,0.00035844155354425311,-1,-2,0.00035844155354425311,2.7599999904632568 +1342,414000,9.782609595276881e-06,-1,-2,9.782609595276881e-06,4.0500001907348633 +1343,30500,4.8524590965826064e-05,-1,-2,4.8524590965826064e-05,1.4800000190734863 +1344,5500,0.00052363640861585736,-1,-2,0.00052363640861585736,2.880000114440918 +1345,700,0.0059714284725487232,-1,-2,0.0059714284725487232,4.179999828338623 +1346,385000,1.057142890203977e-05,-1,-2,1.057142890203977e-05,4.070000171661377 +1347,11500,0.00035739131271839142,-1,-2,0.00035739131271839142,4.1100001335144043 +1348,0,inf,-1,-2,inf,3.2100000381469727 +1349,8100,0.00049506174400448799,-1,-2,0.00049506174400448799,4.0100002288818359 +1350,144400,2.5969529815483838e-05,-1,-2,2.5969529815483838e-05,3.75 +1351,87000,6.1034483223920688e-05,-1,-2,6.1034483223920688e-05,5.309999942779541 +1352,0,inf,-1,-2,inf,4.4499998092651367 +1353,68000,6.2500002968590707e-05,-1,-2,6.2500002968590707e-05,4.25 +1354,0,inf,-1,-2,inf,1.3300000429153442 +1355,51000,4.6078428567852825e-05,-1,-2,4.6078428567852825e-05,2.3499999046325684 +1356,35600,1.5168539903243072e-05,-1,-2,1.5168539903243072e-05,0.54000002145767212 +1357,0,inf,-1,-2,inf,2.7599999904632568 +1358,57000,4.5789471187163144e-05,-1,-2,4.5789471187163144e-05,2.6099998950958252 +1359,0,inf,-1,-2,inf,4.630000114440918 +1360,22300,0.00019058295583818108,-1,-2,0.00019058295583818108,4.25 +1361,0,inf,-1,-2,inf,2.9200000762939453 +1362,16000,0.0001037499969243072,-1,-2,0.0001037499969243072,1.6599999666213989 +1363,65300,5.0535991249489598e-06,-1,-2,5.0535991249489598e-06,0.33000001311302185 +1364,20000,0.00018800000543706119,-1,-2,0.00018800000543706119,3.7599999904632568 +1365,24000,0.00020749999384861439,-1,-2,0.00020749999384861439,4.9800000190734863 +1366,116000,3.7499998143175617e-05,-1,-2,3.7499998143175617e-05,4.3499999046325684 +1367,25700,0.00015680934302508831,-1,-2,0.00015680934302508831,4.0300002098083496 +1368,51000,8.8235290604643524e-05,-1,-2,8.8235290604643524e-05,4.5 +1369,0,inf,-1,-2,inf,4.0300002098083496 +1370,110100,6.0944596043555066e-05,-1,-2,6.0944596043555066e-05,6.7100000381469727 +1371,14400,0.00010625000140862539,-1,-2,0.00010625000140862539,1.5299999713897705 +1372,42700,6.5573767642490566e-05,-1,-2,6.5573767642490566e-05,2.7999999523162842 +1373,34300,5.8892128436127678e-05,-1,-2,5.8892128436127678e-05,2.0199999809265137 +1374,53000,9.9433964351192117e-05,-1,-2,9.9433964351192117e-05,5.2699999809265137 +1375,118600,4.8566613259026781e-05,-1,-2,4.8566613259026781e-05,5.7600002288818359 +1376,0,inf,-1,-2,inf,4.130000114440918 +1377,36500,0.00011369863204890862,-1,-2,0.00011369863204890862,4.1500000953674316 +1378,30000,0.00010366666538175195,-1,-2,0.00010366666538175195,3.1099998950958252 +1379,44000,8.0681820691097528e-05,-1,-2,8.0681820691097528e-05,3.5499999523162842 +1380,81000,4.0987652027979493e-05,-1,-2,4.0987652027979493e-05,3.3199999332427979 +1381,8000,4.874999649473466e-05,-1,-2,4.874999649473466e-05,0.38999998569488525 +1382,6400,0.0002593749959487468,-1,-2,0.0002593749959487468,1.6599999666213989 +1383,10000,0.00073600001633167267,-1,-2,0.00073600001633167267,7.3600001335144043 +1384,0,inf,-1,-2,inf,3.1400001049041748 +1385,11000,0.00026999998954124749,-1,-2,0.00026999998954124749,2.9700000286102295 +1386,0,inf,-1,-2,inf,4.179999828338623 +1387,96200,6.0083162679802626e-05,-1,-2,6.0083162679802626e-05,5.7800002098083496 +1388,56600,5.512367351911962e-05,-1,-2,5.512367351911962e-05,3.119999885559082 +1389,7900,0.00071898731403052807,-1,-2,0.00071898731403052807,5.679999828338623 +1390,7000,0.00033857140806503594,-1,-2,0.00033857140806503594,2.369999885559082 +1391,28000,0.00011000000085914508,-1,-2,0.00011000000085914508,3.0799999237060547 +1392,0,inf,-1,-2,inf,3.7400000095367432 +1393,56150,9.5814786618575454e-05,-1,-2,9.5814786618575454e-05,5.380000114440918 +1394,67200,7.3660710768308491e-05,-1,-2,7.3660710768308491e-05,4.9499998092651367 +1395,43700,8.6498854216188192e-05,-1,-2,8.6498854216188192e-05,3.7799999713897705 +1396,64300,6.6562992287799716e-05,-1,-2,6.6562992287799716e-05,4.2800002098083496 +1397,6780,0.00056489673443138599,-1,-2,0.00056489673443138599,3.8299999237060547 +1398,11700,0.00038632479845546186,-1,-2,0.00038632479845546186,4.5199999809265137 +1399,27000,0.00015814814832992852,-1,-2,0.00015814814832992852,4.2699999809265137 +1400,8600,0.00080232560867443681,-1,-2,0.00080232560867443681,6.9000000953674316 +1401,660,0.0011818181956186891,-1,-2,0.0011818181956186891,0.77999997138977051 +1402,10600,0.00013679245603270829,-1,-2,0.00013679245603270829,1.4500000476837158 +1403,0,inf,-1,-2,inf,1.6499999761581421 +1404,21800,0.0001389908284181729,-1,-2,0.0001389908284181729,3.0299999713897705 +1405,8300,0.00045542168663814664,-1,-2,0.00045542168663814664,3.7799999713897705 +1406,0,inf,-1,-2,inf,3.5799999237060547 +1407,9220,0.00033839477691799402,-1,-2,0.00033839477691799402,3.119999885559082 +1408,21700,5.6682027206989005e-05,-1,-2,5.6682027206989005e-05,1.2300000190734863 +1409,3900,0.00070769229205325246,-1,-2,0.00070769229205325246,2.7599999904632568 +1410,3900,0.0007487179827876389,-1,-2,0.0007487179827876389,2.9200000762939453 +1411,3500,0.00042285714880563319,-1,-2,0.00042285714880563319,1.4800000190734863 +1412,62500,2.9599999834317714e-05,-1,-2,2.9599999834317714e-05,1.8500000238418579 +1413,7700,0.0002454545465297997,-1,-2,0.0002454545465297997,1.8899999856948853 +1414,1804,0.0024833702482283115,-1,-2,0.0024833702482283115,4.4800000190734863 +1415,9900,0.00013131312152836472,-1,-2,0.00013131312152836472,1.2999999523162842 +1416,32500,6.4307692809961736e-05,-1,-2,6.4307692809961736e-05,2.0899999141693115 +1417,32400,0.00013179011875763535,-1,-2,0.00013179011875763535,4.2699999809265137 +1418,270000,1.5777779481140897e-05,-1,-2,1.5777779481140897e-05,4.2600002288818359 +1419,9100,0.00030329669243656099,-1,-2,0.00030329669243656099,2.7599999904632568 +1420,0,inf,-1,-2,inf,3.3599998950958252 +1421,0,inf,-1,-2,inf,3.7400000095367432 +1422,19670,0.00029639044078066945,-1,-2,0.00029639044078066945,5.8299999237060547 +1423,8300,0.00060843373648822308,-1,-2,0.00060843373648822308,5.0500001907348633 +1424,37000,5.0270271458430216e-05,-1,-2,5.0270271458430216e-05,1.8600000143051147 +1425,14000,9.6428571850992739e-05,-1,-2,9.6428571850992739e-05,1.3500000238418579 +1426,15200,0.00032302629551850259,-1,-2,0.00032302629551850259,4.9099998474121094 +1427,6430,0.00090046657714992762,-1,-2,0.00090046657714992762,5.7899999618530273 +1428,62000,6.8870969698764384e-05,-1,-2,6.8870969698764384e-05,4.2699999809265137 +1429,11200,0.00011607142369030043,-1,-2,0.00011607142369030043,1.2999999523162842 +1430,139230,1.9392373360460624e-05,-1,-2,1.9392373360460624e-05,2.7000000476837158 +1431,15000,0.00030066669569350779,-1,-2,0.00030066669569350779,4.5100002288818359 +1432,0,inf,-1,-2,inf,3.3299999237060547 +1433,0,inf,-1,-2,inf,4.3600001335144043 +1434,53700,3.0912477086530998e-05,-1,-2,3.0912477086530998e-05,1.6599999666213989 +1435,30000,5.6333334214286879e-05,-1,-2,5.6333334214286879e-05,1.690000057220459 +1436,7000,0.00050428573740646243,-1,-2,0.00050428573740646243,3.5299999713897705 +1437,35000,0.00010228571045445278,-1,-2,0.00010228571045445278,3.5799999237060547 +1438,122000,1.278688432648778e-05,-1,-2,1.278688432648778e-05,1.559999942779541 +1439,115000,3.5565219150157645e-05,-1,-2,3.5565219150157645e-05,4.0900001525878906 +1440,25000,0.00012280000373721123,-1,-2,0.00012280000373721123,3.0699999332427979 +1441,54800,5.4562042350880802e-05,-1,-2,5.4562042350880802e-05,2.9900000095367432 +1442,78500,5.6305732869077474e-05,-1,-2,5.6305732869077474e-05,4.4200000762939453 +1443,0,inf,-1,-2,inf,2.0099999904632568 +1444,29000,9.0344823547638953e-05,-1,-2,9.0344823547638953e-05,2.619999885559082 +1445,4908,0.00032192340586334467,-1,-2,0.00032192340586334467,1.5800000429153442 +1446,128200,1.3728548765357118e-05,-1,-2,1.3728548765357118e-05,1.7599999904632568 +1447,0,inf,-1,-2,inf,4.1999998092651367 +1448,23800,0.00011344537779223174,-1,-2,0.00011344537779223174,2.7000000476837158 +1449,21000,0.00019761905423365533,-1,-2,0.00019761905423365533,4.1500000953674316 +1450,14000,0.00019928571418859065,-1,-2,0.00019928571418859065,2.7899999618530273 +1451,30000,9.7333337180316448e-05,-1,-2,9.7333337180316448e-05,2.9200000762939453 +1452,44800,3.1249997846316546e-05,-1,-2,3.1249997846316546e-05,1.3999999761581421 +1453,18000,0.00023722222249489278,-1,-2,0.00023722222249489278,4.2699999809265137 +1454,0,inf,-1,-2,inf,3.5 +1455,20900,9.5693780167493969e-05,-1,-2,9.5693780167493969e-05,2 +1456,13900,0.00040215827175416052,-1,-2,0.00040215827175416052,5.5900001525878906 +1457,0,inf,-1,-2,inf,2.3199999332427979 +1458,8000,0.00034624998806975782,-1,-2,0.00034624998806975782,2.7699999809265137 +1459,0,inf,-1,-2,inf,4.7899999618530273 +1460,9400,0.00020106382726226002,-1,-2,0.00020106382726226002,1.8899999856948853 +1461,61000,7.2950817411765456e-05,-1,-2,7.2950817411765456e-05,4.4499998092651367 +1462,37000,0.00012270269508007914,-1,-2,0.00012270269508007914,4.5399999618530273 +1463,43000,3.2558138627791777e-05,-1,-2,3.2558138627791777e-05,1.3999999761581421 +1464,27600,0.0001123188339988701,-1,-2,0.0001123188339988701,3.0999999046325684 +1465,15000,0.00033733333111740649,-1,-2,0.00033733333111740649,5.059999942779541 +1466,149000,1.4026844837644603e-05,-1,-2,1.4026844837644603e-05,2.0899999141693115 +1467,0,inf,-1,-2,inf,3.75 +1468,28000,0.00017678570293355733,-1,-2,0.00017678570293355733,4.9499998092651367 +1469,20000,0.00014600000577047467,-1,-2,0.00014600000577047467,2.9200000762939453 +1470,14800,0.00037297297967597842,-1,-2,0.00037297297967597842,5.5199999809265137 +1471,0,inf,-1,-2,inf,2.9500000476837158 +1472,350000,4.8571428123977967e-06,-1,-2,4.8571428123977967e-06,1.7000000476837158 +1473,16400,0.00019878048624377698,-1,-2,0.00019878048624377698,3.2599999904632568 +1474,30300,0.00012343234266154468,-1,-2,0.00012343234266154468,3.7400000095367432 +1475,0,inf,-1,-2,inf,4.369999885559082 +1476,365300,9.1979190983693115e-06,-1,-2,9.1979190983693115e-06,3.3599998950958252 +1477,242500,1.5298968719434924e-05,-1,-2,1.5298968719434924e-05,3.7100000381469727 +1478,16800,0.00023511904873885214,-1,-2,0.00023511904873885214,3.9500000476837158 +1479,0,inf,-1,-2,inf,1.3500000238418579 +1480,0,inf,-1,-2,inf,1.2400000095367432 +1481,99160,3.4086326195392758e-05,-1,-2,3.4086326195392758e-05,3.380000114440918 +1482,35030,0.00011989722406724468,-1,-2,0.00011989722406724468,4.1999998092651367 +1483,0,inf,-1,-2,inf,3.0699999332427979 +1484,8300,0.00016265059821307659,-1,-2,0.00016265059821307659,1.3500000238418579 +1485,41550,0.00010878459579544142,-1,-2,0.00010878459579544142,4.5199999809265137 +1486,13900,0.00030431654886342585,-1,-2,0.00030431654886342585,4.2300000190734863 +1487,147200,3.0570652597816661e-05,-1,-2,3.0570652597816661e-05,4.5 +1488,0,inf,-1,-2,inf,2.9700000286102295 +1489,133000,2.5112782168434933e-05,-1,-2,2.5112782168434933e-05,3.3399999141693115 +1490,7800,0.00043333333451300859,-1,-2,0.00043333333451300859,3.380000114440918 +1491,12000,6.4166662923526019e-05,-1,-2,6.4166662923526019e-05,0.76999998092651367 +1492,16200,0.00021543209732044488,-1,-2,0.00021543209732044488,3.4900000095367432 +1493,417400,1.3560133993451018e-05,-1,-2,1.3560133993451018e-05,5.6599998474121094 +1494,23700,8.396624616580084e-05,-1,-2,8.396624616580084e-05,1.9900000095367432 +1495,8000,0.00044124998385086656,-1,-2,0.00044124998385086656,3.5299999713897705 +1496,0,inf,-1,-2,inf,4 +1497,414000,4.5652172957488801e-06,-1,-2,4.5652172957488801e-06,1.8899999856948853 +1498,70000,2.6000001525972039e-05,-1,-2,2.6000001525972039e-05,1.8200000524520874 +1499,35000,0.00017857142665889114,-1,-2,0.00017857142665889114,6.25 +1500,33000,0.00010090909199789166,-1,-2,0.00010090909199789166,3.3299999237060547 +1501,61800,4.4012944272253662e-05,-1,-2,4.4012944272253662e-05,2.7200000286102295 +1502,4000,0.0010000000474974513,-1,-2,0.0010000000474974513,4 +1503,141200,1.8838527466868982e-05,-1,-2,1.8838527466868982e-05,2.6600000858306885 +1504,10000,0.00058799999533221126,-1,-2,0.00058799999533221126,5.880000114440918 +1505,0,inf,-1,-2,inf,0.44999998807907104 +1506,0,inf,-1,-2,inf,5.690000057220459 +1507,160800,1.9154227629769593e-05,-1,-2,1.9154227629769593e-05,3.0799999237060547 +1508,97000,4.7835048462729901e-05,-1,-2,4.7835048462729901e-05,4.6399998664855957 +1509,0,inf,-1,-2,inf,3.7000000476837158 +1510,0,inf,-1,-2,inf,2.6500000953674316 +1511,25000,0.00010840000322787091,-1,-2,0.00010840000322787091,2.7100000381469727 +1512,0,inf,-1,-2,inf,4.4099998474121094 +1513,39700,6.9521411205641925e-05,-1,-2,6.9521411205641925e-05,2.7599999904632568 +1514,133000,2.3082706320565194e-05,-1,-2,2.3082706320565194e-05,3.0699999332427979 +1515,5000,0.0010580000234767795,-1,-2,0.0010580000234767795,5.2899999618530273 +1516,45000,1.9111112123937346e-05,-1,-2,1.9111112123937346e-05,0.86000001430511475 +1517,6000,0.00057333335280418396,-1,-2,0.00057333335280418396,3.440000057220459 +1518,20100,0.00023034826153889298,-1,-2,0.00023034826153889298,4.630000114440918 +1519,165000,1.703030284261331e-05,-1,-2,1.703030284261331e-05,2.809999942779541 +1520,15400,0.00038246752228587866,-1,-2,0.00038246752228587866,5.8899998664855957 +1521,57500,7.1478265454061329e-05,-1,-2,7.1478265454061329e-05,4.1100001335144043 +1522,193000,5.0259068302693777e-06,-1,-2,5.0259068302693777e-06,0.97000002861022949 +1523,10000,0.00045300001511350274,-1,-2,0.00045300001511350274,4.5300002098083496 +1524,50000,6.5200001699849963e-05,-1,-2,6.5200001699849963e-05,3.2599999904632568 +1525,0,inf,-1,-2,inf,2.9200000762939453 +1526,0,inf,-1,-2,inf,1.6399999856948853 +1527,11000,0.0002545454481150955,-1,-2,0.0002545454481150955,2.7999999523162842 +1528,26030,8.2212834968231618e-05,-1,-2,8.2212834968231618e-05,2.1400001049041748 +1529,223900,2.4162571207853034e-05,-1,-2,2.4162571207853034e-05,5.4099998474121094 +1530,49000,8.4693878307007253e-05,-1,-2,8.4693878307007253e-05,4.1500000953674316 +1531,0,inf,-1,-2,inf,3.6400001049041748 +1532,18500,5.3513515013037249e-05,-1,-2,5.3513515013037249e-05,0.99000000953674316 +1533,205400,1.7624148313188925e-05,-1,-2,1.7624148313188925e-05,3.619999885559082 +1534,140720,1.8618531612446532e-05,-1,-2,1.8618531612446532e-05,2.619999885559082 +1535,15000,0.00035600000410340726,-1,-2,0.00035600000410340726,5.3400001525878906 +1536,20900,0.00010382775508332998,-1,-2,0.00010382775508332998,2.1700000762939453 +1537,19400,0.00020670103549491614,-1,-2,0.00020670103549491614,4.0100002288818359 +1538,24900,0.00011887550499523059,-1,-2,0.00011887550499523059,2.9600000381469727 +1539,58000,3.2931035093497485e-05,-1,-2,3.2931035093497485e-05,1.9099999666213989 +1540,100000,2.680000034160912e-05,-1,-2,2.680000034160912e-05,2.6800000667572021 +1541,63000,1.2380952284729574e-05,-1,-2,1.2380952284729574e-05,0.77999997138977051 +1542,29200,0.00010445205407449976,-1,-2,0.00010445205407449976,3.0499999523162842 +1543,57500,0.00010139130608877167,-1,-2,0.00010139130608877167,5.8299999237060547 +1544,45600,0.00010350876982556656,-1,-2,0.00010350876982556656,4.7199997901916504 +1545,346000,1.5982659533619881e-05,-1,-2,1.5982659533619881e-05,5.5300002098083496 +1546,22700,6.9603527663275599e-05,-1,-2,6.9603527663275599e-05,1.5800000429153442 +1547,182500,1.8465752873453312e-05,-1,-2,1.8465752873453312e-05,3.369999885559082 +1548,24000,6.2083330703899264e-05,-1,-2,6.2083330703899264e-05,1.4900000095367432 +1549,43600,5.206422065384686e-05,-1,-2,5.206422065384686e-05,2.2699999809265137 +1550,35400,4.7175140934996307e-05,-1,-2,4.7175140934996307e-05,1.6699999570846558 +1551,56000,5.5357140809064731e-05,-1,-2,5.5357140809064731e-05,3.0999999046325684 +1552,22000,0.00021681818179786205,-1,-2,0.00021681818179786205,4.7699999809265137 +1553,58050,3.7037039874121547e-05,-1,-2,3.7037039874121547e-05,2.1500000953674316 +1554,14500,0.00018551724497228861,-1,-2,0.00018551724497228861,2.690000057220459 +1555,14500,0.00012896551925223321,-1,-2,0.00012896551925223321,1.8700000047683716 +1556,70920,8.0231249739881605e-05,-1,-2,8.0231249739881605e-05,5.690000057220459 +1557,0,inf,-1,-2,inf,3.0799999237060547 +1558,25400,0.0001625984295969829,-1,-2,0.0001625984295969829,4.130000114440918 +1559,0,inf,-1,-2,inf,5.8899998664855957 +1560,14100,0.00032411349820904434,-1,-2,0.00032411349820904434,4.570000171661377 +1561,0,inf,-1,-2,inf,4.0500001907348633 +1562,9100,0.00037582419463433325,-1,-2,0.00037582419463433325,3.4200000762939453 +1563,9600,0.00054895831272006035,-1,-2,0.00054895831272006035,5.2699999809265137 +1564,19700,5.2791874622926116e-05,-1,-2,5.2791874622926116e-05,1.0399999618530273 +1565,0,inf,-1,-2,inf,2.7599999904632568 +1566,65000,6.3538464019075036e-05,-1,-2,6.3538464019075036e-05,4.130000114440918 +1567,0,inf,-1,-2,inf,2.0799999237060547 +1568,6000,0.0012266667326912284,-1,-2,0.0012266667326912284,7.3600001335144043 +1569,87000,4.7471265133935958e-05,-1,-2,4.7471265133935958e-05,4.130000114440918 +1570,24700,0.00011821862426586449,-1,-2,0.00011821862426586449,2.9200000762939453 +1571,0,inf,-1,-2,inf,2.2699999809265137 +1572,8680,0.00058179727056995034,-1,-2,0.00058179727056995034,5.0500001907348633 +1573,45000,7.3777773650363088e-05,-1,-2,7.3777773650363088e-05,3.3199999332427979 +1574,22500,0.00019688888278324157,-1,-2,0.00019688888278324157,4.429999828338623 +1575,48500,8.8659799075685441e-05,-1,-2,8.8659799075685441e-05,4.3000001907348633 +1576,8500,0.00018117646686732769,-1,-2,0.00018117646686732769,1.5399999618530273 +1577,108000,4.5000000682193786e-05,-1,-2,4.5000000682193786e-05,4.8600001335144043 +1578,177000,2.3446327759302221e-05,-1,-2,2.3446327759302221e-05,4.1500000953674316 +1579,14300,0.00029930070741102099,-1,-2,0.00029930070741102099,4.2800002098083496 +1580,48000,8.1250000221189111e-06,-1,-2,8.1250000221189111e-06,0.38999998569488525 +1581,0,inf,-1,-2,inf,0.33000001311302185 +1582,12000,0.00031583334202878177,-1,-2,0.00031583334202878177,3.7899999618530273 +1583,4000,0.00065000000176951289,-1,-2,0.00065000000176951289,2.5999999046325684 +1584,388000,5.5412374422303401e-06,-1,-2,5.5412374422303401e-06,2.1500000953674316 +1585,59800,3.6287627153797075e-05,-1,-2,3.6287627153797075e-05,2.1700000762939453 +1586,59800,3.6622073821490631e-05,-1,-2,3.6622073821490631e-05,2.190000057220459 +1587,48000,4.4166663428768516e-05,-1,-2,4.4166663428768516e-05,2.119999885559082 +1588,24000,0.00016916666936594993,-1,-2,0.00016916666936594993,4.059999942779541 +1589,41960,2.9313632694538683e-05,-1,-2,2.9313632694538683e-05,1.2300000190734863 +1590,13900,0.00023021582455839962,-1,-2,0.00023021582455839962,3.2000000476837158 +1591,30000,0.00023833333398215473,-1,-2,0.00023833333398215473,7.1500000953674316 +1592,58000,3.6379307857714593e-05,-1,-2,3.6379307857714593e-05,2.1099998950958252 +1593,1700,0.0020176470279693604,-1,-2,0.0020176470279693604,3.4300000667572021 +1594,8100,0.00043703702976927161,-1,-2,0.00043703702976927161,3.5399999618530273 +1595,326700,5.7239058151026256e-06,-1,-2,5.7239058151026256e-06,1.8700000047683716 +1596,23000,0.00015478261047974229,-1,-2,0.00015478261047974229,3.559999942779541 +1597,9800,0.00046224490506574512,-1,-2,0.00046224490506574512,4.5300002098083496 +1598,81980,5.5379361583618447e-05,-1,-2,5.5379361583618447e-05,4.5399999618530273 +1599,19000,0.00018105263006873429,-1,-2,0.00018105263006873429,3.440000057220459 +1600,8300,0.00025301202549599111,-1,-2,0.00025301202549599111,2.0999999046325684 +1601,5800,0.00086034479318186641,-1,-2,0.00086034479318186641,4.9899997711181641 +1602,22100,6.1085971537977457e-05,-1,-2,6.1085971537977457e-05,1.3500000238418579 +1603,7400,0.00022432432160712779,-1,-2,0.00022432432160712779,1.6599999666213989 +1604,6000,0.00045000002137385309,-1,-2,0.00045000002137385309,2.7000000476837158 +1605,61500,9.2845526523888111e-05,-1,-2,9.2845526523888111e-05,5.7100000381469727 +1606,18900,0.00013703703007195145,-1,-2,0.00013703703007195145,2.5899999141693115 +1607,26060,0.00020644666801672429,-1,-2,0.00020644666801672429,5.380000114440918 +1608,0,inf,-1,-2,inf,4.690000057220459 +1609,462000,5.6493504416721407e-06,-1,-2,5.6493504416721407e-06,2.6099998950958252 +1610,0,inf,-1,-2,inf,3.0799999237060547 +1611,10900,0.0002376146730966866,-1,-2,0.0002376146730966866,2.5899999141693115 +1612,10000,0.00049100001342594624,-1,-2,0.00049100001342594624,4.9099998474121094 +1613,20000,0.0001720000000204891,-1,-2,0.0001720000000204891,3.440000057220459 +1614,8700,0.00035057470086030662,-1,-2,0.00035057470086030662,3.0499999523162842 +1615,8300,0.00036506023025140166,-1,-2,0.00036506023025140166,3.0299999713897705 +1616,13500,0.00022962962975725532,-1,-2,0.00022962962975725532,3.0999999046325684 +1617,103000,3.4077671443810686e-05,-1,-2,3.4077671443810686e-05,3.5099999904632568 +1618,61000,7.3606555815786123e-05,-1,-2,7.3606555815786123e-05,4.4899997711181641 +1619,17800,0.00023202247393783182,-1,-2,0.00023202247393783182,4.130000114440918 +1620,8500,0.00039058821857906878,-1,-2,0.00039058821857906878,3.3199999332427979 +1621,4200,0.00079761905362829566,-1,-2,0.00079761905362829566,3.3499999046325684 +1622,12000,0.00017750001279637218,-1,-2,0.00017750001279637218,2.130000114440918 +1623,99700,3.3901706046890467e-05,-1,-2,3.3901706046890467e-05,3.380000114440918 +1624,41900,6.6109787439927459e-05,-1,-2,6.6109787439927459e-05,2.7699999809265137 +1625,23000,0.00019869566312991083,-1,-2,0.00019869566312991083,4.570000171661377 +1626,910,0.0030439561232924461,-1,-2,0.0030439561232924461,2.7699999809265137 +1627,7000,0.00063285714713856578,-1,-2,0.00063285714713856578,4.429999828338623 +1628,11500,0.00019739130220841616,-1,-2,0.00019739130220841616,2.2699999809265137 +1629,184900,1.0546241355768871e-05,-1,-2,1.0546241355768871e-05,1.9500000476837158 +1630,22600,6.5486725361552089e-05,-1,-2,6.5486725361552089e-05,1.4800000190734863 +1631,19180,0.00028779980493709445,-1,-2,0.00028779980493709445,5.5199999809265137 +1632,5350,0.00056635512737557292,-1,-2,0.00056635512737557292,3.0299999713897705 +1633,0,inf,-1,-2,inf,5.8400001525878906 +1634,74200,3.2884097890928388e-05,-1,-2,3.2884097890928388e-05,2.440000057220459 +1635,206800,1.3346228115551639e-05,-1,-2,1.3346228115551639e-05,2.7599999904632568 +1636,137000,2.1021898646722548e-05,-1,-2,2.1021898646722548e-05,2.880000114440918 +1637,23100,9.1774883912876248e-05,-1,-2,9.1774883912876248e-05,2.119999885559082 +1638,5500,0.00054181821178644896,-1,-2,0.00054181821178644896,2.9800000190734863 +1639,28900,1.557093310111668e-05,-1,-2,1.557093310111668e-05,0.44999998807907104 +1640,44050,9.7162323072552681e-05,-1,-2,9.7162323072552681e-05,4.2800002098083496 +1641,0,inf,-1,-2,inf,3.7400000095367432 +1642,0,inf,-1,-2,inf,4.0399999618530273 +1643,29000,5.1034483476541936e-05,-1,-2,5.1034483476541936e-05,1.4800000190734863 +1644,117000,2.0085470168851316e-05,-1,-2,2.0085470168851316e-05,2.3499999046325684 +1645,23000,7.2173912485595793e-05,-1,-2,7.2173912485595793e-05,1.6599999666213989 +1646,18000,8.4999999671708792e-05,-1,-2,8.4999999671708792e-05,1.5299999713897705 +1647,0,inf,-1,-2,inf,0.81000000238418579 +1648,14900,0.0003067114157602191,-1,-2,0.0003067114157602191,4.570000171661377 +1649,0,inf,-1,-2,inf,2.5999999046325684 +1650,0,inf,-1,-2,inf,3.3299999237060547 +1651,7170,0.00043235701741650701,-1,-2,0.00043235701741650701,3.0999999046325684 +1652,8300,0.00038313254481181502,-1,-2,0.00038313254481181502,3.1800000667572021 +1653,0,inf,-1,-2,inf,4.5999999046325684 +1654,0,inf,-1,-2,inf,2.7599999904632568 +1655,5000,6.6000000515487045e-05,-1,-2,6.6000000515487045e-05,0.33000001311302185 +1656,10600,0.00053773581748828292,-1,-2,0.00053773581748828292,5.6999998092651367 +1657,116000,5.3879310144111514e-05,-1,-2,5.3879310144111514e-05,6.25 +1658,68000,4.5735290768789127e-05,-1,-2,4.5735290768789127e-05,3.1099998950958252 +1659,428000,8.7383177742594853e-06,-1,-2,8.7383177742594853e-06,3.7400000095367432 +1660,20000,2.5999999706982635e-05,-1,-2,2.5999999706982635e-05,0.51999998092651367 +1661,77970,6.3485953432973474e-05,-1,-2,6.3485953432973474e-05,4.9499998092651367 +1662,15900,0.00022075472224969417,-1,-2,0.00022075472224969417,3.5099999904632568 +1663,81980,4.1229570342693478e-05,-1,-2,4.1229570342693478e-05,3.380000114440918 +1664,24000,4.3749998440034688e-05,-1,-2,4.3749998440034688e-05,1.0499999523162842 +1665,136600,3.1918010790832341e-05,-1,-2,3.1918010790832341e-05,4.3600001335144043 +1666,0,inf,-1,-2,inf,1.8500000238418579 +1667,0,inf,-1,-2,inf,4.8499999046325684 +1668,0,inf,-1,-2,inf,5.4099998474121094 +1669,7000,0.00063428573776036501,-1,-2,0.00063428573776036501,4.440000057220459 +1670,8500,0.00063294119900092483,-1,-2,0.00063294119900092483,5.380000114440918 +1671,11000,0.00013454545114655048,-1,-2,0.00013454545114655048,1.4800000190734863 +1672,14800,0.00014797298354096711,-1,-2,0.00014797298354096711,2.190000057220459 +1673,81980,2.2566480765817687e-05,-1,-2,2.2566480765817687e-05,1.8500000238418579 +1674,14700,0.00037346937460824847,-1,-2,0.00037346937460824847,5.4899997711181641 +1675,35300,0.00010481586650712416,-1,-2,0.00010481586650712416,3.7000000476837158 +1676,0,inf,-1,-2,inf,2.619999885559082 +1677,8300,0.00021807228040415794,-1,-2,0.00021807228040415794,1.809999942779541 +1678,38000,0.00010368421499151736,-1,-2,0.00010368421499151736,3.940000057220459 +1679,112000,2.8035714422003366e-05,-1,-2,2.8035714422003366e-05,3.1400001049041748 +1680,6200,0.00069032260216772556,-1,-2,0.00069032260216772556,4.2800002098083496 +1681,120050,1.374427301925607e-05,-1,-2,1.374427301925607e-05,1.6499999761581421 +1682,131000,4.0763359720585868e-05,-1,-2,4.0763359720585868e-05,5.3400001525878906 +1683,0,inf,-1,-2,inf,4.0199999809265137 +1684,29000,5.6551722082076594e-05,-1,-2,5.6551722082076594e-05,1.6399999856948853 +1685,4900,0.00076530611841008067,-1,-2,0.00076530611841008067,3.75 +1686,8500,0.00050235295202583075,-1,-2,0.00050235295202583075,4.2699999809265137 +1687,78500,2.4840765036060475e-05,-1,-2,2.4840765036060475e-05,1.9500000476837158 +1688,26050,0.00016545105609111488,-1,-2,0.00016545105609111488,4.309999942779541 +1689,0,inf,-1,-2,inf,4.4000000953674316 +1690,8100,0.00049629627028480172,-1,-2,0.00049629627028480172,4.0199999809265137 +1691,65000,4.8307694669347256e-05,-1,-2,4.8307694669347256e-05,3.1400001049041748 +1692,0,inf,-1,-2,inf,4.9800000190734863 +1693,177000,3.0225988666643389e-05,-1,-2,3.0225988666643389e-05,5.3499999046325684 +1694,119700,1.5622388673364185e-05,-1,-2,1.5622388673364185e-05,1.8700000047683716 +1695,55200,2.952898466901388e-05,-1,-2,2.952898466901388e-05,1.6299999952316284 +1696,13500,0.00030222220811992884,-1,-2,0.00030222220811992884,4.0799999237060547 +1697,74100,1.6734144082874991e-05,-1,-2,1.6734144082874991e-05,1.2400000095367432 +1698,90000,3.8222224247874692e-05,-1,-2,3.8222224247874692e-05,3.440000057220459 +1699,365300,9.0884204837493598e-06,-1,-2,9.0884204837493598e-06,3.3199999332427979 +1700,1804,0.0018736142665147781,-1,-2,0.0018736142665147781,3.380000114440918 +1701,133480,2.4647886675666086e-05,-1,-2,2.4647886675666086e-05,3.2899999618530273 +1702,414000,1.0096618098032195e-05,-1,-2,1.0096618098032195e-05,4.179999828338623 +1703,173100,2.3627961127203889e-05,-1,-2,2.3627961127203889e-05,4.0900001525878906 +1704,50000,1.2399999832268804e-05,-1,-2,1.2399999832268804e-05,0.62000000476837158 +1705,38000,0.00010578946967143565,-1,-2,0.00010578946967143565,4.0199999809265137 +1706,13900,0.00044748198706656694,-1,-2,0.00044748198706656694,6.2199997901916504 +1707,25500,0.00014784313680138439,-1,-2,0.00014784313680138439,3.7699999809265137 +1708,57300,1.8848168110707775e-05,-1,-2,1.8848168110707775e-05,1.0800000429153442 +1709,51000,9.7058822575490922e-05,-1,-2,9.7058822575490922e-05,4.9499998092651367 +1710,13500,0.00019333332602400333,-1,-2,0.00019333332602400333,2.6099998950958252 +1711,42100,0.00010308789205737412,-1,-2,0.00010308789205737412,4.3400001525878906 +1712,0,inf,-1,-2,inf,6.25 +1713,8300,0.00032650603679940104,-1,-2,0.00032650603679940104,2.7100000381469727 +1714,0,inf,-1,-2,inf,3.8199999332427979 +1715,75000,5.4266667575575411e-05,-1,-2,5.4266667575575411e-05,4.070000171661377 +1716,148800,3.3938173146452755e-05,-1,-2,3.3938173146452755e-05,5.0500001907348633 +1717,39700,8.5390427557285875e-05,-1,-2,8.5390427557285875e-05,3.3900001049041748 +1718,63000,5.5873017117846757e-05,-1,-2,5.5873017117846757e-05,3.5199999809265137 +1719,77600,3.1185569241642952e-05,-1,-2,3.1185569241642952e-05,2.4200000762939453 +1720,220000,2.1863635993213393e-05,-1,-2,2.1863635993213393e-05,4.809999942779541 +1721,26050,0.00011247600923525169,-1,-2,0.00011247600923525169,2.9300000667572021 +1722,45000,1.8000000636675395e-05,-1,-2,1.8000000636675395e-05,0.81000000238418579 +1723,28000,0.00018535714480094612,-1,-2,0.00018535714480094612,5.190000057220459 +1724,60000,5.6333334214286879e-05,-1,-2,5.6333334214286879e-05,3.380000114440918 +1725,18000,0.00012166667147539556,-1,-2,0.00012166667147539556,2.190000057220459 +1726,182500,2.1479452698258683e-05,-1,-2,2.1479452698258683e-05,3.9200000762939453 +1727,4200,0.0007309523643925786,-1,-2,0.0007309523643925786,3.0699999332427979 +1728,32000,1.2500000593718141e-05,-1,-2,1.2500000593718141e-05,0.40000000596046448 +1729,200000,2.0250001398380846e-05,-1,-2,2.0250001398380846e-05,4.0500001907348633 +1730,97000,3.1958763429429382e-05,-1,-2,3.1958763429429382e-05,3.0999999046325684 +1731,1700,0.0034294116776436567,-1,-2,0.0034294116776436567,5.8299999237060547 +1732,30000,0.00012166667147539556,-1,-2,0.00012166667147539556,3.6500000953674316 +1733,17670,0.00017657045100349933,-1,-2,0.00017657045100349933,3.119999885559082 +1734,0,inf,-1,-2,inf,4.820000171661377 +1735,109500,2.045662040472962e-05,-1,-2,2.045662040472962e-05,2.2400000095367432 +1736,4000,0.00037999998312443495,-1,-2,0.00037999998312443495,1.5199999809265137 +1737,27700,0.0001072202212526463,-1,-2,0.0001072202212526463,2.9700000286102295 +1738,58000,8.1206897448282689e-05,-1,-2,8.1206897448282689e-05,4.7100000381469727 +1739,144000,2.6944444471155293e-05,-1,-2,2.6944444471155293e-05,3.880000114440918 +1740,29020,9.0282563178334385e-05,-1,-2,9.0282563178334385e-05,2.619999885559082 +1741,46400,5.1293107389938086e-05,-1,-2,5.1293107389938086e-05,2.380000114440918 +1742,45000,6.2666666053701192e-05,-1,-2,6.2666666053701192e-05,2.8199999332427979 +1743,9600,0.00057708332315087318,-1,-2,0.00057708332315087318,5.5399999618530273 +1744,76100,3.3771353628253564e-05,-1,-2,3.3771353628253564e-05,2.5699999332427979 +1745,101000,5.0297028792556375e-05,-1,-2,5.0297028792556375e-05,5.0799999237060547 +1746,36000,0.00010277777619194239,-1,-2,0.00010277777619194239,3.7000000476837158 +1747,128200,1.0842433766811155e-05,-1,-2,1.0842433766811155e-05,1.3899999856948853 +1748,12600,0.00020634919928852469,-1,-2,0.00020634919928852469,2.5999999046325684 +1749,37000,0.00010108108108397573,-1,-2,0.00010108108108397573,3.7400000095367432 +1750,69700,4.0602582885185257e-05,-1,-2,4.0602582885185257e-05,2.8299999237060547 +1751,8400,0.00086666666902601719,-1,-2,0.00086666666902601719,7.2800002098083496 +1752,0,inf,-1,-2,inf,5.059999942779541 +1753,106120,9.988691090256907e-06,-1,-2,9.988691090256907e-06,1.059999942779541 +1754,325014,1.3907093489251565e-05,-1,-2,1.3907093489251565e-05,4.5199999809265137 +1755,20000,0.00010700000711949542,-1,-2,0.00010700000711949542,2.1400001049041748 +1756,52800,3.2386364182457328e-05,-1,-2,3.2386364182457328e-05,1.7100000381469727 +1757,130000,4.0769227780401707e-06,-1,-2,4.0769227780401707e-06,0.52999997138977051 +1758,66300,2.232277620350942e-05,-1,-2,2.232277620350942e-05,1.4800000190734863 +1759,8300,0.00064819277031347156,-1,-2,0.00064819277031347156,5.380000114440918 +1760,143000,3.8881116779521108e-05,-1,-2,3.8881116779521108e-05,5.559999942779541 +1761,0,inf,-1,-2,inf,2.0099999904632568 +1762,59220,4.9476529966341332e-05,-1,-2,4.9476529966341332e-05,2.9300000667572021 +1763,8100,0.00055555556900799274,-1,-2,0.00055555556900799274,4.5 +1764,45000,0.0001295555557589978,-1,-2,0.0001295555557589978,5.8299999237060547 +1765,100000,5.7600002037361264e-05,-1,-2,5.7600002037361264e-05,5.7600002288818359 +1766,6200,0.00054516131058335304,-1,-2,0.00054516131058335304,3.380000114440918 +1767,8300,0.00046987953828647733,-1,-2,0.00046987953828647733,3.9000000953674316 +1768,0,inf,-1,-2,inf,3.4900000095367432 +1769,270000,3.6296296457294375e-06,-1,-2,3.6296296457294375e-06,0.98000001907348633 +1770,14500,0.00011448275472503155,-1,-2,0.00011448275472503155,1.6599999666213989 +1771,52000,5.2692306780954823e-05,-1,-2,5.2692306780954823e-05,2.7400000095367432 +1772,30480,7.3818897362798452e-05,-1,-2,7.3818897362798452e-05,2.25 +1773,65600,4.5884145947638899e-05,-1,-2,4.5884145947638899e-05,3.0099999904632568 +1774,37700,3.4482756746001542e-05,-1,-2,3.4482756746001542e-05,1.2999999523162842 +1775,59800,3.4615382901392877e-05,-1,-2,3.4615382901392877e-05,2.0699999332427979 +1776,102160,5.2858263188682031e-06,-1,-2,5.2858263188682031e-06,0.54000002145767212 +1777,24600,0.00015406504098791629,-1,-2,0.00015406504098791629,3.7899999618530273 +1778,40000,6.9000001531094313e-05,-1,-2,6.9000001531094313e-05,2.7599999904632568 +1779,114000,7.1052631938073318e-06,-1,-2,7.1052631938073318e-06,0.81000000238418579 +1780,30800,6.5259737311862409e-05,-1,-2,6.5259737311862409e-05,2.0099999904632568 +1781,95000,3.3263157092733309e-05,-1,-2,3.3263157092733309e-05,3.1600000858306885 +1782,70300,3.2290183298755437e-05,-1,-2,3.2290183298755437e-05,2.2699999809265137 +1783,14000,0.00042571430094540119,-1,-2,0.00042571430094540119,5.9600000381469727 +1784,73410,6.824683805461973e-05,-1,-2,6.824683805461973e-05,5.0100002288818359 +1785,109500,2.045662040472962e-05,-1,-2,2.045662040472962e-05,2.2400000095367432 +1786,8100,0.00023086419969331473,-1,-2,0.00023086419969331473,1.8700000047683716 +1787,0,inf,-1,-2,inf,3.0299999713897705 +1788,6500,0.00063538464019075036,-1,-2,0.00063538464019075036,4.130000114440918 +1789,50000,5.9400001191534102e-05,-1,-2,5.9400001191534102e-05,2.9700000286102295 +1790,65600,6.432926602428779e-05,-1,-2,6.432926602428779e-05,4.2199997901916504 +1791,61060,3.9960694266483188e-05,-1,-2,3.9960694266483188e-05,2.440000057220459 +1792,53300,3.0956845876062289e-05,-1,-2,3.0956845876062289e-05,1.6499999761581421 +1793,36000,8.9166664110962301e-05,-1,-2,8.9166664110962301e-05,3.2100000381469727 +1794,75000,5.5466665799031034e-05,-1,-2,5.5466665799031034e-05,4.1599998474121094 +1795,11400,0.0003394736850168556,-1,-2,0.0003394736850168556,3.869999885559082 +1796,28000,0.0001475000026402995,-1,-2,0.0001475000026402995,4.130000114440918 +1797,24000,0.00013791666424367577,-1,-2,0.00013791666424367577,3.309999942779541 +1798,64000,6.687499990221113e-05,-1,-2,6.687499990221113e-05,4.2800002098083496 +1799,26640,5.8183180954074487e-05,-1,-2,5.8183180954074487e-05,1.5499999523162842 +1800,13700,0.00012846715981140733,-1,-2,0.00012846715981140733,1.7599999904632568 +1801,11000,0.00037000002339482307,-1,-2,0.00037000002339482307,4.070000171661377 +1802,0,inf,-1,-2,inf,2.7999999523162842 +1803,23100,0.00018095236737281084,-1,-2,0.00018095236737281084,4.179999828338623 +1804,10000,0.00021800000104121864,-1,-2,0.00021800000104121864,2.1800000667572021 +1805,117000,2.7094018150819466e-05,-1,-2,2.7094018150819466e-05,3.1700000762939453 +1806,20000,8.0500001786276698e-05,-1,-2,8.0500001786276698e-05,1.6100000143051147 +1807,8300,0.00036506023025140166,-1,-2,0.00036506023025140166,3.0299999713897705 +1808,25800,0.00010077519254991785,-1,-2,0.00010077519254991785,2.5999999046325684 +1809,0,inf,-1,-2,inf,3.9200000762939453 +1810,8300,0.00039999998989515007,-1,-2,0.00039999998989515007,3.3199999332427979 +1811,14500,0.00029793105204589665,-1,-2,0.00029793105204589665,4.320000171661377 +1812,26000,0.0001930769212776795,-1,-2,0.0001930769212776795,5.0199999809265137 +1813,27800,5.3597123041981831e-05,-1,-2,5.3597123041981831e-05,1.4900000095367432 +1814,14800,0.0004662162100430578,-1,-2,0.0004662162100430578,6.9000000953674316 +1815,16200,0.00014135801757220179,-1,-2,0.00014135801757220179,2.2899999618530273 +1816,73500,1.8095239283866249e-05,-1,-2,1.8095239283866249e-05,1.3300000429153442 +1817,8420,0.00035510689485818148,-1,-2,0.00035510689485818148,2.9900000095367432 +1818,0,inf,-1,-2,inf,2.7699999809265137 +1819,14000,0.00014999999257270247,-1,-2,0.00014999999257270247,2.0999999046325684 +1820,23400,0.00018461539002601057,-1,-2,0.00018461539002601057,4.320000171661377 +1821,0,inf,-1,-2,inf,4.2199997901916504 +1822,377200,1.1320254088786896e-05,-1,-2,1.1320254088786896e-05,4.2699999809265137 +1823,18800,0.00021382978593464941,-1,-2,0.00021382978593464941,4.0199999809265137 +1824,0,inf,-1,-2,inf,3.0999999046325684 +1825,25800,0.00030775193590670824,-1,-2,0.00030775193590670824,7.940000057220459 +1826,37700,7.0291782321874052e-05,-1,-2,7.0291782321874052e-05,2.6500000953674316 +1827,62050,5.0765513151418418e-05,-1,-2,5.0765513151418418e-05,3.1500000953674316 +1828,57500,5.5478263675468042e-05,-1,-2,5.5478263675468042e-05,3.190000057220459 +1829,36020,0.0001740699663059786,-1,-2,0.0001740699663059786,6.2699999809265137 +1830,34300,1.5743440599180758e-05,-1,-2,1.5743440599180758e-05,0.54000002145767212 +1831,13000,0.00021923075837548822,-1,-2,0.00021923075837548822,2.8499999046325684 +1832,30000,0.00010233333159703761,-1,-2,0.00010233333159703761,3.0699999332427979 +1833,326750,5.4169854593055788e-06,-1,-2,5.4169854593055788e-06,1.7699999809265137 +1834,46400,2.8879310775664635e-05,-1,-2,2.8879310775664635e-05,1.3400000333786011 +1835,0,inf,-1,-2,inf,2.7699999809265137 +1836,64000,5.906249862164259e-05,-1,-2,5.906249862164259e-05,3.7799999713897705 +1837,25100,0.00016294821398332715,-1,-2,0.00016294821398332715,4.0900001525878906 +1838,2400,0.0011291666887700558,-1,-2,0.0011291666887700558,2.7100000381469727 +1839,29500,0.00014406780246645212,-1,-2,0.00014406780246645212,4.25 +1840,51000,3.54901967511978e-05,-1,-2,3.54901967511978e-05,1.809999942779541 +1841,0,inf,-1,-2,inf,4.809999942779541 +1842,7700,0.00040519479080103338,-1,-2,0.00040519479080103338,3.119999885559082 +1843,0,inf,-1,-2,inf,5.8899998664855957 +1844,10300,0.00028932039276696742,-1,-2,0.00028932039276696742,2.9800000190734863 +1845,1200,0.0032999999821186066,-1,-2,0.0032999999821186066,3.9600000381469727 +1846,115000,3.1217390642268583e-05,-1,-2,3.1217390642268583e-05,3.5899999141693115 +1847,18000,5.8888886997010559e-05,-1,-2,5.8888886997010559e-05,1.059999942779541 +1848,60000,2.566666626080405e-05,-1,-2,2.566666626080405e-05,1.5399999618530273 +1849,10000,0.00040900002932175994,-1,-2,0.00040900002932175994,4.0900001525878906 +1850,0,inf,-1,-2,inf,3.0499999523162842 +1851,31000,2.516128915885929e-05,-1,-2,2.516128915885929e-05,0.77999997138977051 +1852,0,inf,-1,-2,inf,3.309999942779541 +1853,65000,5.1076920499326661e-05,-1,-2,5.1076920499326661e-05,3.3199999332427979 +1854,9000,0.00033000000985339284,-1,-2,0.00033000000985339284,2.9700000286102295 +1855,14000,0.00022142856323625892,-1,-2,0.00022142856323625892,3.0999999046325684 +1856,63000,1.6984127796604298e-05,-1,-2,1.6984127796604298e-05,1.0700000524520874 +1857,0,inf,-1,-2,inf,1.4800000190734863 +1858,45000,8.3555554738268256e-05,-1,-2,8.3555554738268256e-05,3.7599999904632568 +1859,21540,0.00013556174235418439,-1,-2,0.00013556174235418439,2.9200000762939453 +1860,0,inf,-1,-2,inf,5.309999942779541 +1861,1300,0.0035461538936942816,-1,-2,0.0035461538936942816,4.6100001335144043 +1862,0,inf,-1,-2,inf,4.679999828338623 +1863,24800,0.00023669353686273098,-1,-2,0.00023669353686273098,5.869999885559082 +1864,0,inf,-1,-2,inf,2.6400001049041748 +1865,6900,0.00051159417489543557,-1,-2,0.00051159417489543557,3.5299999713897705 +1866,76000,5.7894736528396606e-05,-1,-2,5.7894736528396606e-05,4.4000000953674316 +1867,114000,6.1403507061186247e-06,-1,-2,6.1403507061186247e-06,0.69999998807907104 +1868,68000,5.044117642682977e-05,-1,-2,5.044117642682977e-05,3.4300000667572021 +1869,31400,6.0191083321115002e-05,-1,-2,6.0191083321115002e-05,1.8899999856948853 +1870,7800,0.00040769230690784752,-1,-2,0.00040769230690784752,3.1800000667572021 +1871,40000,6.8000001192558557e-05,-1,-2,6.8000001192558557e-05,2.7200000286102295 +1872,9500,0.00022315788373816758,-1,-2,0.00022315788373816758,2.119999885559082 +1873,13600,0.00031029409728944302,-1,-2,0.00031029409728944302,4.2199997901916504 +1874,450000,4.0222221286967397e-06,-1,-2,4.0222221286967397e-06,1.809999942779541 +1875,9500,0.0004042105283588171,-1,-2,0.0004042105283588171,3.8399999141693115 +1876,224000,2.0580357158905827e-05,-1,-2,2.0580357158905827e-05,4.6100001335144043 +1877,19300,0.0001937823835760355,-1,-2,0.0001937823835760355,3.7400000095367432 +1878,10000,0.00053800002206116915,-1,-2,0.00053800002206116915,5.380000114440918 +1879,84400,2.7843600037158467e-05,-1,-2,2.7843600037158467e-05,2.3499999046325684 +1880,0,inf,-1,-2,inf,1.059999942779541 +1881,24000,0.00011541666754055768,-1,-2,0.00011541666754055768,2.7699999809265137 +1882,38270,9.6420175395905972e-05,-1,-2,9.6420175395905972e-05,3.690000057220459 +1883,38000,0.00014052631740923971,-1,-2,0.00014052631740923971,5.3400001525878906 +1884,88800,3.6373872717376798e-05,-1,-2,3.6373872717376798e-05,3.2300000190734863 +1885,43700,7.5972537160851061e-05,-1,-2,7.5972537160851061e-05,3.3199999332427979 +1886,14500,0.00029793105204589665,-1,-2,0.00029793105204589665,4.320000171661377 +1887,62530,5.7732286222744733e-05,-1,-2,5.7732286222744733e-05,3.6099998950958252 +1888,73500,1.9047618479817174e-05,-1,-2,1.9047618479817174e-05,1.3999999761581421 +1889,414000,9.6618362022127258e-07,-1,-2,9.6618362022127258e-07,0.40000000596046448 +1890,52000,5.5384618462994695e-05,-1,-2,5.5384618462994695e-05,2.880000114440918 +1891,12700,0.00017716534784995019,-1,-2,0.00017716534784995019,2.25 +1892,0,inf,-1,-2,inf,6.3499999046325684 +1893,170120,4.7613448259653524e-06,-1,-2,4.7613448259653524e-06,0.81000000238418579 +1894,220000,1.1863636245834641e-05,-1,-2,1.1863636245834641e-05,2.6099998950958252 +1895,14500,0.00041517239878885448,-1,-2,0.00041517239878885448,6.0199999809265137 +1896,0,inf,-1,-2,inf,5.8600001335144043 +1897,10180,0.00030746564152650535,-1,-2,0.00030746564152650535,3.130000114440918 +1898,8860,0.00046952595585025847,-1,-2,0.00046952595585025847,4.1599998474121094 +1899,35720,6.998880417086184e-05,-1,-2,6.998880417086184e-05,2.5 +1900,28600,0.00011643356265267357,-1,-2,0.00011643356265267357,3.3299999237060547 +1901,39220,2.6772053388413042e-05,-1,-2,2.6772053388413042e-05,1.0499999523162842 +1902,50000,8.2200000179000199e-05,-1,-2,8.2200000179000199e-05,4.1100001335144043 +1903,20250,3.851851579383947e-05,-1,-2,3.851851579383947e-05,0.77999997138977051 +1904,0,inf,-1,-2,inf,2.7699999809265137 +1905,30600,6.0457517975009978e-05,-1,-2,6.0457517975009978e-05,1.8500000238418579 +1906,14300,2.7272726583760232e-05,-1,-2,2.7272726583760232e-05,0.38999998569488525 +1907,148010,2.222822695330251e-05,-1,-2,2.222822695330251e-05,3.2899999618530273 +1908,35500,0.00012760564277414232,-1,-2,0.00012760564277414232,4.5300002098083496 +1909,9000,0.0004355555574875325,-1,-2,0.0004355555574875325,3.9200000762939453 +1910,27400,0.00018905109027400613,-1,-2,0.00018905109027400613,5.179999828338623 +1911,27800,0.0001352518011117354,-1,-2,0.0001352518011117354,3.7599999904632568 +1912,0,inf,-1,-2,inf,2.1500000953674316 +1913,2800,0.00077857146970927715,-1,-2,0.00077857146970927715,2.1800000667572021 +1914,24400,0.00022049181279726326,-1,-2,0.00022049181279726326,5.380000114440918 +1915,20000,7.200000254670158e-05,-1,-2,7.200000254670158e-05,1.440000057220459 +1916,112000,3.142857167404145e-05,-1,-2,3.142857167404145e-05,3.5199999809265137 +1917,3700,0.0011297296732664108,-1,-2,0.0011297296732664108,4.179999828338623 +1918,0,inf,-1,-2,inf,3.059999942779541 +1919,15000,0.00018400000408291817,-1,-2,0.00018400000408291817,2.7599999904632568 +1920,102000,2.676470649021212e-05,-1,-2,2.676470649021212e-05,2.7300000190734863 +1921,2800,0.00037857142160646617,-1,-2,0.00037857142160646617,1.059999942779541 +1922,42000,7.4285708251409233e-05,-1,-2,7.4285708251409233e-05,3.119999885559082 +1923,11000,0.00017454545013606548,-1,-2,0.00017454545013606548,1.9199999570846558 +1924,45800,0.00012205240636831149,-1,-2,0.00012205240636831149,5.5900001525878906 +1925,68400,3.0263156077126041e-05,-1,-2,3.0263156077126041e-05,2.0699999332427979 +1926,13000,0.00012692307063844055,-1,-2,0.00012692307063844055,1.6499999761581421 +1927,87000,4.2183910409221426e-05,-1,-2,4.2183910409221426e-05,3.6700000762939453 +1928,145450,2.3169473934103735e-05,-1,-2,2.3169473934103735e-05,3.369999885559082 +1929,75000,5.7466666476102546e-05,-1,-2,5.7466666476102546e-05,4.309999942779541 +1930,5700,0.00084385962691158056,-1,-2,0.00084385962691158056,4.809999942779541 +1931,0,inf,-1,-2,inf,3.0099999904632568 +1932,0,inf,-1,-2,inf,2.6400001049041748 +1933,0,inf,-1,-2,inf,4.1999998092651367 +1934,8100,0.00034197530476376414,-1,-2,0.00034197530476376414,2.7699999809265137 +1935,0,inf,-1,-2,inf,1.8700000047683716 +1936,63000,3.6031746276421472e-05,-1,-2,3.6031746276421472e-05,2.2699999809265137 +1937,23000,0.00021913043747190386,-1,-2,0.00021913043747190386,5.0399999618530273 +1938,28000,0.00010107142588822171,-1,-2,0.00010107142588822171,2.8299999237060547 +1939,30000,3.0333334507304244e-05,-1,-2,3.0333334507304244e-05,0.9100000262260437 +1940,0,inf,-1,-2,inf,1.8700000047683716 +1941,0,inf,-1,-2,inf,3.4200000762939453 +1942,40500,0.00015432099462486804,-1,-2,0.00015432099462486804,6.25 +1943,0,inf,-1,-2,inf,4.9800000190734863 +1944,0,inf,-1,-2,inf,2.2699999809265137 +1945,9000,0.00029666666523553431,-1,-2,0.00029666666523553431,2.6700000762939453 +1946,4200,0.0011166667100042105,-1,-2,0.0011166667100042105,4.690000057220459 +1947,23100,0.00034372296067886055,-1,-2,0.00034372296067886055,7.940000057220459 +1948,29800,5.5369127949234098e-05,-1,-2,5.5369127949234098e-05,1.6499999761581421 +1949,0,inf,-1,-2,inf,2.7699999809265137 +1950,15700,0.00037197454366832972,-1,-2,0.00037197454366832972,5.8400001525878906 +1951,75100,5.7922767155105248e-05,-1,-2,5.7922767155105248e-05,4.3499999046325684 +1952,37700,9.9204247817397118e-05,-1,-2,9.9204247817397118e-05,3.7400000095367432 +1953,0,inf,-1,-2,inf,2.1099998950958252 +1954,47100,8.95966004463844e-05,-1,-2,8.95966004463844e-05,4.2199997901916504 +1955,20000,0.00017650000518187881,-1,-2,0.00017650000518187881,3.5299999713897705 +1956,19400,0.0001716494734864682,-1,-2,0.0001716494734864682,3.3299999237060547 +1957,152180,2.378761928412132e-05,-1,-2,2.378761928412132e-05,3.619999885559082 +1958,0,inf,-1,-2,inf,1.7400000095367432 +1959,50000,7.0200003392528743e-05,-1,-2,7.0200003392528743e-05,3.5099999904632568 +1960,14500,0.00018275862385053188,-1,-2,0.00018275862385053188,2.6500000953674316 +1961,17400,0.00036149425432085991,-1,-2,0.00036149425432085991,6.2899999618530273 +1962,8100,0.00017654320981819183,-1,-2,0.00017654320981819183,1.4299999475479126 +1963,49000,6.0204081819392741e-05,-1,-2,6.0204081819392741e-05,2.9500000476837158 +1964,15200,0.00017368422413710505,-1,-2,0.00017368422413710505,2.6400001049041748 +1965,7200,0.00057777774054557085,-1,-2,0.00057777774054557085,4.1599998474121094 +1966,21800,0.00024403670977335423,-1,-2,0.00024403670977335423,5.320000171661377 +1967,163000,2.0368097466416657e-05,-1,-2,2.0368097466416657e-05,3.3199999332427979 +1968,38930,3.4677628718782216e-05,-1,-2,3.4677628718782216e-05,1.3500000238418579 +1969,4310,0.00060556840617209673,-1,-2,0.00060556840617209673,2.6099998950958252 +1970,4400,0.0005954545340500772,-1,-2,0.0005954545340500772,2.619999885559082 +1971,8310,0.00045487363240681589,-1,-2,0.00045487363240681589,3.7799999713897705 +1972,3500,0.0011857142671942711,-1,-2,0.0011857142671942711,4.1500000953674316 +1973,17000,0.0004394117568153888,-1,-2,0.0004394117568153888,7.4699997901916504 +1974,9000,0.00059333333047106862,-1,-2,0.00059333333047106862,5.3400001525878906 +1975,14400,0.00031388888601213694,-1,-2,0.00031388888601213694,4.5199999809265137 +1976,34100,0.00011964808800257742,-1,-2,0.00011964808800257742,4.0799999237060547 +1977,0,inf,-1,-2,inf,1.6499999761581421 +1978,18000,0.00020833333837799728,-1,-2,0.00020833333837799728,3.75 +1979,47300,0.00013107822451274842,-1,-2,0.00013107822451274842,6.1999998092651367 +1980,1100,0.0022363637108355761,-1,-2,0.0022363637108355761,2.4600000381469727 +1981,25400,0.0001984252012334764,-1,-2,0.0001984252012334764,5.0399999618530273 +1982,125400,2.9824561352143064e-05,-1,-2,2.9824561352143064e-05,3.7400000095367432 +1983,8200,0.00061585369985550642,-1,-2,0.00061585369985550642,5.0500001907348633 +1984,48800,0.00010143442341359332,-1,-2,0.00010143442341359332,4.9499998092651367 +1985,8300,0.00026265060296282172,-1,-2,0.00026265060296282172,2.1800000667572021 +1986,34630,9.0095287305302918e-05,-1,-2,9.0095287305302918e-05,3.119999885559082 +1987,48000,9.8124997748527676e-05,-1,-2,9.8124997748527676e-05,4.7100000381469727 +1988,55000,7.2727270890027285e-05,-1,-2,7.2727270890027285e-05,4 +1989,0,inf,-1,-2,inf,5.75 +1990,31700,9.7160882432945073e-05,-1,-2,9.7160882432945073e-05,3.0799999237060547 +1991,223900,1.6033944120863453e-05,-1,-2,1.6033944120863453e-05,3.5899999141693115 +1992,44500,3.2584270229563117e-05,-1,-2,3.2584270229563117e-05,1.4500000476837158 +1993,17720,0.00024435666273348033,-1,-2,0.00024435666273348033,4.3299999237060547 +1994,8400,0.00022023810015525669,-1,-2,0.00022023810015525669,1.8500000238418579 +1995,8300,0.00064337352523580194,-1,-2,0.00064337352523580194,5.3400001525878906 +1996,18200,6.0989012126810849e-05,-1,-2,6.0989012126810849e-05,1.1100000143051147 +1997,9500,0.0003936842258553952,-1,-2,0.0003936842258553952,3.7400000095367432 +1998,33830,6.473544635809958e-05,-1,-2,6.473544635809958e-05,2.190000057220459 +1999,0,inf,-1,-2,inf,0.38999998569488525 +2000,35000,0.00011200000153621659,-1,-2,0.00011200000153621659,3.9200000762939453 +2001,13800,0.00010217390808975324,-1,-2,0.00010217390808975324,1.4099999666213989 +2002,170120,3.8208322621358093e-06,-1,-2,3.8208322621358093e-06,0.64999997615814209 +2003,17600,0.00018863636068999767,-1,-2,0.00018863636068999767,3.3199999332427979 +2004,220000,1.6863636119524017e-05,-1,-2,1.6863636119524017e-05,3.7100000381469727 +2005,23000,0.00019260868430137634,-1,-2,0.00019260868430137634,4.429999828338623 +2006,12600,0.00014365078823175281,-1,-2,0.00014365078823175281,1.809999942779541 +2007,33830,8.1879989011213183e-05,-1,-2,8.1879989011213183e-05,2.7699999809265137 +2008,16000,8.1250000221189111e-05,-1,-2,8.1250000221189111e-05,1.2999999523162842 +2009,7000,0.00050428573740646243,-1,-2,0.00050428573740646243,3.5299999713897705 +2010,30000,0.0001113333273679018,-1,-2,0.0001113333273679018,3.3399999141693115 +2011,388000,1.1932989764318336e-05,-1,-2,1.1932989764318336e-05,4.630000114440918 +2012,69200,5.5924854677869007e-05,-1,-2,5.5924854677869007e-05,3.869999885559082 +2013,139900,2.1086490960442461e-05,-1,-2,2.1086490960442461e-05,2.9500000476837158 +2014,0,inf,-1,-2,inf,4.630000114440918 +2015,0,inf,-1,-2,inf,2.1400001049041748 +2016,0,inf,-1,-2,inf,1.9700000286102295 +2017,112500,2.657777804415673e-05,-1,-2,2.657777804415673e-05,2.9900000095367432 +2018,35100,4.5584045437863097e-05,-1,-2,4.5584045437863097e-05,1.6000000238418579 +2019,14600,0.00012465754116419703,-1,-2,0.00012465754116419703,1.8200000524520874 +2020,0,inf,-1,-2,inf,4.6399998664855957 +2021,103300,3.697966894833371e-05,-1,-2,3.697966894833371e-05,3.8199999332427979 +2022,34300,0.00012973760021850467,-1,-2,0.00012973760021850467,4.4499998092651367 +2023,123000,2.2520325728692114e-05,-1,-2,2.2520325728692114e-05,2.7699999809265137 +2024,241000,1.3029046385781839e-05,-1,-2,1.3029046385781839e-05,3.1400001049041748 +2025,7800,0.00021282050875015557,-1,-2,0.00021282050875015557,1.6599999666213989 +2026,0,inf,-1,-2,inf,5.0100002288818359 +2027,80600,7.580645615234971e-05,-1,-2,7.580645615234971e-05,6.1100001335144043 +2028,59220,6.7038163251709193e-05,-1,-2,6.7038163251709193e-05,3.9700000286102295 +2029,35000,7.1428570663556457e-05,-1,-2,7.1428570663556457e-05,2.5 +2030,6000,0.00090666668256744742,-1,-2,0.00090666668256744742,5.440000057220459 +2031,4310,0.00098143855575472116,-1,-2,0.00098143855575472116,4.2300000190734863 +2032,6780,0.00061209441628307104,-1,-2,0.00061209441628307104,4.1500000953674316 +2033,0,inf,-1,-2,inf,5.3299999237060547 +2034,9500,0.00058315787464380264,-1,-2,0.00058315787464380264,5.5399999618530273 +2035,0,inf,-1,-2,inf,5.690000057220459 +2036,45000,0.00011933333007618785,-1,-2,0.00011933333007618785,5.369999885559082 +2037,17000,0.00012235293979756534,-1,-2,0.00012235293979756534,2.0799999237060547 +2038,390000,1.1538461876625661e-05,-1,-2,1.1538461876625661e-05,4.5 +2039,106730,3.7946221709717065e-05,-1,-2,3.7946221709717065e-05,4.0500001907348633 +2040,97000,1.6494845112902112e-05,-1,-2,1.6494845112902112e-05,1.6000000238418579 +2041,15000,0.00050799996824935079,-1,-2,0.00050799996824935079,7.619999885559082 +2042,110100,4.8228881496470422e-05,-1,-2,4.8228881496470422e-05,5.309999942779541 +2043,230000,1.3913043403590564e-05,-1,-2,1.3913043403590564e-05,3.2000000476837158 +2044,8300,0.00032409638515673578,-1,-2,0.00032409638515673578,2.690000057220459 +2045,9000,0.00061555556021630764,-1,-2,0.00061555556021630764,5.5399999618530273 +2046,45000,6.2666666053701192e-05,-1,-2,6.2666666053701192e-05,2.8199999332427979 +2047,9100,0.00031538459006696939,-1,-2,0.00031538459006696939,2.869999885559082 +2048,25000,9.5600007625762373e-05,-1,-2,9.5600007625762373e-05,2.3900001049041748 +2049,83530,4.3098287278553471e-05,-1,-2,4.3098287278553471e-05,3.5999999046325684 +2050,78600,1.7811704310588539e-05,-1,-2,1.7811704310588539e-05,1.3999999761581421 +2051,17000,0.00016529411368537694,-1,-2,0.00016529411368537694,2.809999942779541 +2052,6430,0.00048833596520125866,-1,-2,0.00048833596520125866,3.1400001049041748 +2053,8400,0.00062976189656183124,-1,-2,0.00062976189656183124,5.2899999618530273 +2054,10000,0.00015700000221841037,-1,-2,0.00015700000221841037,1.5700000524520874 +2055,36000,7.9722216469235718e-05,-1,-2,7.9722216469235718e-05,2.869999885559082 +2056,16400,0.0003164634108543396,-1,-2,0.0003164634108543396,5.190000057220459 +2057,20100,0.0001592039770912379,-1,-2,0.0001592039770912379,3.2000000476837158 +2058,47000,9.2978720203973353e-05,-1,-2,9.2978720203973353e-05,4.369999885559082 +2059,97000,2.0618555936380289e-05,-1,-2,2.0618555936380289e-05,2 +2060,11400,0.00052982458146288991,-1,-2,0.00052982458146288991,6.0399999618530273 +2061,30,0.19433332979679108,-1,-2,0.19433332979679108,5.8299999237060547 +2062,100700,3.6047666071681306e-05,-1,-2,3.6047666071681306e-05,3.630000114440918 +2063,45700,4.3982494389638305e-05,-1,-2,4.3982494389638305e-05,2.0099999904632568 +2064,0,inf,-1,-2,inf,2.9800000190734863 +2065,325000,6.6769234763341956e-06,-1,-2,6.6769234763341956e-06,2.1700000762939453 +2066,560,0.0048214285634458065,-1,-2,0.0048214285634458065,2.7000000476837158 +2067,48000,0.00010979166836477816,-1,-2,0.00010979166836477816,5.2699999809265137 +2068,14500,3.7241381505737081e-05,-1,-2,3.7241381505737081e-05,0.54000002145767212 +2069,148500,1.3602693798020482e-05,-1,-2,1.3602693798020482e-05,2.0199999809265137 +2070,0,inf,-1,-2,inf,1.3999999761581421 +2071,3500,0.0010285713942721486,-1,-2,0.0010285713942721486,3.5999999046325684 +2072,77970,2.5907400413416326e-05,-1,-2,2.5907400413416326e-05,2.0199999809265137 +2073,0,inf,-1,-2,inf,0.52999997138977051 +2074,31210,0.00013937840412836522,-1,-2,0.00013937840412836522,4.3499999046325684 +2075,177000,2.0395480532897636e-05,-1,-2,2.0395480532897636e-05,3.6099998950958252 +2076,44000,9.2727270384784788e-05,-1,-2,9.2727270384784788e-05,4.0799999237060547 +2077,102800,2.5778210329008289e-05,-1,-2,2.5778210329008289e-05,2.6500000953674316 +2078,14000,0.00027571426471695304,-1,-2,0.00027571426471695304,3.8599998950958252 +2079,34600,7.6300580985844135e-05,-1,-2,7.6300580985844135e-05,2.6400001049041748 +2080,67200,6.3988096371758729e-05,-1,-2,6.3988096371758729e-05,4.3000001907348633 +2081,0,inf,-1,-2,inf,3.0299999713897705 +2082,5040,0.00071031745756044984,-1,-2,0.00071031745756044984,3.5799999237060547 +2083,20500,0.00021512193779926747,-1,-2,0.00021512193779926747,4.4099998474121094 +2084,99500,2.6633166271494702e-05,-1,-2,2.6633166271494702e-05,2.6500000953674316 +2085,8400,0.00041547618457116187,-1,-2,0.00041547618457116187,3.4900000095367432 +2086,44500,5.370786675484851e-05,-1,-2,5.370786675484851e-05,2.3900001049041748 +2087,11000,0.00032545454450882971,-1,-2,0.00032545454450882971,3.5799999237060547 +2088,290010,1.4723630556545686e-05,-1,-2,1.4723630556545686e-05,4.2699999809265137 +2089,8000,0.0004400000034365803,-1,-2,0.0004400000034365803,3.5199999809265137 +2090,0,inf,-1,-2,inf,3.7599999904632568 +2091,14000,0.00019785713811870664,-1,-2,0.00019785713811870664,2.7699999809265137 +2092,146220,1.8396936866338365e-05,-1,-2,1.8396936866338365e-05,2.690000057220459 +2093,0,inf,-1,-2,inf,3.3399999141693115 +2094,7200,0.00040138891199603677,-1,-2,0.00040138891199603677,2.8900001049041748 +2095,41500,9.3012044089846313e-05,-1,-2,9.3012044089846313e-05,3.8599998950958252 +2096,0,inf,-1,-2,inf,3.9100000858306885 +2097,0,inf,-1,-2,inf,3.9200000762939453 +2098,8400,0.00022023810015525669,-1,-2,0.00022023810015525669,1.8500000238418579 +2099,0,inf,-1,-2,inf,2.7200000286102295 +2100,55500,6.8108107370790094e-05,-1,-2,6.8108107370790094e-05,3.7799999713897705 +2101,56250,6.2044447986409068e-05,-1,-2,6.2044447986409068e-05,3.4900000095367432 +2102,10000,6.1999999161344022e-05,-1,-2,6.1999999161344022e-05,0.62000000476837158 +2103,8000,0.0003375000087544322,-1,-2,0.0003375000087544322,2.7000000476837158 +2104,28000,0.00015714285837020725,-1,-2,0.00015714285837020725,4.4000000953674316 +2105,0,inf,-1,-2,inf,1.0800000429153442 +2106,37000,8.2972968812100589e-05,-1,-2,8.2972968812100589e-05,3.0699999332427979 +2107,13500,0.0002074074000120163,-1,-2,0.0002074074000120163,2.7999999523162842 +2108,350000,6.200000370881753e-06,-1,-2,6.200000370881753e-06,2.1700000762939453 +2109,16500,0.00026666666963137686,-1,-2,0.00026666666963137686,4.4000000953674316 +2110,0,inf,-1,-2,inf,0.38999998569488525 +2111,17700,0.00028531075804494321,-1,-2,0.00028531075804494321,5.0500001907348633 +2112,19000,0.0001968421129276976,-1,-2,0.0001968421129276976,3.7400000095367432 +2113,30000,0.00024266667605843395,-1,-2,0.00024266667605843395,7.2800002098083496 +2114,4000,0.00022000000171829015,-1,-2,0.00022000000171829015,0.87999999523162842 +2115,0,inf,-1,-2,inf,3.9000000953674316 +2116,6000,0.00085499999113380909,-1,-2,0.00085499999113380909,5.130000114440918 +2117,68000,4.9411763029638678e-05,-1,-2,4.9411763029638678e-05,3.3599998950958252 +2118,80000,4.2124996980419382e-05,-1,-2,4.2124996980419382e-05,3.369999885559082 +2119,65000,5.7846154959406704e-05,-1,-2,5.7846154959406704e-05,3.7599999904632568 +2120,25000,8.920000254875049e-05,-1,-2,8.920000254875049e-05,2.2300000190734863 +2121,101000,3.7425743357744068e-05,-1,-2,3.7425743357744068e-05,3.7799999713897705 +2122,65000,6.1692313465755433e-05,-1,-2,6.1692313465755433e-05,4.0100002288818359 +2123,53000,8.0754718510434031e-05,-1,-2,8.0754718510434031e-05,4.2800002098083496 +2124,35400,8.2203390775248408e-05,-1,-2,8.2203390775248408e-05,2.9100000858306885 +2125,144500,2.5813149477471597e-05,-1,-2,2.5813149477471597e-05,3.7300000190734863 +2126,8400,0.00018690477008931339,-1,-2,0.00018690477008931339,1.5700000524520874 +2127,66000,6.1060607549734414e-05,-1,-2,6.1060607549734414e-05,4.0300002098083496 +2128,20000,0.00016749999485909939,-1,-2,0.00016749999485909939,3.3499999046325684 +2129,11030,0.00050589302554726601,-1,-2,0.00050589302554726601,5.5799999237060547 +2130,92700,4.4768068619305268e-05,-1,-2,4.4768068619305268e-05,4.1500000953674316 +2131,8200,0.00046585366362705827,-1,-2,0.00046585366362705827,3.8199999332427979 +2132,47100,5.1380044169491157e-05,-1,-2,5.1380044169491157e-05,2.4200000762939453 +2133,1804,0.0012472283560782671,-1,-2,0.0012472283560782671,2.25 +2134,123000,1.7154470697278157e-05,-1,-2,1.7154470697278157e-05,2.1099998950958252 +2135,0,inf,-1,-2,inf,3.7599999904632568 +2136,8200,0.0005097560933791101,-1,-2,0.0005097560933791101,4.179999828338623 +2137,0,inf,-1,-2,inf,3.3499999046325684 +2138,10800,0.00036759258364327252,-1,-2,0.00036759258364327252,3.9700000286102295 +2139,71000,2.8309859771979973e-05,-1,-2,2.8309859771979973e-05,2.0099999904632568 +2140,51000,1.5882353181950748e-05,-1,-2,1.5882353181950748e-05,0.81000000238418579 +2141,2800,0.0023428571876138449,-1,-2,0.0023428571876138449,6.559999942779541 +2142,4400,0.0014159091515466571,-1,-2,0.0014159091515466571,6.2300000190734863 +2143,0,inf,-1,-2,inf,4.4899997711181641 +2144,23000,2.8260868930374272e-05,-1,-2,2.8260868930374272e-05,0.64999997615814209 +2145,0,inf,-1,-2,inf,2.2999999523162842 +2146,10000,0.00033199999597854912,-1,-2,0.00033199999597854912,3.3199999332427979 +2147,66000,4.4696971599478275e-05,-1,-2,4.4696971599478275e-05,2.9500000476837158 +2148,70000,6.7142857005819678e-05,-1,-2,6.7142857005819678e-05,4.6999998092651367 +2149,5300,0.00088679243344813585,-1,-2,0.00088679243344813585,4.6999998092651367 +2150,50000,1.0800000382005237e-05,-1,-2,1.0800000382005237e-05,0.54000002145767212 +2151,11900,4.4537813664646819e-05,-1,-2,4.4537813664646819e-05,0.52999997138977051 +2152,36500,0.0001558904186822474,-1,-2,0.0001558904186822474,5.690000057220459 +2153,242500,2.0865978513029404e-05,-1,-2,2.0865978513029404e-05,5.059999942779541 +2154,0,inf,-1,-2,inf,4.179999828338623 +2155,18700,8.1283418694511056e-05,-1,-2,8.1283418694511056e-05,1.5199999809265137 +2156,43000,7.6976743002887815e-05,-1,-2,7.6976743002887815e-05,3.309999942779541 +2157,43000,0.00010069767449749634,-1,-2,0.00010069767449749634,4.3299999237060547 +2158,158700,2.6969126338372007e-05,-1,-2,2.6969126338372007e-05,4.2800002098083496 +2159,61900,5.9127625718247145e-05,-1,-2,5.9127625718247145e-05,3.6600000858306885 +2160,0,inf,-1,-2,inf,3.059999942779541 +2161,26500,0.00011245282803429291,-1,-2,0.00011245282803429291,2.9800000190734863 +2162,37900,9.525065979687497e-05,-1,-2,9.525065979687497e-05,3.6099998950958252 +2163,13960,0.00026934096240438521,-1,-2,0.00026934096240438521,3.7599999904632568 +2164,95000,6.2736842664889991e-05,-1,-2,6.2736842664889991e-05,5.9600000381469727 +2165,27100,0.00010738007404142991,-1,-2,0.00010738007404142991,2.9100000858306885 +2166,0,inf,-1,-2,inf,2.1700000762939453 +2167,8200,0.0005853658658452332,-1,-2,0.0005853658658452332,4.8000001907348633 +2168,0,inf,-1,-2,inf,4.3000001907348633 +2169,46100,7.1149675932247192e-05,-1,-2,7.1149675932247192e-05,3.2799999713897705 +2170,0,inf,-1,-2,inf,4.3400001525878906 +2171,9220,0.00047830800758674741,-1,-2,0.00047830800758674741,4.4099998474121094 +2172,7000,0.00064714287873357534,-1,-2,0.00064714287873357534,4.5300002098083496 +2173,172000,4.5348839194048196e-05,-1,-2,4.5348839194048196e-05,7.8000001907348633 +2174,0,inf,-1,-2,inf,2.7100000381469727 +2175,73390,5.1914430514443666e-05,-1,-2,5.1914430514443666e-05,3.809999942779541 +2176,8300,0.00036024095606990159,-1,-2,0.00036024095606990159,2.9900000095367432 +2177,338000,7.1597637543163728e-06,-1,-2,7.1597637543163728e-06,2.4200000762939453 +2178,70920,7.0642978243995458e-05,-1,-2,7.0642978243995458e-05,5.0100002288818359 +2179,8500,0.0003247058775741607,-1,-2,0.0003247058775741607,2.7599999904632568 +2180,0,inf,-1,-2,inf,1.6000000238418579 +2181,8400,9.2857138952240348e-05,-1,-2,9.2857138952240348e-05,0.77999997138977051 +2182,42000,8.3095241279806942e-05,-1,-2,8.3095241279806942e-05,3.4900000095367432 +2183,9100,0.00027032967773266137,-1,-2,0.00027032967773266137,2.4600000381469727 +2184,41550,7.5812276918441057e-05,-1,-2,7.5812276918441057e-05,3.1500000953674316 +2185,10500,0.00040666665881872177,-1,-2,0.00040666665881872177,4.2699999809265137 +2186,590,0.0075423726812005043,-1,-2,0.0075423726812005043,4.4499998092651367 +2187,133000,1.6842104741954245e-05,-1,-2,1.6842104741954245e-05,2.2400000095367432 +2188,14800,0.00027432432398200035,-1,-2,0.00027432432398200035,4.059999942779541 +2189,156600,1.0919540727627464e-05,-1,-2,1.0919540727627464e-05,1.7100000381469727 +2190,28300,0.00016360424342565238,-1,-2,0.00016360424342565238,4.630000114440918 +2191,37400,5.3743315220344812e-05,-1,-2,5.3743315220344812e-05,2.0099999904632568 +2192,0,inf,-1,-2,inf,0.38999998569488525 +2193,18520,0.00021058315178379416,-1,-2,0.00021058315178379416,3.9000000953674316 +2194,36800,0.00013342390593606979,-1,-2,0.00013342390593606979,4.9099998474121094 +2195,15000,0.00020399999630171806,-1,-2,0.00020399999630171806,3.059999942779541 +2196,45000,4.7777779400348663e-05,-1,-2,4.7777779400348663e-05,2.1500000953674316 +2197,37000,0.0001813513517845422,-1,-2,0.0001813513517845422,6.7100000381469727 +2198,27650,0.00021193490829318762,-1,-2,0.00021193490829318762,5.8600001335144043 +2199,204900,1.6300633433274925e-05,-1,-2,1.6300633433274925e-05,3.3399999141693115 +2200,70000,1.5285715562640689e-05,-1,-2,1.5285715562640689e-05,1.0700000524520874 +2201,25000,0.00019479999900795519,-1,-2,0.00019479999900795519,4.869999885559082 +2202,113234,2.7288622732157819e-05,-1,-2,2.7288622732157819e-05,3.0899999141693115 +2203,72800,7.664834993192926e-05,-1,-2,7.664834993192926e-05,5.5799999237060547 +2204,21320,0.00019090056593995541,-1,-2,0.00019090056593995541,4.070000171661377 +2205,55000,7.6545453339349478e-05,-1,-2,7.6545453339349478e-05,4.2100000381469727 +2206,1340,0.0020597015973180532,-1,-2,0.0020597015973180532,2.7599999904632568 +2207,38000,5.3684208978665993e-05,-1,-2,5.3684208978665993e-05,2.0399999618530273 +2208,10000,0.00038800001493655145,-1,-2,0.00038800001493655145,3.880000114440918 +2209,62000,3.7741934647783637e-05,-1,-2,3.7741934647783637e-05,2.3399999141693115 +2210,15000,0.00028533334261737764,-1,-2,0.00028533334261737764,4.2800002098083496 +2211,15900,0.00023270440578926355,-1,-2,0.00023270440578926355,3.7000000476837158 +2212,8300,0.00042771082371473312,-1,-2,0.00042771082371473312,3.5499999523162842 +2213,0,inf,-1,-2,inf,3.0299999713897705 +2214,14300,0.00036293707671575248,-1,-2,0.00036293707671575248,5.190000057220459 +2215,70000,4.8142854211619124e-05,-1,-2,4.8142854211619124e-05,3.369999885559082 +2216,5800,0.00057068961905315518,-1,-2,0.00057068961905315518,3.309999942779541 +2217,20000,0.00020650000078603625,-1,-2,0.00020650000078603625,4.130000114440918 +2218,19200,0.00011302084021735936,-1,-2,0.00011302084021735936,2.1700000762939453 +2219,21800,0.00010412844130769372,-1,-2,0.00010412844130769372,2.2699999809265137 +2220,8100,0.00041358024463988841,-1,-2,0.00041358024463988841,3.3499999046325684 +2221,20000,0.00019349998910911381,-1,-2,0.00019349998910911381,3.869999885559082 +2222,73390,6.4177678723353893e-05,-1,-2,6.4177678723353893e-05,4.7100000381469727 +2223,10000,0.00025899999309331179,-1,-2,0.00025899999309331179,2.5899999141693115 +2224,75000,2.680000034160912e-05,-1,-2,2.680000034160912e-05,2.0099999904632568 +2225,0,inf,-1,-2,inf,3.5299999713897705 +2226,67200,5.9821428294526413e-05,-1,-2,5.9821428294526413e-05,4.0199999809265137 +2227,97000,4.0412371163256466e-05,-1,-2,4.0412371163256466e-05,3.9200000762939453 +2228,5800,6.7241373471915722e-05,-1,-2,6.7241373471915722e-05,0.38999998569488525 +2229,40000,8.2749997091013938e-05,-1,-2,8.2749997091013938e-05,3.309999942779541 +2230,26100,0.00012528736260719597,-1,-2,0.00012528736260719597,3.2699999809265137 +2231,70000,2.914285687438678e-05,-1,-2,2.914285687438678e-05,2.0399999618530273 +2232,49000,9.0204084699507803e-05,-1,-2,9.0204084699507803e-05,4.4200000762939453 +2233,8200,0.00028658536029979587,-1,-2,0.00028658536029979587,2.3499999046325684 +2234,63070,5.5176788009703159e-05,-1,-2,5.5176788009703159e-05,3.4800000190734863 +2235,36500,5.1780822104774415e-05,-1,-2,5.1780822104774415e-05,1.8899999856948853 +2236,11300,0.00033008848549798131,-1,-2,0.00033008848549798131,3.7300000190734863 +2237,0,inf,-1,-2,inf,3.8599998950958252 +2238,0,inf,-1,-2,inf,4.130000114440918 +2239,10000,0.00052699999650940299,-1,-2,0.00052699999650940299,5.2699999809265137 +2240,70000,5.5428572522941977e-05,-1,-2,5.5428572522941977e-05,3.880000114440918 +2241,0,inf,-1,-2,inf,4.8499999046325684 +2242,54800,5.1459854148561135e-05,-1,-2,5.1459854148561135e-05,2.8199999332427979 +2243,43700,6.9794048613402992e-05,-1,-2,6.9794048613402992e-05,3.0499999523162842 +2244,15300,0.00024379085516557097,-1,-2,0.00024379085516557097,3.7300000190734863 +2245,3000,0.0010400000028312206,-1,-2,0.0010400000028312206,3.119999885559082 +2246,70000,5.6285716709680855e-05,-1,-2,5.6285716709680855e-05,3.940000057220459 +2247,9400,0.0003499999875202775,-1,-2,0.0003499999875202775,3.2899999618530273 +2248,266000,7.8195489550125785e-06,-1,-2,7.8195489550125785e-06,2.0799999237060547 +2249,70000,5.0714286771835759e-05,-1,-2,5.0714286771835759e-05,3.5499999523162842 +2250,70000,4.7857141908025369e-05,-1,-2,4.7857141908025369e-05,3.3499999046325684 +2251,0,inf,-1,-2,inf,3.9700000286102295 +2252,94100,4.1232731746276841e-05,-1,-2,4.1232731746276841e-05,3.880000114440918 +2253,70000,3.9142858440754935e-05,-1,-2,3.9142858440754935e-05,2.7400000095367432 +2254,335000,8.2388060036464594e-06,-1,-2,8.2388060036464594e-06,2.7599999904632568 +2255,14800,0.00018040540453512222,-1,-2,0.00018040540453512222,2.6700000762939453 +2256,15600,0.00012115384743083268,-1,-2,0.00012115384743083268,1.8899999856948853 +2257,45100,0.00011197339335922152,-1,-2,0.00011197339335922152,5.0500001907348633 +2258,63100,4.8969886847771704e-05,-1,-2,4.8969886847771704e-05,3.0899999141693115 +2259,8200,0.00061951216775923967,-1,-2,0.00061951216775923967,5.0799999237060547 +2260,73410,7.3150797106791288e-05,-1,-2,7.3150797106791288e-05,5.369999885559082 +2261,28100,9.2526686785276979e-05,-1,-2,9.2526686785276979e-05,2.5999999046325684 +2262,374000,4.2245992517564446e-06,-1,-2,4.2245992517564446e-06,1.5800000429153442 +2263,224000,1.866071397671476e-05,-1,-2,1.866071397671476e-05,4.179999828338623 +2264,75300,5.4050466133048758e-05,-1,-2,5.4050466133048758e-05,4.070000171661377 +2265,0,inf,-1,-2,inf,4.4000000953674316 +2266,0,inf,-1,-2,inf,3.7799999713897705 +2267,0,inf,-1,-2,inf,2.3900001049041748 +2268,4204,0.0010466222884133458,-1,-2,0.0010466222884133458,4.4000000953674316 +2269,162000,3.1666666473029181e-05,-1,-2,3.1666666473029181e-05,5.130000114440918 +2270,388000,6.0567008404177614e-06,-1,-2,6.0567008404177614e-06,2.3499999046325684 +2271,0,inf,-1,-2,inf,0.38999998569488525 +2272,20000,0.00011900000390596688,-1,-2,0.00011900000390596688,2.380000114440918 +2273,31400,8.7898086349014193e-05,-1,-2,8.7898086349014193e-05,2.7599999904632568 +2274,652070,2.2236877157411072e-06,-1,-2,2.2236877157411072e-06,1.4500000476837158 +2275,8300,0.0004313252866268158,-1,-2,0.0004313252866268158,3.5799999237060547 +2276,52000,9.1730769781861454e-05,-1,-2,9.1730769781861454e-05,4.7699999809265137 +2277,0,inf,-1,-2,inf,3.3399999141693115 +2278,0,inf,-1,-2,inf,3.1400001049041748 +2279,61740,1.3281503015605267e-05,-1,-2,1.3281503015605267e-05,0.81999999284744263 +2280,0,inf,-1,-2,inf,3.880000114440918 +2281,63000,4.206349331070669e-05,-1,-2,4.206349331070669e-05,2.6500000953674316 +2282,0,inf,-1,-2,inf,5.7800002098083496 +2283,9800,0.00013265306188259274,-1,-2,0.00013265306188259274,1.2999999523162842 +2284,0,inf,-1,-2,inf,2.0099999904632568 +2285,16400,0.00026097561931237578,-1,-2,0.00026097561931237578,4.2800002098083496 +2286,0,inf,-1,-2,inf,5.4099998474121094 +2287,7000,0.00058714288752526045,-1,-2,0.00058714288752526045,4.1100001335144043 +2288,77970,5.5405926104867831e-05,-1,-2,5.5405926104867831e-05,4.320000171661377 +2289,15600,8.5897438111715019e-05,-1,-2,8.5897438111715019e-05,1.3400000333786011 +2290,137000,7.8102193583617918e-06,-1,-2,7.8102193583617918e-06,1.0700000524520874 +2291,11500,0.00024086955818347633,-1,-2,0.00024086955818347633,2.7699999809265137 +2292,50050,5.4145853937370703e-05,-1,-2,5.4145853937370703e-05,2.7100000381469727 +2293,92500,3.4594595490489155e-05,-1,-2,3.4594595490489155e-05,3.2000000476837158 +2294,141200,2.9390936106210575e-05,-1,-2,2.9390936106210575e-05,4.1500000953674316 +2295,117000,2.247863267257344e-05,-1,-2,2.247863267257344e-05,2.630000114440918 +2296,8100,0.00023086419969331473,-1,-2,0.00023086419969331473,1.8700000047683716 +2297,13100,0.00025648853625170887,-1,-2,0.00025648853625170887,3.3599998950958252 +2298,78500,1.6942674847086892e-05,-1,-2,1.6942674847086892e-05,1.3300000429153442 +2299,86000,7.8023258538451046e-05,-1,-2,7.8023258538451046e-05,6.7100000381469727 +2300,0,inf,-1,-2,inf,4.0500001907348633 +2301,7800,0.00057564099552109838,-1,-2,0.00057564099552109838,4.4899997711181641 +2302,270000,1.5629628251190297e-05,-1,-2,1.5629628251190297e-05,4.2199997901916504 +2303,101000,6.7920795117970556e-05,-1,-2,6.7920795117970556e-05,6.8600001335144043 +2304,560,0.0099285710602998734,-1,-2,0.0099285710602998734,5.559999942779541 +2305,123000,1.9024389985133894e-05,-1,-2,1.9024389985133894e-05,2.3399999141693115 +2306,11200,0.00031339286942966282,-1,-2,0.00031339286942966282,3.5099999904632568 +2307,8100,0.00034197530476376414,-1,-2,0.00034197530476376414,2.7699999809265137 +2308,0,inf,-1,-2,inf,1.6599999666213989 +2309,45700,0.00011028446169802919,-1,-2,0.00011028446169802919,5.0399999618530273 +2310,43950,3.2081909012049437e-05,-1,-2,3.2081909012049437e-05,1.4099999666213989 +2311,0,inf,-1,-2,inf,1.7400000095367432 +2312,34100,0.0001029325503623113,-1,-2,0.0001029325503623113,3.5099999904632568 +2313,116000,2.5172414098051377e-05,-1,-2,2.5172414098051377e-05,2.9200000762939453 +2314,95000,4.0526316297473386e-05,-1,-2,4.0526316297473386e-05,3.8499999046325684 +2315,12000,0.00046916666906327009,-1,-2,0.00046916666906327009,5.630000114440918 +2316,40000,7.4750001658685505e-05,-1,-2,7.4750001658685505e-05,2.9900000095367432 +2317,110250,1.7687074432615191e-05,-1,-2,1.7687074432615191e-05,1.9500000476837158 +2318,0,inf,-1,-2,inf,5.0199999809265137 +2319,20200,0.00024207920068874955,-1,-2,0.00024207920068874955,4.8899998664855957 +2320,36000,8.4722218161914498e-05,-1,-2,8.4722218161914498e-05,3.0499999523162842 +2321,16000,0.00021812500199303031,-1,-2,0.00021812500199303031,3.4900000095367432 +2322,0,inf,-1,-2,inf,5.5799999237060547 +2323,0,inf,-1,-2,inf,4.8299999237060547 +2324,47000,9.6382980700582266e-05,-1,-2,9.6382980700582266e-05,4.5300002098083496 +2325,0,inf,-1,-2,inf,2.869999885559082 +2326,141200,3.1161474908003584e-05,-1,-2,3.1161474908003584e-05,4.4000000953674316 +2327,17600,0.00016931818390730768,-1,-2,0.00016931818390730768,2.9800000190734863 +2328,13100,0.00027786259306594729,-1,-2,0.00027786259306594729,3.6400001049041748 +2329,10180,0.00021316307538654655,-1,-2,0.00021316307538654655,2.1700000762939453 +2330,68400,2.5584795366739854e-05,-1,-2,2.5584795366739854e-05,1.75 +2331,25000,0.00012520000746008009,-1,-2,0.00012520000746008009,3.130000114440918 +2332,8000,0.00034624998806975782,-1,-2,0.00034624998806975782,2.7699999809265137 +2333,175900,1.9897668607882224e-05,-1,-2,1.9897668607882224e-05,3.5 +2334,0,inf,-1,-2,inf,2.7599999904632568 +2335,0,inf,-1,-2,inf,3.75 +2336,10900,0.00027889906778000295,-1,-2,0.00027889906778000295,3.0399999618530273 +2337,22500,0.00013155555643606931,-1,-2,0.00013155555643606931,2.9600000381469727 +2338,0,inf,-1,-2,inf,3.3399999141693115 +2339,92700,3.3117583370767534e-05,-1,-2,3.3117583370767534e-05,3.0699999332427979 +2340,6090,0.00057963875588029623,-1,-2,0.00057963875588029623,3.5299999713897705 +2341,9000,0.00032111111795529723,-1,-2,0.00032111111795529723,2.8900001049041748 +2342,12000,8.6666666902601719e-05,-1,-2,8.6666666902601719e-05,1.0399999618530273 +2343,15200,0.00034078946919180453,-1,-2,0.00034078946919180453,5.179999828338623 +2344,0,inf,-1,-2,inf,4.429999828338623 +2345,42000,4.9285714339930564e-05,-1,-2,4.9285714339930564e-05,2.0699999332427979 +2346,14400,0.00038749998202547431,-1,-2,0.00038749998202547431,5.5799999237060547 +2347,8000,0.00033875001827254891,-1,-2,0.00033875001827254891,2.7100000381469727 +2348,47500,6.2736842664889991e-05,-1,-2,6.2736842664889991e-05,2.9800000190734863 +2349,103000,2.0873787434538826e-05,-1,-2,2.0873787434538826e-05,2.1500000953674316 +2350,1000,0.0052800001576542854,-1,-2,0.0052800001576542854,5.2800002098083496 +2351,150000,3.3733333111740649e-05,-1,-2,3.3733333111740649e-05,5.059999942779541 +2352,9500,0.00043684212141670287,-1,-2,0.00043684212141670287,4.1500000953674316 +2353,21700,0.00012718893412966281,-1,-2,0.00012718893412966281,2.7599999904632568 +2354,54400,7.8860291978344321e-05,-1,-2,7.8860291978344321e-05,4.2899999618530273 +2355,74100,6.2483130022883415e-05,-1,-2,6.2483130022883415e-05,4.630000114440918 +2356,125400,1.5869218259467743e-05,-1,-2,1.5869218259467743e-05,1.9900000095367432 +2357,28000,0.00013785713235847652,-1,-2,0.00013785713235847652,3.8599998950958252 +2358,51700,4.912959411740303e-05,-1,-2,4.912959411740303e-05,2.5399999618530273 +2359,142100,9.3596063379663974e-06,-1,-2,9.3596063379663974e-06,1.3300000429153442 +2360,0,inf,-1,-2,inf,4.9699997901916504 +2361,0,inf,-1,-2,inf,5.179999828338623 +2362,0,inf,-1,-2,inf,3.7000000476837158 +2363,133000,3.0150376915116794e-05,-1,-2,3.0150376915116794e-05,4.0100002288818359 +2364,14400,0.00016527778643649071,-1,-2,0.00016527778643649071,2.380000114440918 +2365,62000,4.9516129365656525e-05,-1,-2,4.9516129365656525e-05,3.0699999332427979 +2366,174500,3.3352436730638146e-05,-1,-2,3.3352436730638146e-05,5.820000171661377 +2367,11620,0.00038296039565466344,-1,-2,0.00038296039565466344,4.4499998092651367 +2368,0,inf,-1,-2,inf,1.8700000047683716 +2369,35300,4.1076487832469866e-05,-1,-2,4.1076487832469866e-05,1.4500000476837158 +2370,77970,5.9510064602363855e-05,-1,-2,5.9510064602363855e-05,4.6399998664855957 +2371,13960,0.00018624641234055161,-1,-2,0.00018624641234055161,2.5999999046325684 +2372,45000,0.00010711111826822162,-1,-2,0.00010711111826822162,4.820000171661377 +2373,13370,7.9281970101874322e-05,-1,-2,7.9281970101874322e-05,1.059999942779541 +2374,80000,4.4374999561114237e-05,-1,-2,4.4374999561114237e-05,3.5499999523162842 +2375,37700,9.8143238574266434e-05,-1,-2,9.8143238574266434e-05,3.7000000476837158 +2376,17700,0.00024745764676481485,-1,-2,0.00024745764676481485,4.380000114440918 +2377,10900,0.00025412844843231142,-1,-2,0.00025412844843231142,2.7699999809265137 +2378,100500,4.2288556869607419e-05,-1,-2,4.2288556869607419e-05,4.25 +2379,0,inf,-1,-2,inf,3.8399999141693115 +2380,0,inf,-1,-2,inf,1.8700000047683716 +2381,147500,1.8305085177416913e-05,-1,-2,1.8305085177416913e-05,2.7000000476837158 +2382,325000,1.8553846530267037e-05,-1,-2,1.8553846530267037e-05,6.0300002098083496 +2383,3500,0.0015285713598132133,-1,-2,0.0015285713598132133,5.3499999046325684 +2384,0,inf,-1,-2,inf,1.3999999761581421 +2385,118600,5.3541312809102237e-05,-1,-2,5.3541312809102237e-05,6.3499999046325684 +2386,1700,0.0016647058073431253,-1,-2,0.0016647058073431253,2.8299999237060547 +2387,17000,0.00015588235692121089,-1,-2,0.00015588235692121089,2.6500000953674316 +2388,79000,5.1772152801277116e-05,-1,-2,5.1772152801277116e-05,4.0900001525878906 +2389,60000,0.0001140000022132881,-1,-2,0.0001140000022132881,6.8400001525878906 +2390,14000,0.00011857142817461863,-1,-2,0.00011857142817461863,1.6599999666213989 +2391,169700,2.2333530068863183e-05,-1,-2,2.2333530068863183e-05,3.7899999618530273 +2392,24000,0.00020875000336673111,-1,-2,0.00020875000336673111,5.0100002288818359 +2393,58050,4.6683893742738292e-05,-1,-2,4.6683893742738292e-05,2.7100000381469727 +2394,8100,0.00034814813989214599,-1,-2,0.00034814813989214599,2.8199999332427979 +2395,51480,1.5734265616629273e-05,-1,-2,1.5734265616629273e-05,0.81000000238418579 +2396,56000,7.6249998528510332e-05,-1,-2,7.6249998528510332e-05,4.2699999809265137 +2397,68400,2.0614033928723074e-05,-1,-2,2.0614033928723074e-05,1.4099999666213989 +2398,61500,1.7560976630193181e-05,-1,-2,1.7560976630193181e-05,1.0800000429153442 +2399,26000,0.00012346153380349278,-1,-2,0.00012346153380349278,3.2100000381469727 +2400,0,inf,-1,-2,inf,2.9500000476837158 +2401,325000,8.5230767581379041e-06,-1,-2,8.5230767581379041e-06,2.7699999809265137 +2402,0,inf,-1,-2,inf,2.380000114440918 +2403,41600,8.5336534539237618e-05,-1,-2,8.5336534539237618e-05,3.5499999523162842 +2404,23100,0.00013593073526863009,-1,-2,0.00013593073526863009,3.1400001049041748 +2405,8300,8.0722893471829593e-05,-1,-2,8.0722893471829593e-05,0.67000001668930054 +2406,84000,3.428571653785184e-05,-1,-2,3.428571653785184e-05,2.880000114440918 +2407,62000,6.0161291912663728e-05,-1,-2,6.0161291912663728e-05,3.7300000190734863 +2408,8500,0.00047999998787418008,-1,-2,0.00047999998787418008,4.0799999237060547 +2409,0,inf,-1,-2,inf,3.5099999904632568 +2410,7000,0.00077571428846567869,-1,-2,0.00077571428846567869,5.429999828338623 +2411,16700,8.3832332165911794e-05,-1,-2,8.3832332165911794e-05,1.3999999761581421 +2412,39400,7.1827409556135535e-05,-1,-2,7.1827409556135535e-05,2.8299999237060547 +2413,15500,0.00029161290149204433,-1,-2,0.00029161290149204433,4.5199999809265137 +2414,41800,2.5358849597978406e-05,-1,-2,2.5358849597978406e-05,1.059999942779541 +2415,8300,0.00035662652226164937,-1,-2,0.00035662652226164937,2.9600000381469727 +2416,13800,0.00026376813184469938,-1,-2,0.00026376813184469938,3.6400001049041748 +2417,2400,0.0018333334010094404,-1,-2,0.0018333334010094404,4.4000000953674316 +2418,14000,0.00013428571401163936,-1,-2,0.00013428571401163936,1.8799999952316284 +2419,166000,2.6084337150678039e-05,-1,-2,2.6084337150678039e-05,4.3299999237060547 +2420,6000,0.00064666668185964227,-1,-2,0.00064666668185964227,3.880000114440918 +2421,10200,0.00028627453139051795,-1,-2,0.00028627453139051795,2.9200000762939453 +2422,17130,0.00013601867249235511,-1,-2,0.00013601867249235511,2.3299999237060547 +2423,14100,0.00023333332501351833,-1,-2,0.00023333332501351833,3.2899999618530273 +2424,9900,0.00056363636394962668,-1,-2,0.00056363636394962668,5.5799999237060547 +2425,114000,2.4298245989484712e-05,-1,-2,2.4298245989484712e-05,2.7699999809265137 +2426,10000,0.00027000001864507794,-1,-2,0.00027000001864507794,2.7000000476837158 +2427,0,inf,-1,-2,inf,2.1700000762939453 +2428,4300,0.00074418605072423816,-1,-2,0.00074418605072423816,3.2000000476837158 +2429,8400,0.00042619046871550381,-1,-2,0.00042619046871550381,3.5799999237060547 +2430,7300,0.00049726030556485057,-1,-2,0.00049726030556485057,3.630000114440918 +2431,6200,0.00046290320460684597,-1,-2,0.00046290320460684597,2.869999885559082 +2432,0,inf,-1,-2,inf,3.3299999237060547 +2433,43950,3.7770190829178318e-05,-1,-2,3.7770190829178318e-05,1.6599999666213989 +2434,43600,6.5825683122966439e-05,-1,-2,6.5825683122966439e-05,2.869999885559082 +2435,82040,3.376401582499966e-05,-1,-2,3.376401582499966e-05,2.7699999809265137 +2436,14400,0.00031249999301508069,-1,-2,0.00031249999301508069,4.5 +2437,62000,8.0322577559854835e-05,-1,-2,8.0322577559854835e-05,4.9800000190734863 +2438,8000,0.00062750000506639481,-1,-2,0.00062750000506639481,5.0199999809265137 +2439,20100,0.00023980099649634212,-1,-2,0.00023980099649634212,4.820000171661377 +2440,8300,0.00065060239285230637,-1,-2,0.00065060239285230637,5.4000000953674316 +2441,29704,5.3191492042969912e-05,-1,-2,5.3191492042969912e-05,1.5800000429153442 +2442,45000,4.0222221286967397e-05,-1,-2,4.0222221286967397e-05,1.809999942779541 +2443,35300,0.00011019829980796203,-1,-2,0.00011019829980796203,3.8900001049041748 +2444,5000,0.00069600000279024243,-1,-2,0.00069600000279024243,3.4800000190734863 +2445,52030,0.00012896406406071037,-1,-2,0.00012896406406071037,6.7100000381469727 +2446,0,inf,-1,-2,inf,3.0699999332427979 +2447,7000,0.00011714285938069224,-1,-2,0.00011714285938069224,0.81999999284744263 +2448,700,0.001857142779044807,-1,-2,0.001857142779044807,1.2999999523162842 +2449,5000,0.00081800005864351988,-1,-2,0.00081800005864351988,4.0900001525878906 +2450,77100,3.4500648325774819e-05,-1,-2,3.4500648325774819e-05,2.6600000858306885 +2451,66000,0.00010696969548007473,-1,-2,0.00010696969548007473,7.059999942779541 +2452,74100,4.0890688978834078e-05,-1,-2,4.0890688978834078e-05,3.0299999713897705 +2453,17800,0.00015056179836392403,-1,-2,0.00015056179836392403,2.6800000667572021 +2454,21400,0.00012149532267358154,-1,-2,0.00012149532267358154,2.5999999046325684 +2455,10000,0.00027399999089539051,-1,-2,0.00027399999089539051,2.7400000095367432 +2456,9400,0.00042553190723992884,-1,-2,0.00042553190723992884,4 +2457,4200,0.00067380949622020125,-1,-2,0.00067380949622020125,2.8299999237060547 +2458,37000,7.1351350925397128e-05,-1,-2,7.1351350925397128e-05,2.6400001049041748 +2459,17100,0.00014444444968830794,-1,-2,0.00014444444968830794,2.4700000286102295 +2460,388000,1.9458762835711241e-05,-1,-2,1.9458762835711241e-05,7.5500001907348633 +2461,66300,1.3725491044169758e-05,-1,-2,1.3725491044169758e-05,0.9100000262260437 +2462,8100,0.00021728394494857639,-1,-2,0.00021728394494857639,1.7599999904632568 +2463,7700,0.00056623376440256834,-1,-2,0.00056623376440256834,4.3600001335144043 +2464,0,inf,-1,-2,inf,3.3199999332427979 +2465,41600,4.4951924792258069e-05,-1,-2,4.4951924792258069e-05,1.8700000047683716 +2466,66850,4.1735227569006383e-05,-1,-2,4.1735227569006383e-05,2.7899999618530273 +2467,110250,4.5804990804754198e-05,-1,-2,4.5804990804754198e-05,5.0500001907348633 +2468,0,inf,-1,-2,inf,3.380000114440918 +2469,45600,0.00010350876982556656,-1,-2,0.00010350876982556656,4.7199997901916504 +2470,68000,0.00011176470434293151,-1,-2,0.00011176470434293151,7.5999999046325684 +2471,9220,0.00045010846224613488,-1,-2,0.00045010846224613488,4.1500000953674316 +2472,44000,1.5227273252094164e-05,-1,-2,1.5227273252094164e-05,0.67000001668930054 +2473,11400,7.9824560089036822e-05,-1,-2,7.9824560089036822e-05,0.9100000262260437 +2474,86500,3.0867053283145651e-05,-1,-2,3.0867053283145651e-05,2.6700000762939453 +2475,40000,8.8749999122228473e-05,-1,-2,8.8749999122228473e-05,3.5499999523162842 +2476,25000,0.00021759999799542129,-1,-2,0.00021759999799542129,5.440000057220459 +2477,4000,0.00083499995525926352,-1,-2,0.00083499995525926352,3.3399999141693115 +2478,42500,7.0588233938906342e-05,-1,-2,7.0588233938906342e-05,3 +2479,0,inf,-1,-2,inf,2.7999999523162842 +2480,6430,0.00058786937734112144,-1,-2,0.00058786937734112144,3.7799999713897705 +2481,8100,0.00080740742851048708,-1,-2,0.00080740742851048708,6.5399999618530273 +2482,370,0.0083513511344790459,-1,-2,0.0083513511344790459,3.0899999141693115 +2483,130000,4.292307494324632e-05,-1,-2,4.292307494324632e-05,5.5799999237060547 +2484,0,inf,-1,-2,inf,2.7599999904632568 +2485,14500,0.00021655173623003066,-1,-2,0.00021655173623003066,3.1400001049041748 +2486,38400,8.3593753515742719e-05,-1,-2,8.3593753515742719e-05,3.2100000381469727 +2487,180000,2.4888888219720684e-05,-1,-2,2.4888888219720684e-05,4.4800000190734863 +2488,8200,0.00051829265430569649,-1,-2,0.00051829265430569649,4.25 +2489,68400,3.4210526791866869e-05,-1,-2,3.4210526791866869e-05,2.3399999141693115 +2490,10200,0.00024509805371053517,-1,-2,0.00024509805371053517,2.5 +2491,141200,1.5934843759168871e-05,-1,-2,1.5934843759168871e-05,2.25 +2492,40000,3.7500001781154424e-05,-1,-2,3.7500001781154424e-05,1.5 +2493,351000,5.9544158830249216e-06,-1,-2,5.9544158830249216e-06,2.0899999141693115 +2494,8700,0.00041264365427196026,-1,-2,0.00041264365427196026,3.5899999141693115 +2495,127000,2.1338582882890478e-05,-1,-2,2.1338582882890478e-05,2.7100000381469727 +2496,43700,7.1853552071843296e-05,-1,-2,7.1853552071843296e-05,3.1400001049041748 +2497,8300,0.00068795180413872004,-1,-2,0.00068795180413872004,5.7100000381469727 +2498,23400,0.00024059829593170434,-1,-2,0.00024059829593170434,5.630000114440918 +2499,165000,3.2060605008155107e-05,-1,-2,3.2060605008155107e-05,5.2899999618530273 +2500,75000,3.1999999919207767e-05,-1,-2,3.1999999919207767e-05,2.4000000953674316 +2501,17000,0.00015294116747099906,-1,-2,0.00015294116747099906,2.5999999046325684 +2502,218000,3.1926607334753498e-05,-1,-2,3.1926607334753498e-05,6.9600000381469727 +2503,33500,5.8805970184039325e-05,-1,-2,5.8805970184039325e-05,1.9700000286102295 +2504,6300,0.00054285716032609344,-1,-2,0.00054285716032609344,3.4200000762939453 +2505,0,inf,-1,-2,inf,2.6500000953674316 +2506,7900,0.00033544303732924163,-1,-2,0.00033544303732924163,2.6500000953674316 +2507,200,0.010400000028312206,-1,-2,0.010400000028312206,2.0799999237060547 +2508,19400,0.0001041237119352445,-1,-2,0.0001041237119352445,2.0199999809265137 +2509,68300,3.0453878935077228e-05,-1,-2,3.0453878935077228e-05,2.0799999237060547 +2510,18800,0.0002207446814281866,-1,-2,0.0002207446814281866,4.1500000953674316 +2511,0,inf,-1,-2,inf,6.5399999618530273 +2512,26000,0.00026038460782729089,-1,-2,0.00026038460782729089,6.7699999809265137 +2513,9400,0.00025425534113310277,-1,-2,0.00025425534113310277,2.3900001049041748 +2514,106700,3.7956891901558265e-05,-1,-2,3.7956891901558265e-05,4.0500001907348633 +2515,36020,1.887840153358411e-05,-1,-2,1.887840153358411e-05,0.68000000715255737 +2516,29000,0.00014103448484092951,-1,-2,0.00014103448484092951,4.0900001525878906 +2517,69900,6.8383407779037952e-05,-1,-2,6.8383407779037952e-05,4.7800002098083496 +2518,39000,5.5897438869578764e-05,-1,-2,5.5897438869578764e-05,2.1800000667572021 +2519,70200,6.1253563217178453e-06,-1,-2,6.1253563217178453e-06,0.43000000715255737 +2520,4000,0.0010175000643357635,-1,-2,0.0010175000643357635,4.070000171661377 +2521,0,inf,-1,-2,inf,1.9700000286102295 +2522,153800,2.5292589270975441e-05,-1,-2,2.5292589270975441e-05,3.8900001049041748 +2523,13900,4.8201440222328529e-05,-1,-2,4.8201440222328529e-05,0.67000001668930054 +2524,56500,6.0884955018991604e-05,-1,-2,6.0884955018991604e-05,3.440000057220459 +2525,9800,0.00028163264505565166,-1,-2,0.00028163264505565166,2.7599999904632568 +2526,13000,0.00016846154176164418,-1,-2,0.00016846154176164418,2.190000057220459 +2527,24800,6.048387149348855e-05,-1,-2,6.048387149348855e-05,1.5 +2528,8100,0.00053580250823870301,-1,-2,0.00053580250823870301,4.3400001525878906 +2529,89000,3.4044944186462089e-05,-1,-2,3.4044944186462089e-05,3.0299999713897705 +2530,0,inf,-1,-2,inf,7.619999885559082 +2531,26600,6.0526315792230889e-05,-1,-2,6.0526315792230889e-05,1.6100000143051147 +2532,7800,0.00033846154110506177,-1,-2,0.00033846154110506177,2.6400001049041748 +2533,652070,2.2236877157411072e-06,-1,-2,2.2236877157411072e-06,1.4500000476837158 +2534,15000,0.00019733334193006158,-1,-2,0.00019733334193006158,2.9600000381469727 +2535,100000,4.5700002374360338e-05,-1,-2,4.5700002374360338e-05,4.570000171661377 +2536,8500,0.00031176471384242177,-1,-2,0.00031176471384242177,2.6500000953674316 +2537,21000,0.0002195238193962723,-1,-2,0.0002195238193962723,4.6100001335144043 +2538,22700,0.00023524230346083641,-1,-2,0.00023524230346083641,5.3400001525878906 +2539,16800,0.00019940476340707392,-1,-2,0.00019940476340707392,3.3499999046325684 +2540,20000,0.00022799998987466097,-1,-2,0.00022799998987466097,4.559999942779541 +2541,3700,0.0011162162991240621,-1,-2,0.0011162162991240621,4.130000114440918 +2542,22870,0.00025972889852710068,-1,-2,0.00025972889852710068,5.940000057220459 +2543,28000,7.5357136665843427e-05,-1,-2,7.5357136665843427e-05,2.1099998950958252 +2544,8800,0.000353409064700827,-1,-2,0.000353409064700827,3.1099998950958252 +2545,32000,0.00016718749247957021,-1,-2,0.00016718749247957021,5.3499999046325684 +2546,74000,2.391891939623747e-05,-1,-2,2.391891939623747e-05,1.7699999809265137 +2547,317700,8.718917342775967e-06,-1,-2,8.718917342775967e-06,2.7699999809265137 +2548,70000,4.742856981465593e-05,-1,-2,4.742856981465593e-05,3.3199999332427979 +2549,20500,0.00018878048285841942,-1,-2,0.00018878048285841942,3.869999885559082 +2550,14400,0.00034791667712852359,-1,-2,0.00034791667712852359,5.0100002288818359 +2551,158000,1.0506329090276267e-05,-1,-2,1.0506329090276267e-05,1.6599999666213989 +2552,6580,0.00041945287375710905,-1,-2,0.00041945287375710905,2.7599999904632568 +2553,29350,7.8705277701374143e-05,-1,-2,7.8705277701374143e-05,2.309999942779541 +2554,65000,6.4307692809961736e-05,-1,-2,6.4307692809961736e-05,4.179999828338623 +2555,28000,0.00017178570851683617,-1,-2,0.00017178570851683617,4.809999942779541 +2556,23000,0.00027260868228040636,-1,-2,0.00027260868228040636,6.2699999809265137 +2557,26030,0.00017825585382524878,-1,-2,0.00017825585382524878,4.6399998664855957 +2558,146220,1.4635481420555152e-05,-1,-2,1.4635481420555152e-05,2.1400001049041748 +2559,19670,0.00020030503219459206,-1,-2,0.00020030503219459206,3.940000057220459 +2560,0,inf,-1,-2,inf,5.679999828338623 +2561,32000,0.00010906250099651515,-1,-2,0.00010906250099651515,3.4900000095367432 +2562,15300,0.0002352941082790494,-1,-2,0.0002352941082790494,3.5999999046325684 +2563,35000,5.5714288464514539e-05,-1,-2,5.5714288464514539e-05,1.9500000476837158 +2564,50000,3.980000110459514e-05,-1,-2,3.980000110459514e-05,1.9900000095367432 +2565,35000,5.6285716709680855e-05,-1,-2,5.6285716709680855e-05,1.9700000286102295 +2566,41400,8.0434780102223158e-05,-1,-2,8.0434780102223158e-05,3.3299999237060547 +2567,1500,0.002173333428800106,-1,-2,0.002173333428800106,3.2599999904632568 +2568,85800,1.2354311365925241e-05,-1,-2,1.2354311365925241e-05,1.059999942779541 +2569,32500,8.8923079601954669e-05,-1,-2,8.8923079601954669e-05,2.8900001049041748 +2570,0,inf,-1,-2,inf,2.6600000858306885 +2571,61060,5.4372747399611399e-05,-1,-2,5.4372747399611399e-05,3.3199999332427979 +2572,10260,0.00061013648519292474,-1,-2,0.00061013648519292474,6.2600002288818359 +2573,7400,0.00071891892002895474,-1,-2,0.00071891892002895474,5.320000171661377 +2574,35000,0.00011085714504588395,-1,-2,0.00011085714504588395,3.880000114440918 +2575,0,inf,-1,-2,inf,1.6499999761581421 +2576,33000,3.2727275538491085e-05,-1,-2,3.2727275538491085e-05,1.0800000429153442 +2577,28800,0.00014340277994051576,-1,-2,0.00014340277994051576,4.130000114440918 +2578,680,0.0092352945357561111,-1,-2,0.0092352945357561111,6.2800002098083496 +2579,57000,2.5964913220377639e-05,-1,-2,2.5964913220377639e-05,1.4800000190734863 +2580,64000,7.1249996835831553e-05,-1,-2,7.1249996835831553e-05,4.559999942779541 +2581,14000,0.0002899999963119626,-1,-2,0.0002899999963119626,4.059999942779541 +2582,680,0.004117647185921669,-1,-2,0.004117647185921669,2.7999999523162842 +2583,0,inf,-1,-2,inf,3.8499999046325684 +2584,18600,0.0001419354957761243,-1,-2,0.0001419354957761243,2.6400001049041748 +2585,8400,0.00044642857392318547,-1,-2,0.00044642857392318547,3.75 +2586,50000,4.5000000682193786e-05,-1,-2,4.5000000682193786e-05,2.25 +2587,15800,0.00028291138005442917,-1,-2,0.00028291138005442917,4.4699997901916504 +2588,32300,0.00011455108324298635,-1,-2,0.00011455108324298635,3.7000000476837158 +2589,66850,3.5901273804483935e-05,-1,-2,3.5901273804483935e-05,2.4000000953674316 +2590,30800,0.00014772727445233613,-1,-2,0.00014772727445233613,4.5500001907348633 +2591,33500,6.7761196987703443e-05,-1,-2,6.7761196987703443e-05,2.2699999809265137 +2592,24300,4.3621395889203995e-05,-1,-2,4.3621395889203995e-05,1.059999942779541 +2593,24900,0.00017068273155018687,-1,-2,0.00017068273155018687,4.25 +2594,106730,3.401105641387403e-05,-1,-2,3.401105641387403e-05,3.630000114440918 +2595,0,inf,-1,-2,inf,2.309999942779541 +2596,8200,0.00054634147090837359,-1,-2,0.00054634147090837359,4.4800000190734863 +2597,57500,5.5826087191235274e-05,-1,-2,5.5826087191235274e-05,3.2100000381469727 +2598,11200,0.00040446431376039982,-1,-2,0.00040446431376039982,4.5300002098083496 +2599,53000,1.2264150427654386e-05,-1,-2,1.2264150427654386e-05,0.64999997615814209 +2600,69960,6.6895365307573229e-05,-1,-2,6.6895365307573229e-05,4.679999828338623 +2601,7800,0.00067948718788102269,-1,-2,0.00067948718788102269,5.3000001907348633 +2602,12000,0.00052333337953314185,-1,-2,0.00052333337953314185,6.2800002098083496 +2603,0,inf,-1,-2,inf,1.4800000190734863 +2604,0,inf,-1,-2,inf,4.9800000190734863 +2605,15000,0.00029600001289509237,-1,-2,0.00029600001289509237,4.440000057220459 +2606,8400,0.00049761903937906027,-1,-2,0.00049761903937906027,4.179999828338623 +2607,28200,0.00014680851018056273,-1,-2,0.00014680851018056273,4.1399998664855957 +2608,9000,0.00044111110037192702,-1,-2,0.00044111110037192702,3.9700000286102295 +2609,205400,7.7896784205222502e-06,-1,-2,7.7896784205222502e-06,1.6000000238418579 +2610,81000,4.049382550874725e-05,-1,-2,4.049382550874725e-05,3.2799999713897705 +2611,0,inf,-1,-2,inf,6.0999999046325684 +2612,11200,0.00027589284582063556,-1,-2,0.00027589284582063556,3.0899999141693115 +2613,80000,6.9125002482905984e-05,-1,-2,6.9125002482905984e-05,5.5300002098083496 +2614,61000,2.7704918466042727e-05,-1,-2,2.7704918466042727e-05,1.690000057220459 +2615,10800,0.00044907405390404165,-1,-2,0.00044907405390404165,4.8499999046325684 +2616,48140,8.9322811618330888e-06,-1,-2,8.9322811618330888e-06,0.43000000715255737 +2617,74100,1.1875843483721837e-05,-1,-2,1.1875843483721837e-05,0.87999999523162842 +2618,0,inf,-1,-2,inf,4.9899997711181641 +2619,73500,7.210884359665215e-05,-1,-2,7.210884359665215e-05,5.3000001907348633 +2620,92500,6.1621620261576027e-05,-1,-2,6.1621620261576027e-05,5.6999998092651367 +2621,76900,4.0832252125255764e-05,-1,-2,4.0832252125255764e-05,3.1400001049041748 +2622,43600,4.2660551116568968e-05,-1,-2,4.2660551116568968e-05,1.8600000143051147 +2623,36020,7.4958355980925262e-05,-1,-2,7.4958355980925262e-05,2.7000000476837158 +2624,14800,0.00027567567303776741,-1,-2,0.00027567567303776741,4.0799999237060547 +2625,81000,6.0246915381867439e-05,-1,-2,6.0246915381867439e-05,4.880000114440918 +2626,205000,2.726829370658379e-05,-1,-2,2.726829370658379e-05,5.5900001525878906 +2627,60500,5.0909089623019099e-05,-1,-2,5.0909089623019099e-05,3.0799999237060547 +2628,24000,0.0001808333327062428,-1,-2,0.0001808333327062428,4.3400001525878906 +2629,8420,0.00039548691711388528,-1,-2,0.00039548691711388528,3.3299999237060547 +2630,0,inf,-1,-2,inf,4.2199997901916504 +2631,44680,0.00011638316209428012,-1,-2,0.00011638316209428012,5.1999998092651367 +2632,7500,0.00073733337922021747,-1,-2,0.00073733337922021747,5.5300002098083496 +2633,107600,2.2769516363041475e-05,-1,-2,2.2769516363041475e-05,2.4500000476837158 +2634,24000,0.00016708334442228079,-1,-2,0.00016708334442228079,4.0100002288818359 +2635,42000,0.00012785714352503419,-1,-2,0.00012785714352503419,5.369999885559082 +2636,77100,2.1400777768576518e-05,-1,-2,2.1400777768576518e-05,1.6499999761581421 +2637,33050,9.0468987764324993e-05,-1,-2,9.0468987764324993e-05,2.9900000095367432 +2638,136600,2.6573939976515248e-05,-1,-2,2.6573939976515248e-05,3.630000114440918 +2639,0,inf,-1,-2,inf,5.6999998092651367 +2640,9200,0.00014456521603278816,-1,-2,0.00014456521603278816,1.3300000429153442 +2641,61000,2.3934426280902699e-05,-1,-2,2.3934426280902699e-05,1.4600000381469727 +2642,11000,0.00035272727836854756,-1,-2,0.00035272727836854756,3.880000114440918 +2643,21320,0.00012992495612706989,-1,-2,0.00012992495612706989,2.7699999809265137 +2644,6580,0.00046200607903301716,-1,-2,0.00046200607903301716,3.0399999618530273 +2645,123000,2.5447156076552346e-05,-1,-2,2.5447156076552346e-05,3.130000114440918 +2646,190000,3.0684208468301222e-05,-1,-2,3.0684208468301222e-05,5.8299999237060547 +2647,193000,1.9170984160155058e-05,-1,-2,1.9170984160155058e-05,3.7000000476837158 +2648,32000,9.0937501227017492e-05,-1,-2,9.0937501227017492e-05,2.9100000858306885 +2649,115750,4.855291626881808e-05,-1,-2,4.855291626881808e-05,5.619999885559082 +2650,0,inf,-1,-2,inf,3.7699999809265137 +2651,13100,0.00047709923819638789,-1,-2,0.00047709923819638789,6.25 +2652,100000,5.5399999837391078e-05,-1,-2,5.5399999837391078e-05,5.5399999618530273 +2653,5040,0.00062301591970026493,-1,-2,0.00062301591970026493,3.1400001049041748 +2654,0,inf,-1,-2,inf,4.679999828338623 +2655,630,0.0038730159867554903,-1,-2,0.0038730159867554903,2.440000057220459 +2656,7900,0.00031012657564133406,-1,-2,0.00031012657564133406,2.4500000476837158 +2657,57400,6.5679443650878966e-05,-1,-2,6.5679443650878966e-05,3.7699999809265137 +2658,76000,1.0789473890326917e-05,-1,-2,1.0789473890326917e-05,0.81999999284744263 +2659,130000,3.2538460800424218e-05,-1,-2,3.2538460800424218e-05,4.2300000190734863 +2660,41400,8.6231884779408574e-05,-1,-2,8.6231884779408574e-05,3.5699999332427979 +2661,117000,3.5982906410936266e-05,-1,-2,3.5982906410936266e-05,4.2100000381469727 +2662,0,inf,-1,-2,inf,2.1800000667572021 +2663,190000,2.3578946638735943e-05,-1,-2,2.3578946638735943e-05,4.4800000190734863 +2664,103400,2.6305609935661778e-05,-1,-2,2.6305609935661778e-05,2.7200000286102295 +2665,6900,0.00042173915426246822,-1,-2,0.00042173915426246822,2.9100000858306885 +2666,24600,9.1463414719328284e-05,-1,-2,9.1463414719328284e-05,2.25 +2667,11900,0.00043109245598316193,-1,-2,0.00043109245598316193,5.130000114440918 +2668,18800,0.00011223403998883441,-1,-2,0.00011223403998883441,2.1099998950958252 +2669,182500,2.3287671865546145e-05,-1,-2,2.3287671865546145e-05,4.25 +2670,112000,1.6874999346327968e-05,-1,-2,1.6874999346327968e-05,1.8899999856948853 +2671,14200,0.00034225353738293052,-1,-2,0.00034225353738293052,4.8600001335144043 +2672,0,inf,-1,-2,inf,3.119999885559082 +2673,8100,0.00037407406489364803,-1,-2,0.00037407406489364803,3.0299999713897705 +2674,161500,1.6346750271623023e-05,-1,-2,1.6346750271623023e-05,2.6400001049041748 +2675,153800,3.1469440727960318e-05,-1,-2,3.1469440727960318e-05,4.8400001525878906 +2676,9500,0.0003926315694116056,-1,-2,0.0003926315694116056,3.7300000190734863 +2677,47900,9.1440502728801221e-05,-1,-2,9.1440502728801221e-05,4.380000114440918 +2678,16000,9.2499998572748154e-05,-1,-2,9.2499998572748154e-05,1.4800000190734863 +2679,0,inf,-1,-2,inf,2.25 +2680,75000,5.4000003729015589e-05,-1,-2,5.4000003729015589e-05,4.0500001907348633 +2681,28000,0.00018535714480094612,-1,-2,0.00018535714480094612,5.190000057220459 +2682,0,inf,-1,-2,inf,3.1400001049041748 +2683,146220,1.8191765775554813e-05,-1,-2,1.8191765775554813e-05,2.6600000858306885 +2684,27350,0.00013016453885938972,-1,-2,0.00013016453885938972,3.559999942779541 +2685,107200,4.4682834413833916e-05,-1,-2,4.4682834413833916e-05,4.7899999618530273 +2686,117000,3.1452993425773457e-05,-1,-2,3.1452993425773457e-05,3.6800000667572021 +2687,12000,0.00012333333143033087,-1,-2,0.00012333333143033087,1.4800000190734863 +2688,28700,9.3379792815539986e-05,-1,-2,9.3379792815539986e-05,2.6800000667572021 +2689,10000,0.0003279999946244061,-1,-2,0.0003279999946244061,3.2799999713897705 +2690,37700,0.00010663129796739668,-1,-2,0.00010663129796739668,4.0199999809265137 +2691,44500,4.6966291847638786e-05,-1,-2,4.6966291847638786e-05,2.0899999141693115 +2692,53000,0.00010207547165919095,-1,-2,0.00010207547165919095,5.4099998474121094 +2693,35300,5.6940509239211679e-05,-1,-2,5.6940509239211679e-05,2.0099999904632568 +2694,22500,0.00018666665710043162,-1,-2,0.00018666665710043162,4.1999998092651367 +2695,7600,0.00070394732756540179,-1,-2,0.00070394732756540179,5.3499999046325684 +2696,8400,0.00044642857392318547,-1,-2,0.00044642857392318547,3.75 +2697,1700,0.0014235294656828046,-1,-2,0.0014235294656828046,2.4200000762939453 +2698,96000,3.7916666769888252e-05,-1,-2,3.7916666769888252e-05,3.6400001049041748 +2699,72000,4.1944444092223421e-05,-1,-2,4.1944444092223421e-05,3.0199999809265137 +2700,146220,4.1376009903615341e-05,-1,-2,4.1376009903615341e-05,6.0500001907348633 +2701,84400,4.5142180169932544e-05,-1,-2,4.5142180169932544e-05,3.809999942779541 +2702,0,inf,-1,-2,inf,2.7200000286102295 +2703,55000,1.2363636415102519e-05,-1,-2,1.2363636415102519e-05,0.68000000715255737 +2704,21000,0.00023904761474113911,-1,-2,0.00023904761474113911,5.0199999809265137 +2705,2400,0.00089583336375653744,-1,-2,0.00089583336375653744,2.1500000953674316 +2706,0,inf,-1,-2,inf,4.0900001525878906 +2707,17130,0.00024109749938361347,-1,-2,0.00024109749938361347,4.130000114440918 +2708,13250,0.00040603775414638221,-1,-2,0.00040603775414638221,5.380000114440918 +2709,216700,2.2150439690449275e-05,-1,-2,2.2150439690449275e-05,4.8000001907348633 +2710,103000,1.3689320439880248e-05,-1,-2,1.3689320439880248e-05,1.4099999666213989 +2711,21400,7.7102806244511157e-05,-1,-2,7.7102806244511157e-05,1.6499999761581421 +2712,0,inf,-1,-2,inf,4.2199997901916504 +2713,7900,0.00013164556003175676,-1,-2,0.00013164556003175676,1.0399999618530273 +2714,0,inf,-1,-2,inf,2.7400000095367432 +2715,8050,0.00041242234874516726,-1,-2,0.00041242234874516726,3.3199999332427979 +2716,118500,2.0337552996352315e-05,-1,-2,2.0337552996352315e-05,2.4100000858306885 +2717,28100,5.6227760069305077e-05,-1,-2,5.6227760069305077e-05,1.5800000429153442 +2718,55500,5.5315314966719598e-05,-1,-2,5.5315314966719598e-05,3.0699999332427979 +2719,365300,3.9693404687568545e-06,-1,-2,3.9693404687568545e-06,1.4500000476837158 +2720,23000,9.2173904704395682e-05,-1,-2,9.2173904704395682e-05,2.119999885559082 +2721,23000,0.00021826087322551757,-1,-2,0.00021826087322551757,5.0199999809265137 +2722,64900,6.1787366576027125e-05,-1,-2,6.1787366576027125e-05,4.0100002288818359 +2723,6400,0.0003499999875202775,-1,-2,0.0003499999875202775,2.2400000095367432 +2724,84400,2.2393363906303421e-05,-1,-2,2.2393363906303421e-05,1.8899999856948853 +2725,20000,0.00022600000374950469,-1,-2,0.00022600000374950469,4.5199999809265137 +2726,30,0.068999998271465302,-1,-2,0.068999998271465302,2.0699999332427979 +2727,35000,5.657142901327461e-05,-1,-2,5.657142901327461e-05,1.9800000190734863 +2728,40000,0.00010900000052060932,-1,-2,0.00010900000052060932,4.3600001335144043 +2729,85850,3.261502570239827e-05,-1,-2,3.261502570239827e-05,2.7999999523162842 +2730,37700,8.8063658040482551e-05,-1,-2,8.8063658040482551e-05,3.3199999332427979 +2731,74300,5.3432031563716009e-05,-1,-2,5.3432031563716009e-05,3.9700000286102295 +2732,108110,3.9774306060280651e-05,-1,-2,3.9774306060280651e-05,4.3000001907348633 +2733,204900,1.7276719518122263e-05,-1,-2,1.7276719518122263e-05,3.5399999618530273 +2734,20900,0.00010095693141920492,-1,-2,0.00010095693141920492,2.1099998950958252 +2735,8900,0.00031123595545068383,-1,-2,0.00031123595545068383,2.7699999809265137 +2736,9400,0.00041914894245564938,-1,-2,0.00041914894245564938,3.940000057220459 +2737,66000,2.1212121282587759e-05,-1,-2,2.1212121282587759e-05,1.3999999761581421 +2738,70000,1.8428570911055431e-05,-1,-2,1.8428570911055431e-05,1.2899999618530273 +2739,68000,8.2794118497986346e-05,-1,-2,8.2794118497986346e-05,5.630000114440918 +2740,1040,0.0027692308649420738,-1,-2,0.0027692308649420738,2.880000114440918 +2741,64300,4.0902024920796975e-05,-1,-2,4.0902024920796975e-05,2.630000114440918 +2742,7500,0.00061733333859592676,-1,-2,0.00061733333859592676,4.630000114440918 +2743,230000,2.3000000510364771e-05,-1,-2,2.3000000510364771e-05,5.2899999618530273 +2744,41300,4.5278451580088586e-05,-1,-2,4.5278451580088586e-05,1.8700000047683716 +2745,7700,0.00031688311719335616,-1,-2,0.00031688311719335616,2.440000057220459 +2746,43000,6.3023253460414708e-05,-1,-2,6.3023253460414708e-05,2.7100000381469727 +2747,35000,9.0571433247532696e-05,-1,-2,9.0571433247532696e-05,3.1700000762939453 +2748,21000,9.5714283816050738e-05,-1,-2,9.5714283816050738e-05,2.0099999904632568 +2749,325014,1.5630095731467009e-05,-1,-2,1.5630095731467009e-05,5.0799999237060547 +2750,8300,0.00041204818990081549,-1,-2,0.00041204818990081549,3.4200000762939453 +2751,11500,0.00038347824010998011,-1,-2,0.00038347824010998011,4.4099998474121094 +2752,38000,0.0001542105310363695,-1,-2,0.0001542105310363695,5.8600001335144043 +2753,3500,0.00049714284250512719,-1,-2,0.00049714284250512719,1.7400000095367432 +2754,57000,7.8947370639070868e-05,-1,-2,7.8947370639070868e-05,4.5 +2755,0,inf,-1,-2,inf,4.2600002288818359 +2756,7600,0.00074868422234430909,-1,-2,0.00074868422234430909,5.690000057220459 +2757,0,inf,-1,-2,inf,4.3000001907348633 +2758,61060,8.6799864220665768e-06,-1,-2,8.6799864220665768e-06,0.52999997138977051 +2759,21000,9.8095231805928051e-05,-1,-2,9.8095231805928051e-05,2.059999942779541 +2760,25000,0.00019239999528508633,-1,-2,0.00019239999528508633,4.809999942779541 +2761,10200,0.00025490194093436003,-1,-2,0.00025490194093436003,2.5999999046325684 +2762,26620,8.5274230514187366e-05,-1,-2,8.5274230514187366e-05,2.2699999809265137 +2763,0,inf,-1,-2,inf,2.940000057220459 +2764,49000,8.1632650108076632e-05,-1,-2,8.1632650108076632e-05,4 +2765,200000,1.4500000361294951e-05,-1,-2,1.4500000361294951e-05,2.9000000953674316 +2766,0,inf,-1,-2,inf,2.1099998950958252 +2767,0,inf,-1,-2,inf,3.7400000095367432 +2768,21600,7.7777775004506111e-05,-1,-2,7.7777775004506111e-05,1.6799999475479126 +2769,1500,0.0026133332867175341,-1,-2,0.0026133332867175341,3.9200000762939453 +2770,62000,8.0483863712288439e-05,-1,-2,8.0483863712288439e-05,4.9899997711181641 +2771,54400,4.5036766096018255e-05,-1,-2,4.5036766096018255e-05,2.4500000476837158 +2772,43700,3.0434783184318803e-05,-1,-2,3.0434783184318803e-05,1.3300000429153442 +2773,11900,0.00030924371094442904,-1,-2,0.00030924371094442904,3.6800000667572021 +2774,0,inf,-1,-2,inf,3.75 +2775,9000,0.00045555553515441716,-1,-2,0.00045555553515441716,4.0999999046325684 +2776,32000,0.00014937500236555934,-1,-2,0.00014937500236555934,4.7800002098083496 +2777,5000,0.00093199999537318945,-1,-2,0.00093199999537318945,4.6599998474121094 +2778,29000,0.00018551724497228861,-1,-2,0.00018551724497228861,5.380000114440918 +2779,39700,0.00011435768101364374,-1,-2,0.00011435768101364374,4.5399999618530273 +2780,68000,6.7794120695907623e-05,-1,-2,6.7794120695907623e-05,4.6100001335144043 +2781,12000,5.0833335990319028e-05,-1,-2,5.0833335990319028e-05,0.61000001430511475 +2782,79000,6.1898732383269817e-05,-1,-2,6.1898732383269817e-05,4.8899998664855957 +2783,242500,5.5670102483418304e-06,-1,-2,5.5670102483418304e-06,1.3500000238418579 +2784,7800,0.00072179490234702826,-1,-2,0.00072179490234702826,5.630000114440918 +2785,25700,0.00016031127597671002,-1,-2,0.00016031127597671002,4.119999885559082 +2786,0,inf,-1,-2,inf,0.38999998569488525 +2787,97000,3.7010308005847037e-05,-1,-2,3.7010308005847037e-05,3.5899999141693115 +2788,0,inf,-1,-2,inf,3.5199999809265137 +2789,0,inf,-1,-2,inf,2.4200000762939453 +2790,15000,0.00033999999868683517,-1,-2,0.00033999999868683517,5.0999999046325684 +2791,80000,2.5624998670537025e-05,-1,-2,2.5624998670537025e-05,2.0499999523162842 +2792,80000,8.4874998719897121e-05,-1,-2,8.4874998719897121e-05,6.7899999618530273 +2793,7600,0.00057105266023427248,-1,-2,0.00057105266023427248,4.3400001525878906 +2794,7700,0.00056623376440256834,-1,-2,0.00056623376440256834,4.3600001335144043 +2795,14300,0.00039370631566271186,-1,-2,0.00039370631566271186,5.630000114440918 +2796,43000,9.3488371931016445e-05,-1,-2,9.3488371931016445e-05,4.0199999809265137 +2797,106120,3.2604599255137146e-05,-1,-2,3.2604599255137146e-05,3.4600000381469727 +2798,76000,4.92105282319244e-05,-1,-2,4.92105282319244e-05,3.7400000095367432 +2799,32600,3.2515334169147536e-05,-1,-2,3.2515334169147536e-05,1.059999942779541 +2800,0,inf,-1,-2,inf,5.5900001525878906 +2801,121000,2.5289255063398741e-05,-1,-2,2.5289255063398741e-05,3.059999942779541 +2802,9900,0.00037676768261007965,-1,-2,0.00037676768261007965,3.7300000190734863 +2803,6800,0.00020588234474416822,-1,-2,0.00020588234474416822,1.3999999761581421 +2804,0,inf,-1,-2,inf,3.3399999141693115 +2805,0,inf,-1,-2,inf,5.119999885559082 +2806,90400,3.0752213206142187e-05,-1,-2,3.0752213206142187e-05,2.7799999713897705 +2807,26120,0.0001071975493687205,-1,-2,0.0001071975493687205,2.7999999523162842 +2808,163000,3.3006133890012279e-05,-1,-2,3.3006133890012279e-05,5.380000114440918 +2809,79100,4.2098607082152739e-05,-1,-2,4.2098607082152739e-05,3.3299999237060547 +2810,6400,0.00039375000051222742,-1,-2,0.00039375000051222742,2.5199999809265137 +2811,9000,0.00048777775373309851,-1,-2,0.00048777775373309851,4.3899998664855957 +2812,0,inf,-1,-2,inf,1.4500000476837158 +2813,75000,2.6666666599339806e-05,-1,-2,2.6666666599339806e-05,2 +2814,160000,2.1562500478466973e-05,-1,-2,2.1562500478466973e-05,3.4500000476837158 +2815,35400,0.00011723164061550051,-1,-2,0.00011723164061550051,4.1500000953674316 +2816,107200,4.1138056985801086e-05,-1,-2,4.1138056985801086e-05,4.4099998474121094 +2817,1700,0.0028588236309587955,-1,-2,0.0028588236309587955,4.8600001335144043 +2818,182300,1.2890838661405724e-05,-1,-2,1.2890838661405724e-05,2.3499999046325684 +2819,77000,1.0519480383663904e-05,-1,-2,1.0519480383663904e-05,0.81000000238418579 +2820,69800,4.6275072236312553e-05,-1,-2,4.6275072236312553e-05,3.2300000190734863 +2821,16400,0.0001896341418614611,-1,-2,0.0001896341418614611,3.1099998950958252 +2822,112000,4.26785736635793e-05,-1,-2,4.26785736635793e-05,4.7800002098083496 +2823,22500,0.00026444444665685296,-1,-2,0.00026444444665685296,5.9499998092651367 +2824,47000,6.872340600239113e-05,-1,-2,6.872340600239113e-05,3.2300000190734863 +2825,4000,0.0014249999076128006,-1,-2,0.0014249999076128006,5.6999998092651367 +2826,4400,0.00014772727445233613,-1,-2,0.00014772727445233613,0.64999997615814209 +2827,25400,0.00023385827080346644,-1,-2,0.00023385827080346644,5.940000057220459 +2828,127000,1.6456691810162738e-05,-1,-2,1.6456691810162738e-05,2.0899999141693115 +2829,12630,0.0002090261405101046,-1,-2,0.0002090261405101046,2.6400001049041748 +2830,0,inf,-1,-2,inf,3.9100000858306885 +2831,230000,1.6782607417553663e-05,-1,-2,1.6782607417553663e-05,3.8599998950958252 +2832,24700,0.00016194331692531705,-1,-2,0.00016194331692531705,4 +2833,65000,6.1076920246705413e-05,-1,-2,6.1076920246705413e-05,3.9700000286102295 +2834,22534,0.00023608769697602838,-1,-2,0.00023608769697602838,5.320000171661377 +2835,66850,5.6245324230985716e-05,-1,-2,5.6245324230985716e-05,3.7599999904632568 +2836,0,inf,-1,-2,inf,1.7100000381469727 +2837,48000,0.00012166667147539556,-1,-2,0.00012166667147539556,5.8400001525878906 +2838,216700,8.3525610534707084e-06,-1,-2,8.3525610534707084e-06,1.809999942779541 +2839,8400,0.00074880954343825579,-1,-2,0.00074880954343825579,6.2899999618530273 +2840,74000,2.7027026590076275e-05,-1,-2,2.7027026590076275e-05,2 +2841,85700,1.8903150703408755e-05,-1,-2,1.8903150703408755e-05,1.6200000047683716 +2842,36100,0.00017340721387881786,-1,-2,0.00017340721387881786,6.2600002288818359 +2843,17000,0.00024588234373368323,-1,-2,0.00024588234373368323,4.179999828338623 +2844,55000,5.5636362958466634e-05,-1,-2,5.5636362958466634e-05,3.059999942779541 +2845,62000,5.3225805459078401e-05,-1,-2,5.3225805459078401e-05,3.2999999523162842 +2846,15400,0.00030324675026349723,-1,-2,0.00030324675026349723,4.6700000762939453 +2847,30000,3.5333330743014812e-05,-1,-2,3.5333330743014812e-05,1.059999942779541 +2848,0,inf,-1,-2,inf,2.7200000286102295 +2849,19700,3.2994921639328822e-05,-1,-2,3.2994921639328822e-05,0.64999997615814209 +2850,83600,3.4090906410710886e-05,-1,-2,3.4090906410710886e-05,2.8499999046325684 +2851,100000,6.0200000007171184e-05,-1,-2,6.0200000007171184e-05,6.0199999809265137 +2852,0,inf,-1,-2,inf,4.2100000381469727 +2853,0,inf,-1,-2,inf,3.0199999809265137 +2854,70000,6.9857138441875577e-05,-1,-2,6.9857138441875577e-05,4.8899998664855957 +2855,20000,0.00021800000104121864,-1,-2,0.00021800000104121864,4.3600001335144043 +2856,0,inf,-1,-2,inf,3.940000057220459 +2857,0,inf,-1,-2,inf,3.0699999332427979 +2858,0,inf,-1,-2,inf,4.1500000953674316 +2859,69900,3.7768240872537717e-05,-1,-2,3.7768240872537717e-05,2.6400001049041748 +2860,0,inf,-1,-2,inf,1.8700000047683716 +2861,63000,6.7777778895106167e-05,-1,-2,6.7777778895106167e-05,4.2699999809265137 +2862,62050,4.3674455810105428e-05,-1,-2,4.3674455810105428e-05,2.7100000381469727 +2863,0,inf,-1,-2,inf,4.6999998092651367 +2864,0,inf,-1,-2,inf,3.0499999523162842 +2865,80000,3.9125003240769729e-05,-1,-2,3.9125003240769729e-05,3.130000114440918 +2866,45600,6.1184211517684162e-05,-1,-2,6.1184211517684162e-05,2.7899999618530273 +2867,0,inf,-1,-2,inf,3.9700000286102295 +2868,16480,0.0001171116455225274,-1,-2,0.0001171116455225274,1.9299999475479126 +2869,0,inf,-1,-2,inf,2.9700000286102295 +2870,8300,0.00033253012225031853,-1,-2,0.00033253012225031853,2.7599999904632568 +2871,34100,0.0001340175949735567,-1,-2,0.0001340175949735567,4.570000171661377 +2872,47300,5.6871038395911455e-05,-1,-2,5.6871038395911455e-05,2.690000057220459 +2873,36000,3.6944446037523448e-05,-1,-2,3.6944446037523448e-05,1.3300000429153442 +2874,117000,5.5555551625730004e-06,-1,-2,5.5555551625730004e-06,0.64999997615814209 +2875,77000,5.8181816712021828e-05,-1,-2,5.8181816712021828e-05,4.4800000190734863 +2876,8000,0.00021875000675208867,-1,-2,0.00021875000675208867,1.75 +2877,52000,5.673076884704642e-05,-1,-2,5.673076884704642e-05,2.9500000476837158 +2878,10000,0.000590000010561198,-1,-2,0.000590000010561198,5.9000000953674316 +2879,14400,0.00031249999301508069,-1,-2,0.00031249999301508069,4.5 +2880,8000,0.00041499998769722879,-1,-2,0.00041499998769722879,3.3199999332427979 +2881,58000,1.5689654901507311e-05,-1,-2,1.5689654901507311e-05,0.9100000262260437 +2882,0,inf,-1,-2,inf,3.7799999713897705 +2883,65600,6.9359761255327612e-05,-1,-2,6.9359761255327612e-05,4.5500001907348633 +2884,49000,4.7959179937606677e-05,-1,-2,4.7959179937606677e-05,2.3499999046325684 +2885,66850,3.9192218537209556e-05,-1,-2,3.9192218537209556e-05,2.619999885559082 +2886,92500,4.3891890527447686e-05,-1,-2,4.3891890527447686e-05,4.059999942779541 +2887,46400,9.2025860794819891e-05,-1,-2,9.2025860794819891e-05,4.2699999809265137 +2888,65000,4.0307691961061209e-05,-1,-2,4.0307691961061209e-05,2.619999885559082 +2889,8300,0.00039638552698306739,-1,-2,0.00039638552698306739,3.2899999618530273 +2890,0,inf,-1,-2,inf,3.8399999141693115 +2891,0,inf,-1,-2,inf,5.8299999237060547 +2892,25600,0.00020976562518626451,-1,-2,0.00020976562518626451,5.369999885559082 +2893,7000,0.00098571425769478083,-1,-2,0.00098571425769478083,6.9000000953674316 +2894,166000,2.0481928004301153e-05,-1,-2,2.0481928004301153e-05,3.4000000953674316 +2895,101000,2.8415839551598765e-05,-1,-2,2.8415839551598765e-05,2.869999885559082 +2896,365400,1.0454296898387838e-05,-1,-2,1.0454296898387838e-05,3.8199999332427979 +2897,106000,3.4339624107815325e-05,-1,-2,3.4339624107815325e-05,3.6400001049041748 +2898,2400,0.00090833334252238274,-1,-2,0.00090833334252238274,2.1800000667572021 +2899,14500,0.00026689653168432415,-1,-2,0.00026689653168432415,3.869999885559082 +2900,14000,0.00023857141786720604,-1,-2,0.00023857141786720604,3.3399999141693115 +2901,75000,8.9333334472030401e-06,-1,-2,8.9333334472030401e-06,0.67000001668930054 +2902,0,inf,-1,-2,inf,3.130000114440918 +2903,0,inf,-1,-2,inf,3.1099998950958252 +2904,6000,0.00064333330374211073,-1,-2,0.00064333330374211073,3.8599998950958252 +2905,660,0.0086363637819886208,-1,-2,0.0086363637819886208,5.6999998092651367 +2906,10900,0.00019724771846085787,-1,-2,0.00019724771846085787,2.1500000953674316 +2907,25640,0.00011037441436201334,-1,-2,0.00011037441436201334,2.8299999237060547 +2908,79000,4.772151805809699e-05,-1,-2,4.772151805809699e-05,3.7699999809265137 +2909,39000,6.7692308221012354e-05,-1,-2,6.7692308221012354e-05,2.6400001049041748 +2910,8310,0.00035980745451524854,-1,-2,0.00035980745451524854,2.9900000095367432 +2911,129500,2.0463321561692283e-05,-1,-2,2.0463321561692283e-05,2.6500000953674316 +2912,86400,3.5416665923548862e-05,-1,-2,3.5416665923548862e-05,3.059999942779541 +2913,10900,0.00029908257420174778,-1,-2,0.00029908257420174778,3.2599999904632568 +2914,21320,8.4896804764866829e-05,-1,-2,8.4896804764866829e-05,1.809999942779541 +2915,29704,8.2143822510261089e-05,-1,-2,8.2143822510261089e-05,2.440000057220459 +2916,25000,0.00020239999867044389,-1,-2,0.00020239999867044389,5.059999942779541 +2917,84000,6.0595240938710049e-05,-1,-2,6.0595240938710049e-05,5.0900001525878906 +2918,38190,0.00010526315600145608,-1,-2,0.00010526315600145608,4.0199999809265137 +2919,75000,1.4133333024801686e-05,-1,-2,1.4133333024801686e-05,1.059999942779541 +2920,0,inf,-1,-2,inf,2.7699999809265137 +2921,26100,0.00018927203200291842,-1,-2,0.00018927203200291842,4.940000057220459 +2922,51600,7.8100776590872556e-05,-1,-2,7.8100776590872556e-05,4.0300002098083496 +2923,125400,8.2934602687601e-06,-1,-2,8.2934602687601e-06,1.0399999618530273 +2924,56500,3.4867258364101872e-05,-1,-2,3.4867258364101872e-05,1.9700000286102295 +2925,4000,0.0010575000196695328,-1,-2,0.0010575000196695328,4.2300000190734863 +2926,0,inf,-1,-2,inf,3.1099998950958252 +2927,30000,1.7666665371507406e-05,-1,-2,1.7666665371507406e-05,0.52999997138977051 +2928,7170,0.00040306834853254259,-1,-2,0.00040306834853254259,2.8900001049041748 +2929,8300,0.00058433733647689223,-1,-2,0.00058433733647689223,4.8499999046325684 +2930,29500,0.00011288135283393785,-1,-2,0.00011288135283393785,3.3299999237060547 +2931,0,inf,-1,-2,inf,3.7200000286102295 +2932,34400,8.808139682514593e-05,-1,-2,8.808139682514593e-05,3.0299999713897705 +2933,65600,3.0487804906442761e-05,-1,-2,3.0487804906442761e-05,2 +2934,114000,2.2807016648584977e-05,-1,-2,2.2807016648584977e-05,2.5999999046325684 +2935,35300,7.2804534283932298e-05,-1,-2,7.2804534283932298e-05,2.5699999332427979 +2936,5500,0.00023636363039258868,-1,-2,0.00023636363039258868,1.2999999523162842 +2937,8700,0.0004804597410839051,-1,-2,0.0004804597410839051,4.179999828338623 +2938,250,0.021080000326037407,-1,-2,0.021080000326037407,5.2699999809265137 +2939,45500,8.989011257654056e-05,-1,-2,8.989011257654056e-05,4.0900001525878906 +2940,215000,7.6279070526652504e-06,-1,-2,7.6279070526652504e-06,1.6399999856948853 +2941,2400,0.0024000001139938831,-1,-2,0.0024000001139938831,5.7600002288818359 +2942,18000,9.833333024289459e-05,-1,-2,9.833333024289459e-05,1.7699999809265137 +2943,127900,2.5723220460349694e-05,-1,-2,2.5723220460349694e-05,3.2899999618530273 +2944,278300,9.414300620846916e-06,-1,-2,9.414300620846916e-06,2.619999885559082 +2945,118800,4.2592593672452495e-05,-1,-2,4.2592593672452495e-05,5.059999942779541 +2946,14000,0.00031642857356928289,-1,-2,0.00031642857356928289,4.429999828338623 +2947,11000,0.00042090911301784217,-1,-2,0.00042090911301784217,4.630000114440918 +2948,26240,0.00010556402412476018,-1,-2,0.00010556402412476018,2.7699999809265137 +2949,70000,3.9142858440754935e-05,-1,-2,3.9142858440754935e-05,2.7400000095367432 +2950,64200,4.8598129069432616e-05,-1,-2,4.8598129069432616e-05,3.119999885559082 +2951,21320,0.00015712945605628192,-1,-2,0.00015712945605628192,3.3499999046325684 +2952,120000,2.2833333787275478e-05,-1,-2,2.2833333787275478e-05,2.7400000095367432 +2953,13900,9.6402880444657058e-05,-1,-2,9.6402880444657058e-05,1.3400000333786011 +2954,89950,4.7470817662542686e-05,-1,-2,4.7470817662542686e-05,4.2699999809265137 +2955,136600,4.553440521704033e-05,-1,-2,4.553440521704033e-05,6.2199997901916504 +2956,11000,0.00039727272815071046,-1,-2,0.00039727272815071046,4.369999885559082 +2957,8000,0.00031500001205131412,-1,-2,0.00031500001205131412,2.5199999809265137 +2958,32300,9.7832817118614912e-05,-1,-2,9.7832817118614912e-05,3.1600000858306885 +2959,27000,0.00011333332804497331,-1,-2,0.00011333332804497331,3.059999942779541 +2960,0,inf,-1,-2,inf,4.059999942779541 +2961,18800,0.00010372340329922736,-1,-2,0.00010372340329922736,1.9500000476837158 +2962,65000,9.1538458946160972e-05,-1,-2,9.1538458946160972e-05,5.9499998092651367 +2963,16000,0.00013000000035390258,-1,-2,0.00013000000035390258,2.0799999237060547 +2964,74900,6.6488653828855604e-05,-1,-2,6.6488653828855604e-05,4.9800000190734863 +2965,337600,1.2381516171444673e-05,-1,-2,1.2381516171444673e-05,4.179999828338623 +2966,8500,0.00045411763130687177,-1,-2,0.00045411763130687177,3.8599998950958252 +2967,34300,5.2186587709002197e-05,-1,-2,5.2186587709002197e-05,1.7899999618530273 +2968,160000,2.2062500647734851e-05,-1,-2,2.2062500647734851e-05,3.5299999713897705 +2969,9600,0.00033958331914618611,-1,-2,0.00033958331914618611,3.2599999904632568 +2970,23800,0.00018235294555779546,-1,-2,0.00018235294555779546,4.3400001525878906 +2971,14000,0.00014285714132711291,-1,-2,0.00014285714132711291,2 +2972,66380,5.7246157666668296e-05,-1,-2,5.7246157666668296e-05,3.7999999523162842 +2973,0,inf,-1,-2,inf,5.5900001525878906 +2974,1300,0.0027000000700354576,-1,-2,0.0027000000700354576,3.5099999904632568 +2975,43700,6.270023004617542e-05,-1,-2,6.270023004617542e-05,2.7400000095367432 +2976,77000,3.1038962333695963e-05,-1,-2,3.1038962333695963e-05,2.3900001049041748 +2977,0,inf,-1,-2,inf,4.6599998474121094 +2978,20000,0.00023050000891089439,-1,-2,0.00023050000891089439,4.6100001335144043 +2979,8100,0.00033333332976326346,-1,-2,0.00033333332976326346,2.7000000476837158 +2980,27100,5.9778598370030522e-05,-1,-2,5.9778598370030522e-05,1.6200000047683716 +2981,365300,1.0238160029985011e-05,-1,-2,1.0238160029985011e-05,3.7400000095367432 +2982,60000,5.5499996960861608e-05,-1,-2,5.5499996960861608e-05,3.3299999237060547 +2983,15000,0.00020733333076350391,-1,-2,0.00020733333076350391,3.1099998950958252 +2984,8900,0.00047191008343361318,-1,-2,0.00047191008343361318,4.1999998092651367 +2985,62050,6.9621273723896593e-05,-1,-2,6.9621273723896593e-05,4.320000171661377 +2986,18000,0.00013222222332842648,-1,-2,0.00013222222332842648,2.380000114440918 +2987,7700,0.00054415583144873381,-1,-2,0.00054415583144873381,4.190000057220459 +2988,7500,0.00041466666152700782,-1,-2,0.00041466666152700782,3.1099998950958252 +2989,30920,6.4359635871369392e-05,-1,-2,6.4359635871369392e-05,1.9900000095367432 +2990,157000,1.7452230167691596e-05,-1,-2,1.7452230167691596e-05,2.7400000095367432 +2991,157000,2.5668790840427391e-05,-1,-2,2.5668790840427391e-05,4.0300002098083496 +2992,26000,0.00016269230400212109,-1,-2,0.00016269230400212109,4.2300000190734863 +2993,195000,2.010256503126584e-05,-1,-2,2.010256503126584e-05,3.9200000762939453 +2994,100000,2.1800000467919745e-05,-1,-2,2.1800000467919745e-05,2.1800000667572021 +2995,9600,0.0001541666715638712,-1,-2,0.0001541666715638712,1.4800000190734863 +2996,79900,4.88110117657925e-06,-1,-2,4.88110117657925e-06,0.38999998569488525 +2997,7400,7.1621616370975971e-05,-1,-2,7.1621616370975971e-05,0.52999997138977051 +2998,0,inf,-1,-2,inf,3.5899999141693115 +2999,18100,9.6132600447162986e-05,-1,-2,9.6132600447162986e-05,1.7400000095367432 +3000,25600,7.4218747613485903e-05,-1,-2,7.4218747613485903e-05,1.8999999761581421 +3001,0,inf,-1,-2,inf,4.9099998474121094 +3002,100000,5.070000042906031e-05,-1,-2,5.070000042906031e-05,5.070000171661377 +3003,35000,0.00017914285126607865,-1,-2,0.00017914285126607865,6.2699999809265137 +3004,16000,0.0003256250056438148,-1,-2,0.0003256250056438148,5.2100000381469727 +3005,30500,9.4426235591527075e-05,-1,-2,9.4426235591527075e-05,2.880000114440918 +3006,40000,0.00011499999527586624,-1,-2,0.00011499999527586624,4.5999999046325684 +3007,30000,2.23333336180076e-05,-1,-2,2.23333336180076e-05,0.67000001668930054 +3008,112500,4.0177776099881157e-05,-1,-2,4.0177776099881157e-05,4.5199999809265137 +3009,26300,0.00011825094406958669,-1,-2,0.00011825094406958669,3.1099998950958252 +3010,0,inf,-1,-2,inf,4.630000114440918 +3011,19400,0.00023865980620030314,-1,-2,0.00023865980620030314,4.630000114440918 +3012,15304,0.00013068478438071907,-1,-2,0.00013068478438071907,2 +3013,34630,0.00013081144425086677,-1,-2,0.00013081144425086677,4.5300002098083496 +3014,9500,0.00031684210989624262,-1,-2,0.00031684210989624262,3.0099999904632568 +3015,13900,0.00029280578019097447,-1,-2,0.00029280578019097447,4.070000171661377 +3016,17300,6.1271675804164261e-05,-1,-2,6.1271675804164261e-05,1.059999942779541 +3017,0,inf,-1,-2,inf,2.7100000381469727 +3018,8300,0.00036024095606990159,-1,-2,0.00036024095606990159,2.9900000095367432 +3019,54500,3.3944954338949174e-05,-1,-2,3.3944954338949174e-05,1.8500000238418579 +3020,42000,1.2619047083717305e-05,-1,-2,1.2619047083717305e-05,0.52999997138977051 +3021,270000,1.4222221579984762e-05,-1,-2,1.4222221579984762e-05,3.8399999141693115 +3022,3400,0.00019117647025268525,-1,-2,0.00019117647025268525,0.64999997615814209 +3023,4600,0.00071521737845614552,-1,-2,0.00071521737845614552,3.2899999618530273 +3024,62000,4.6290319005493075e-05,-1,-2,4.6290319005493075e-05,2.869999885559082 +3025,80400,4.3407959310570732e-05,-1,-2,4.3407959310570732e-05,3.4900000095367432 +3026,0,inf,-1,-2,inf,3.0699999332427979 +3027,77700,3.8223937735892832e-05,-1,-2,3.8223937735892832e-05,2.9700000286102295 +3028,17000,0.00027705883258022368,-1,-2,0.00027705883258022368,4.7100000381469727 +3029,0,inf,-1,-2,inf,7.2800002098083496 +3030,70000,1.257142866961658e-05,-1,-2,1.257142866961658e-05,0.87999999523162842 +3031,97000,2.2886597434990108e-05,-1,-2,2.2886597434990108e-05,2.2200000286102295 +3032,86700,5.1095728849759325e-05,-1,-2,5.1095728849759325e-05,4.429999828338623 +3033,127950,2.1101994207128882e-05,-1,-2,2.1101994207128882e-05,2.7000000476837158 +3034,8400,0.00049404765013605356,-1,-2,0.00049404765013605356,4.1500000953674316 +3035,25000,0.00015999999595806003,-1,-2,0.00015999999595806003,4 +3036,26050,7.8310942626558244e-05,-1,-2,7.8310942626558244e-05,2.0399999618530273 +3037,96000,2.8750000637955964e-05,-1,-2,2.8750000637955964e-05,2.7599999904632568 +3038,8200,0.00020243902690708637,-1,-2,0.00020243902690708637,1.6599999666213989 +3039,4000,0.0011350000277161598,-1,-2,0.0011350000277161598,4.5399999618530273 +3040,46400,2.9956896469229832e-05,-1,-2,2.9956896469229832e-05,1.3899999856948853 +3041,7000,0.00030714288004674017,-1,-2,0.00030714288004674017,2.1500000953674316 +3042,81500,3.3865031582536176e-05,-1,-2,3.3865031582536176e-05,2.7599999904632568 +3043,325000,8.2769229265977629e-06,-1,-2,8.2769229265977629e-06,2.690000057220459 +3044,16400,8.8414635683875531e-05,-1,-2,8.8414635683875531e-05,1.4500000476837158 +3045,34000,0.00010823529737535864,-1,-2,0.00010823529737535864,3.6800000667572021 +3046,69200,2.6734103812486865e-05,-1,-2,2.6734103812486865e-05,1.8500000238418579 +3047,9000,0.0005433332989923656,-1,-2,0.0005433332989923656,4.8899998664855957 +3048,83000,1.7469879821874201e-05,-1,-2,1.7469879821874201e-05,1.4500000476837158 +3049,89500,2.6927375074592419e-05,-1,-2,2.6927375074592419e-05,2.4100000858306885 +3050,5000,0.0005300000193528831,-1,-2,0.0005300000193528831,2.6500000953674316 +3051,0,inf,-1,-2,inf,1.8700000047683716 +3052,242500,9.8556702141650021e-06,-1,-2,9.8556702141650021e-06,2.3900001049041748 +3053,4204,0.00057326356181874871,-1,-2,0.00057326356181874871,2.4100000858306885 +3054,19400,6.7010303610004485e-05,-1,-2,6.7010303610004485e-05,1.2999999523162842 +3055,4000,0.0010400000028312206,-1,-2,0.0010400000028312206,4.1599998474121094 +3056,48110,5.5289961892412975e-05,-1,-2,5.5289961892412975e-05,2.6600000858306885 +3057,205000,1.8292683307663538e-05,-1,-2,1.8292683307663538e-05,3.75 +3058,108000,4.8703706852393225e-05,-1,-2,4.8703706852393225e-05,5.2600002288818359 +3059,36300,0.000115151509817224,-1,-2,0.000115151509817224,4.179999828338623 +3060,14000,0.00027571426471695304,-1,-2,0.00027571426471695304,3.8599998950958252 +3061,69000,2.4202898202929646e-05,-1,-2,2.4202898202929646e-05,1.6699999570846558 +3062,70000,7.9428573371842504e-05,-1,-2,7.9428573371842504e-05,5.559999942779541 +3063,0,inf,-1,-2,inf,2.7699999809265137 +3064,75000,4.8666668590158224e-05,-1,-2,4.8666668590158224e-05,3.6500000953674316 +3065,12700,8.2677164755295962e-05,-1,-2,8.2677164755295962e-05,1.0499999523162842 +3066,26030,8.3365353930275887e-05,-1,-2,8.3365353930275887e-05,2.1700000762939453 +3067,35000,5.7714285503607243e-05,-1,-2,5.7714285503607243e-05,2.0199999809265137 +3068,0,inf,-1,-2,inf,2.7599999904632568 +3069,35300,9.4617564172949642e-05,-1,-2,9.4617564172949642e-05,3.3399999141693115 +3070,8300,0.0004385542415548116,-1,-2,0.0004385542415548116,3.6400001049041748 +3071,15300,0.00021895424288231879,-1,-2,0.00021895424288231879,3.3499999046325684 +3072,9500,0.000357894750777632,-1,-2,0.000357894750777632,3.4000000953674316 +3073,48000,3.9375001506414264e-05,-1,-2,3.9375001506414264e-05,1.8899999856948853 +3074,10100,0.00041782174957916141,-1,-2,0.00041782174957916141,4.2199997901916504 +3075,51000,6.2745100876782089e-05,-1,-2,6.2745100876782089e-05,3.2000000476837158 +3076,158000,3.2025316613726318e-05,-1,-2,3.2025316613726318e-05,5.059999942779541 +3077,17000,3.9999998989515007e-05,-1,-2,3.9999998989515007e-05,0.68000000715255737 +3078,0,inf,-1,-2,inf,1.3300000429153442 +3079,34000,8.9411762019153684e-05,-1,-2,8.9411762019153684e-05,3.0399999618530273 +3080,8400,0.00015952381363604218,-1,-2,0.00015952381363604218,1.3400000333786011 +3081,74000,3.6351353628560901e-05,-1,-2,3.6351353628560901e-05,2.690000057220459 +3082,22000,0.00013590909657068551,-1,-2,0.00013590909657068551,2.9900000095367432 +3083,140100,1.6059957488323562e-05,-1,-2,1.6059957488323562e-05,2.25 +3084,9000,0.00018444443412590772,-1,-2,0.00018444443412590772,1.6599999666213989 +3085,0,inf,-1,-2,inf,2.2400000095367432 +3086,0,inf,-1,-2,inf,3.3399999141693115 +3087,0,inf,-1,-2,inf,0.62000000476837158 +3088,17300,0.00022369941871147603,-1,-2,0.00022369941871147603,3.869999885559082 +3089,115000,1.321739091508789e-05,-1,-2,1.321739091508789e-05,1.5199999809265137 +3090,58000,9.3103453764342703e-06,-1,-2,9.3103453764342703e-06,0.54000002145767212 +3091,100000,2.1099998775753193e-05,-1,-2,2.1099998775753193e-05,2.1099998950958252 +3092,15370,0.00036890045157633722,-1,-2,0.00036890045157633722,5.6700000762939453 +3093,74000,1.0540539733483456e-05,-1,-2,1.0540539733483456e-05,0.77999997138977051 +3094,0,inf,-1,-2,inf,5.8299999237060547 +3095,60000,0.00012633332516998053,-1,-2,0.00012633332516998053,7.5799999237060547 +3096,32500,8.7692307715769857e-05,-1,-2,8.7692307715769857e-05,2.8499999046325684 +3097,8700,0.00050229881890118122,-1,-2,0.00050229881890118122,4.369999885559082 +3098,0,inf,-1,-2,inf,2.2799999713897705 +3099,0,inf,-1,-2,inf,1.0800000429153442 +3100,137000,2.2919708499102853e-05,-1,-2,2.2919708499102853e-05,3.1400001049041748 +3101,9200,0.00023695653362665325,-1,-2,0.00023695653362665325,2.1800000667572021 +3102,7000,0.00022142856323625892,-1,-2,0.00022142856323625892,1.5499999523162842 +3103,62300,6.9502406404353678e-05,-1,-2,6.9502406404353678e-05,4.3299999237060547 +3104,109000,2.4403670977335423e-05,-1,-2,2.4403670977335423e-05,2.6600000858306885 +3105,158000,1.7784810552257113e-05,-1,-2,1.7784810552257113e-05,2.809999942779541 +3106,106700,2.9334583814488724e-05,-1,-2,2.9334583814488724e-05,3.130000114440918 +3107,9900,6.5656560764182359e-05,-1,-2,6.5656560764182359e-05,0.64999997615814209 +3108,87400,6.5331805672030896e-05,-1,-2,6.5331805672030896e-05,5.7100000381469727 +3109,43000,2.1162792108952999e-05,-1,-2,2.1162792108952999e-05,0.9100000262260437 +3110,100000,3.3800002711359411e-05,-1,-2,3.3800002711359411e-05,3.380000114440918 +3111,79000,4.8860758397495374e-05,-1,-2,4.8860758397495374e-05,3.8599998950958252 +3112,0,inf,-1,-2,inf,0.43999999761581421 +3113,30100,0.00014019932132214308,-1,-2,0.00014019932132214308,4.2199997901916504 +3114,20000,3.2500000088475645e-05,-1,-2,3.2500000088475645e-05,0.64999997615814209 +3115,0,inf,-1,-2,inf,3.1600000858306885 +3116,66300,4.8717949539422989e-05,-1,-2,4.8717949539422989e-05,3.2300000190734863 +3117,21700,0.00016497695469297469,-1,-2,0.00016497695469297469,3.5799999237060547 +3118,50000,9.9600001703947783e-05,-1,-2,9.9600001703947783e-05,4.9800000190734863 +3119,8300,0.00025301202549599111,-1,-2,0.00025301202549599111,2.0999999046325684 +3120,13370,3.9640985050937161e-05,-1,-2,3.9640985050937161e-05,0.52999997138977051 +3121,0,inf,-1,-2,inf,6.690000057220459 +3122,133000,1.6240601325989701e-05,-1,-2,1.6240601325989701e-05,2.1600000858306885 +3123,50900,4.5186639908934012e-05,-1,-2,4.5186639908934012e-05,2.2999999523162842 +3124,33000,8.6060601461213082e-05,-1,-2,8.6060601461213082e-05,2.8399999141693115 +3125,145450,3.623238080763258e-05,-1,-2,3.623238080763258e-05,5.2699999809265137 +3126,130000,2.5615383492549881e-05,-1,-2,2.5615383492549881e-05,3.3299999237060547 +3127,0,inf,-1,-2,inf,6.0500001907348633 +3128,62000,4.7258065023925155e-05,-1,-2,4.7258065023925155e-05,2.9300000667572021 +3129,14500,0.00033724136301316321,-1,-2,0.00033724136301316321,4.8899998664855957 +3130,20000,7.6500000432133675e-05,-1,-2,7.6500000432133675e-05,1.5299999713897705 +3131,66300,6.2745093600824475e-05,-1,-2,6.2745093600824475e-05,4.1599998474121094 +3132,8300,0.00026385541423223913,-1,-2,0.00026385541423223913,2.190000057220459 +3133,149000,2.6845636966754682e-05,-1,-2,2.6845636966754682e-05,4 +3134,13800,0.00043623187229968607,-1,-2,0.00043623187229968607,6.0199999809265137 +3135,0,inf,-1,-2,inf,5.619999885559082 +3136,20000,7.4000003223773092e-05,-1,-2,7.4000003223773092e-05,1.4800000190734863 +3137,15400,0.00013701297575607896,-1,-2,0.00013701297575607896,2.1099998950958252 +3138,38190,0.00010683424625312909,-1,-2,0.00010683424625312909,4.0799999237060547 +3139,119700,2.6399331545690075e-05,-1,-2,2.6399331545690075e-05,3.1600000858306885 +3140,0,inf,-1,-2,inf,1.4600000381469727 +3141,10000,0.00013500000932253897,-1,-2,0.00013500000932253897,1.3500000238418579 +3142,0,inf,-1,-2,inf,2.7400000095367432 +3143,26640,0.00013063063670415431,-1,-2,0.00013063063670415431,3.4800000190734863 +3144,4600,0.00028260867111384869,-1,-2,0.00028260867111384869,1.2999999523162842 +3145,8100,0.00066790124401450157,-1,-2,0.00066790124401450157,5.4099998474121094 +3146,19500,0.0002476923109497875,-1,-2,0.0002476923109497875,4.8299999237060547 +3147,0,inf,-1,-2,inf,0.67000001668930054 +3148,5050,0.00081782182678580284,-1,-2,0.00081782182678580284,4.130000114440918 +3149,42500,4.3764706788351759e-05,-1,-2,4.3764706788351759e-05,1.8600000143051147 +3150,652070,5.4288648243527859e-06,-1,-2,5.4288648243527859e-06,3.5399999618530273 +3151,0,inf,-1,-2,inf,3.8900001049041748 +3152,12200,0.00023196720576379448,-1,-2,0.00023196720576379448,2.8299999237060547 +3153,0,inf,-1,-2,inf,2.6800000667572021 +3154,43000,4.8372090532211587e-05,-1,-2,4.8372090532211587e-05,2.0799999237060547 +3155,0,inf,-1,-2,inf,5.0199999809265137 +3156,70300,8.6628737335558981e-05,-1,-2,8.6628737335558981e-05,6.0900001525878906 +3157,0,inf,-1,-2,inf,5.0799999237060547 +3158,3400,0.0011294117430225015,-1,-2,0.0011294117430225015,3.8399999141693115 +3159,60000,0.00010416666918899864,-1,-2,0.00010416666918899864,6.25 +3160,101500,2.5615761842345819e-05,-1,-2,2.5615761842345819e-05,2.5999999046325684 +3161,7500,0.0010079999919980764,-1,-2,0.0010079999919980764,7.559999942779541 +3162,25700,0.00012957198487129062,-1,-2,0.00012957198487129062,3.3299999237060547 +3163,20000,0.0002184999902965501,-1,-2,0.0002184999902965501,4.369999885559082 +3164,14000,0.00027428570319898427,-1,-2,0.00027428570319898427,3.8399999141693115 +3165,39400,1.7005077097564936e-05,-1,-2,1.7005077097564936e-05,0.67000001668930054 +3166,10000,0.00050500000361353159,-1,-2,0.00050500000361353159,5.0500001907348633 +3167,0,inf,-1,-2,inf,2.0699999332427979 +3168,153000,2.0392155420267954e-05,-1,-2,2.0392155420267954e-05,3.119999885559082 +3169,120250,2.7193347705178894e-05,-1,-2,2.7193347705178894e-05,3.2699999809265137 +3170,12000,0.00017666665371507406,-1,-2,0.00017666665371507406,2.119999885559082 +3171,126000,4.0476188587490469e-05,-1,-2,4.0476188587490469e-05,5.0999999046325684 +3172,15000,0.0002386666601523757,-1,-2,0.0002386666601523757,3.5799999237060547 +3173,14800,0.00011216216080356389,-1,-2,0.00011216216080356389,1.6599999666213989 +3174,4200,0.0014809523709118366,-1,-2,0.0014809523709118366,6.2199997901916504 +3175,158000,2.2594937036046758e-05,-1,-2,2.2594937036046758e-05,3.5699999332427979 +3176,16000,0.00028062498313374817,-1,-2,0.00028062498313374817,4.4899997711181641 +3177,66000,2.4848484827089123e-05,-1,-2,2.4848484827089123e-05,1.6399999856948853 +3178,11000,0.00032090907916426659,-1,-2,0.00032090907916426659,3.5299999713897705 +3179,34600,0.00011820809595519677,-1,-2,0.00011820809595519677,4.0900001525878906 +3180,8300,0.00016024097567424178,-1,-2,0.00016024097567424178,1.3300000429153442 +3181,0,inf,-1,-2,inf,3.2899999618530273 +3182,0,inf,-1,-2,inf,2.0199999809265137 +3183,81000,2.5185185222653672e-05,-1,-2,2.5185185222653672e-05,2.0399999618530273 +3184,4800,0.00011041665857192129,-1,-2,0.00011041665857192129,0.52999997138977051 +3185,14000,0.0003064285556320101,-1,-2,0.0003064285556320101,4.2899999618530273 +3186,1100,0.0034636363852769136,-1,-2,0.0034636363852769136,3.809999942779541 +3187,26120,9.8774879006668925e-05,-1,-2,9.8774879006668925e-05,2.5799999237060547 +3188,14800,0.00030743243405595422,-1,-2,0.00030743243405595422,4.5500001907348633 +3189,10200,0.00025980392820201814,-1,-2,0.00025980392820201814,2.6500000953674316 +3190,26000,6.3461535319220275e-05,-1,-2,6.3461535319220275e-05,1.6499999761581421 +3191,6500,0.00063846155535429716,-1,-2,0.00063846155535429716,4.1500000953674316 +3192,0,inf,-1,-2,inf,2.4600000381469727 +3193,22000,0.0001404545473633334,-1,-2,0.0001404545473633334,3.0899999141693115 +3194,8420,0.00034560571657493711,-1,-2,0.00034560571657493711,2.9100000858306885 +3195,7000,0.00020714286074507982,-1,-2,0.00020714286074507982,1.4500000476837158 +3196,9000,0.00042888888856396079,-1,-2,0.00042888888856396079,3.8599998950958252 +3197,56000,1.1964286386501044e-05,-1,-2,1.1964286386501044e-05,0.67000001668930054 +3198,50500,9.0495050244498998e-05,-1,-2,9.0495050244498998e-05,4.570000171661377 +3199,20000,0.00016900000628083944,-1,-2,0.00016900000628083944,3.380000114440918 +3200,15700,0.00027707006665877998,-1,-2,0.00027707006665877998,4.3499999046325684 +3201,0,inf,-1,-2,inf,5.7100000381469727 +3202,0,inf,-1,-2,inf,1.2999999523162842 +3203,25200,8.1349207903258502e-05,-1,-2,8.1349207903258502e-05,2.0499999523162842 +3204,462000,7.4458876042626798e-06,-1,-2,7.4458876042626798e-06,3.440000057220459 +3205,27030,0.00018571957480162382,-1,-2,0.00018571957480162382,5.0199999809265137 +3206,70900,8.0677004007156938e-05,-1,-2,8.0677004007156938e-05,5.7199997901916504 +3207,24000,0.00012874999083578587,-1,-2,0.00012874999083578587,3.0899999141693115 +3208,0,inf,-1,-2,inf,1.9900000095367432 +3209,195000,4.6666668822581414e-06,-1,-2,4.6666668822581414e-06,0.9100000262260437 +3210,44000,0.00011636363342404366,-1,-2,0.00011636363342404366,5.119999885559082 +3211,15200,5.1315786549821496e-05,-1,-2,5.1315786549821496e-05,0.77999997138977051 +3212,45000,3.6666664527729154e-05,-1,-2,3.6666664527729154e-05,1.6499999761581421 +3213,3400,0.0010970588773488998,-1,-2,0.0010970588773488998,3.7300000190734863 +3214,46000,6.0217389545869082e-05,-1,-2,6.0217389545869082e-05,2.7699999809265137 +3215,0,inf,-1,-2,inf,0.77999997138977051 +3216,49000,9.8979588074143976e-05,-1,-2,9.8979588074143976e-05,4.8499999046325684 +3217,22500,0.00015688888379372656,-1,-2,0.00015688888379372656,3.5299999713897705 +3218,43700,0.00010457666212460026,-1,-2,0.00010457666212460026,4.570000171661377 +3219,17600,0.00024886365281417966,-1,-2,0.00024886365281417966,4.380000114440918 +3220,27000,0.00013629629393108189,-1,-2,0.00013629629393108189,3.6800000667572021 +3221,374000,1.0320854926249012e-05,-1,-2,1.0320854926249012e-05,3.8599998950958252 +3222,28100,7.7935947047080845e-05,-1,-2,7.7935947047080845e-05,2.190000057220459 +3223,21320,0.00012523452460300177,-1,-2,0.00012523452460300177,2.6700000762939453 +3224,8000,0.00056124996626749635,-1,-2,0.00056124996626749635,4.4899997711181641 +3225,125000,1.52000002344721e-05,-1,-2,1.52000002344721e-05,1.8999999761581421 +3226,9500,0.00036631579860113561,-1,-2,0.00036631579860113561,3.4800000190734863 +3227,28800,0.00010451388516230509,-1,-2,0.00010451388516230509,3.0099999904632568 +3228,0,inf,-1,-2,inf,5.190000057220459 +3229,67000,3.8805967051303014e-05,-1,-2,3.8805967051303014e-05,2.5999999046325684 +3230,20500,0.00023512195912189782,-1,-2,0.00023512195912189782,4.820000171661377 +3231,0,inf,-1,-2,inf,1.3300000429153442 +3232,42000,8.4761901234742254e-05,-1,-2,8.4761901234742254e-05,3.559999942779541 +3233,0,inf,-1,-2,inf,3.75 +3234,50000,4.1799998143687844e-05,-1,-2,4.1799998143687844e-05,2.0899999141693115 +3235,0,inf,-1,-2,inf,1.4800000190734863 +3236,0,inf,-1,-2,inf,2.1099998950958252 +3237,68000,8.2205886428710073e-05,-1,-2,8.2205886428710073e-05,5.5900001525878906 +3238,74000,5.1081082347081974e-05,-1,-2,5.1081082347081974e-05,3.7799999713897705 +3239,24900,6.4658634073566645e-05,-1,-2,6.4658634073566645e-05,1.6100000143051147 +3240,73100,2.4760600354056805e-05,-1,-2,2.4760600354056805e-05,1.809999942779541 +3241,74000,3.6621622712118551e-05,-1,-2,3.6621622712118551e-05,2.7100000381469727 +3242,11600,0.00049913791008293629,-1,-2,0.00049913791008293629,5.7899999618530273 +3243,158000,3.0316456104628742e-05,-1,-2,3.0316456104628742e-05,4.7899999618530273 +3244,40000,7.5000003562308848e-05,-1,-2,7.5000003562308848e-05,3 +3245,106700,2.9709466616623104e-05,-1,-2,2.9709466616623104e-05,3.1700000762939453 +3246,14200,0.00015422535943798721,-1,-2,0.00015422535943798721,2.190000057220459 +3247,99200,3.0141129172989167e-05,-1,-2,3.0141129172989167e-05,2.9900000095367432 +3248,10000,0.0003690000157803297,-1,-2,0.0003690000157803297,3.690000057220459 +3249,8400,0.00037380954017862678,-1,-2,0.00037380954017862678,3.1400001049041748 +3250,102160,2.603758912300691e-05,-1,-2,2.603758912300691e-05,2.6600000858306885 +3251,33220,0.00018844071018975228,-1,-2,0.00018844071018975228,6.2600002288818359 +3252,60000,1.4833332897978835e-05,-1,-2,1.4833332897978835e-05,0.88999998569488525 +3253,22100,4.8868780140765011e-05,-1,-2,4.8868780140765011e-05,1.0800000429153442 +3254,161300,1.593304295965936e-05,-1,-2,1.593304295965936e-05,2.5699999332427979 +3255,15400,0.00024610388209111989,-1,-2,0.00024610388209111989,3.7899999618530273 +3256,3500,0.0010828571394085884,-1,-2,0.0010828571394085884,3.7899999618530273 +3257,0,inf,-1,-2,inf,1.8700000047683716 +3258,107210,5.4845630074851215e-05,-1,-2,5.4845630074851215e-05,5.880000114440918 +3259,23000,0.00010608696175040677,-1,-2,0.00010608696175040677,2.440000057220459 +3260,18800,0.00018882978474721313,-1,-2,0.00018882978474721313,3.5499999523162842 +3261,1500,0.0022066666278988123,-1,-2,0.0022066666278988123,3.309999942779541 +3262,88600,4.7178327804431319e-05,-1,-2,4.7178327804431319e-05,4.179999828338623 +3263,18000,0.00017333333380520344,-1,-2,0.00017333333380520344,3.119999885559082 +3264,72000,5.3611111070495099e-05,-1,-2,5.3611111070495099e-05,3.8599998950958252 +3265,49300,7.3022310971282423e-05,-1,-2,7.3022310971282423e-05,3.5999999046325684 +3266,44000,0.00011477273073978722,-1,-2,0.00011477273073978722,5.0500001907348633 +3267,68400,8.0263154814019799e-05,-1,-2,8.0263154814019799e-05,5.4899997711181641 +3268,27350,0.00010091407602885738,-1,-2,0.00010091407602885738,2.7599999904632568 +3269,0,inf,-1,-2,inf,3.1700000762939453 +3270,26500,8.5660380136687309e-05,-1,-2,8.5660380136687309e-05,2.2699999809265137 +3271,33200,0.0001081325244740583,-1,-2,0.0001081325244740583,3.5899999141693115 +3272,68900,5.1669085223693401e-05,-1,-2,5.1669085223693401e-05,3.559999942779541 +3273,44050,4.5629964006366208e-05,-1,-2,4.5629964006366208e-05,2.0099999904632568 +3274,34300,9.8542273917701095e-05,-1,-2,9.8542273917701095e-05,3.380000114440918 +3275,14100,0.00019432624685578048,-1,-2,0.00019432624685578048,2.7400000095367432 +3276,65000,3.1384613976115361e-05,-1,-2,3.1384613976115361e-05,2.0399999618530273 +3277,74000,1.0540539733483456e-05,-1,-2,1.0540539733483456e-05,0.77999997138977051 +3278,79000,7.0126581704244018e-05,-1,-2,7.0126581704244018e-05,5.5399999618530273 +3279,4000,0.0013274999801069498,-1,-2,0.0013274999801069498,5.309999942779541 +3280,0,inf,-1,-2,inf,1.9500000476837158 +3281,144100,1.8806384105118923e-05,-1,-2,1.8806384105118923e-05,2.7100000381469727 +3282,30000,0.00013766667689196765,-1,-2,0.00013766667689196765,4.130000114440918 +3283,68400,3.8742691685911268e-05,-1,-2,3.8742691685911268e-05,2.6500000953674316 +3284,0,inf,-1,-2,inf,2.0199999809265137 +3285,21000,0.00019190477905794978,-1,-2,0.00019190477905794978,4.0300002098083496 +3286,17850,0.00011596638069022447,-1,-2,0.00011596638069022447,2.0699999332427979 +3287,37000,7.3243245424237102e-05,-1,-2,7.3243245424237102e-05,2.7100000381469727 +3288,22600,0.00014778760669287294,-1,-2,0.00014778760669287294,3.3399999141693115 +3289,30900,9.1585759946610779e-05,-1,-2,9.1585759946610779e-05,2.8299999237060547 +3290,0,inf,-1,-2,inf,2.4500000476837158 +3291,14800,0.00011891892063431442,-1,-2,0.00011891892063431442,1.7599999904632568 +3292,0,inf,-1,-2,inf,1.3300000429153442 +3293,23510,8.9323686552233994e-05,-1,-2,8.9323686552233994e-05,2.0999999046325684 +3294,7800,0.00046410254435613751,-1,-2,0.00046410254435613751,3.619999885559082 +3295,10600,0.00059716979740187526,-1,-2,0.00059716979740187526,6.3299999237060547 +3296,25000,9.8800002888310701e-05,-1,-2,9.8800002888310701e-05,2.4700000286102295 +3297,54800,3.2481751986779273e-05,-1,-2,3.2481751986779273e-05,1.7799999713897705 +3298,0,inf,-1,-2,inf,3.75 +3299,10000,0.00016900000628083944,-1,-2,0.00016900000628083944,1.690000057220459 +3300,75100,6.5912114223465323e-05,-1,-2,6.5912114223465323e-05,4.9499998092651367 +3301,9500,0.00035684212343767285,-1,-2,0.00035684212343767285,3.3900001049041748 +3302,3000,0.001449999981559813,-1,-2,0.001449999981559813,4.3499999046325684 +3303,9600,8.1250000221189111e-05,-1,-2,8.1250000221189111e-05,0.77999997138977051 +3304,0,inf,-1,-2,inf,0.43999999761581421 +3305,0,inf,-1,-2,inf,3.9800000190734863 +3306,17000,0.0001323529431829229,-1,-2,0.0001323529431829229,2.25 +3307,23400,0.00017222223686985672,-1,-2,0.00017222223686985672,4.0300002098083496 +3308,0,inf,-1,-2,inf,2.9500000476837158 +3309,62000,7.1290320192929357e-05,-1,-2,7.1290320192929357e-05,4.4200000762939453 +3310,158000,2.1139239834155887e-05,-1,-2,2.1139239834155887e-05,3.3399999141693115 +3311,15000,0.00023933332704473287,-1,-2,0.00023933332704473287,3.5899999141693115 +3312,22300,0.00028295963420532644,-1,-2,0.00028295963420532644,6.309999942779541 +3313,55100,4.6642468078061938e-05,-1,-2,4.6642468078061938e-05,2.5699999332427979 +3314,7800,0.00025256411754526198,-1,-2,0.00025256411754526198,1.9700000286102295 +3315,15000,0.00031199998920783401,-1,-2,0.00031199998920783401,4.679999828338623 +3316,78800,2.7284264433546923e-05,-1,-2,2.7284264433546923e-05,2.1500000953674316 +3317,0,inf,-1,-2,inf,1.0800000429153442 +3318,14000,0.00027571426471695304,-1,-2,0.00027571426471695304,3.8599998950958252 +3319,0,inf,-1,-2,inf,4.7100000381469727 +3320,0,inf,-1,-2,inf,4.369999885559082 +3321,29704,0.00014981147251091897,-1,-2,0.00014981147251091897,4.4499998092651367 +3322,31500,0.0001228571345563978,-1,-2,0.0001228571345563978,3.869999885559082 +3323,18000,0.00025111110880970955,-1,-2,0.00025111110880970955,4.5199999809265137 +3324,0,inf,-1,-2,inf,2 +3325,388000,1.2551546205941122e-05,-1,-2,1.2551546205941122e-05,4.869999885559082 +3326,145020,2.0548890461213887e-05,-1,-2,2.0548890461213887e-05,2.9800000190734863 +3327,8400,0.00010833333362825215,-1,-2,0.00010833333362825215,0.9100000262260437 +3328,39000,0.00011179487773915753,-1,-2,0.00011179487773915753,4.3600001335144043 +3329,33500,0.00017940299585461617,-1,-2,0.00017940299585461617,6.0100002288818359 +3330,36000,0.00010916667088167742,-1,-2,0.00010916667088167742,3.9300000667572021 +3331,8800,0.00035568184102885425,-1,-2,0.00035568184102885425,3.130000114440918 +3332,6090,0.00063711003167554736,-1,-2,0.00063711003167554736,3.880000114440918 +3333,34000,0.00012529412924777716,-1,-2,0.00012529412924777716,4.2600002288818359 +3334,12400,0.00035161292180418968,-1,-2,0.00035161292180418968,4.3600001335144043 +3335,108110,4.5786695409333333e-05,-1,-2,4.5786695409333333e-05,4.9499998092651367 +3336,16400,0.00030731706647202373,-1,-2,0.00030731706647202373,5.0399999618530273 +3337,0,inf,-1,-2,inf,5.4800000190734863 +3338,97000,3.2164945878321305e-05,-1,-2,3.2164945878321305e-05,3.119999885559082 +3339,244170,1.6668715034029447e-05,-1,-2,1.6668715034029447e-05,4.070000171661377 +3340,29000,3.5862067306879908e-05,-1,-2,3.5862067306879908e-05,1.0399999618530273 +3341,63000,6.9047615397721529e-05,-1,-2,6.9047615397721529e-05,4.3499999046325684 +3342,60000,7.3333330874447711e-06,-1,-2,7.3333330874447711e-06,0.43999999761581421 +3343,8300,0.00042530120117589831,-1,-2,0.00042530120117589831,3.5299999713897705 +3344,49300,0.00010223123535979539,-1,-2,0.00010223123535979539,5.0399999618530273 +3345,24000,3.6666668165707961e-05,-1,-2,3.6666668165707961e-05,0.87999999523162842 +3346,17850,0.00011988796177320182,-1,-2,0.00011988796177320182,2.1400001049041748 +3347,9000,0.00030777778010815382,-1,-2,0.00030777778010815382,2.7699999809265137 +3348,338000,6.9526622610283084e-06,-1,-2,6.9526622610283084e-06,2.3499999046325684 +3349,10000,0.00049200002104043961,-1,-2,0.00049200002104043961,4.9200000762939453 +3350,7500,0.00027599997702054679,-1,-2,0.00027599997702054679,2.0699999332427979 +3351,65000,8.6923078924883157e-05,-1,-2,8.6923078924883157e-05,5.6500000953674316 +3352,60000,3.0999999580672011e-05,-1,-2,3.0999999580672011e-05,1.8600000143051147 +3353,146220,3.1801395380171016e-05,-1,-2,3.1801395380171016e-05,4.6500000953674316 +3354,53300,7.0168855017982423e-05,-1,-2,7.0168855017982423e-05,3.7400000095367432 +3355,25400,8.3070859545841813e-05,-1,-2,8.3070859545841813e-05,2.1099998950958252 +3356,53000,9.4716982857789844e-05,-1,-2,9.4716982857789844e-05,5.0199999809265137 +3357,13960,0.00022349569189827889,-1,-2,0.00022349569189827889,3.119999885559082 +3358,0,inf,-1,-2,inf,3.3399999141693115 +3359,50000,2.0800000129383989e-05,-1,-2,2.0800000129383989e-05,1.0399999618530273 +3360,9550,0.00038743455661460757,-1,-2,0.00038743455661460757,3.7000000476837158 +3361,27600,0.00018768115842249244,-1,-2,0.00018768115842249244,5.179999828338623 +3362,17000,0.00032117648515850306,-1,-2,0.00032117648515850306,5.4600000381469727 +3363,14800,0.00019594594778027385,-1,-2,0.00019594594778027385,2.9000000953674316 +3364,37000,2.621621752041392e-05,-1,-2,2.621621752041392e-05,0.97000002861022949 +3365,22100,0.00030723982490599155,-1,-2,0.00030723982490599155,6.7899999618530273 +3366,66000,3.2424242817796767e-05,-1,-2,3.2424242817796767e-05,2.1400001049041748 +3367,158000,1.0126582310476806e-05,-1,-2,1.0126582310476806e-05,1.6000000238418579 +3368,30000,6.6666667407844216e-05,-1,-2,6.6666667407844216e-05,2 +3369,0,inf,-1,-2,inf,3.0299999713897705 +3370,9000,0.0002899999963119626,-1,-2,0.0002899999963119626,2.6099998950958252 +3371,6000,0.00055833329679444432,-1,-2,0.00055833329679444432,3.3499999046325684 +3372,29200,1.3356164345168509e-05,-1,-2,1.3356164345168509e-05,0.38999998569488525 +3373,66270,6.3075298385228962e-05,-1,-2,6.3075298385228962e-05,4.179999828338623 +3374,42000,0.00011690476094372571,-1,-2,0.00011690476094372571,4.9099998474121094 +3375,24000,0.00017416666378267109,-1,-2,0.00017416666378267109,4.179999828338623 +3376,24600,5.8536588767310604e-05,-1,-2,5.8536588767310604e-05,1.440000057220459 +3377,9560,0.00060983264120295644,-1,-2,0.00060983264120295644,5.8299999237060547 +3378,0,inf,-1,-2,inf,3.0999999046325684 +3379,13360,0.0004049401031807065,-1,-2,0.0004049401031807065,5.4099998474121094 +3380,9220,7.375271525233984e-05,-1,-2,7.375271525233984e-05,0.68000000715255737 +3381,15000,0.00027933332603424788,-1,-2,0.00027933332603424788,4.190000057220459 +3382,69000,4.8115940444404259e-05,-1,-2,4.8115940444404259e-05,3.3199999332427979 +3383,14100,0.00053900707280263305,-1,-2,0.00053900707280263305,7.5999999046325684 +3384,35300,6.1756378272548318e-05,-1,-2,6.1756378272548318e-05,2.1800000667572021 +3385,8050,0.0001552795001771301,-1,-2,0.0001552795001771301,1.25 +3386,77970,2.8728998586302623e-05,-1,-2,2.8728998586302623e-05,2.2400000095367432 +3387,0,inf,-1,-2,inf,4.1599998474121094 +3388,59220,6.5856129367602989e-06,-1,-2,6.5856129367602989e-06,0.38999998569488525 +3389,170000,2.9470589652191848e-05,-1,-2,2.9470589652191848e-05,5.0100002288818359 +3390,5800,0.00072068959707394242,-1,-2,0.00072068959707394242,4.179999828338623 +3391,8800,0.00012045454059261829,-1,-2,0.00012045454059261829,1.059999942779541 +3392,20000,9.4499999249819666e-05,-1,-2,9.4499999249819666e-05,1.8899999856948853 +3393,24300,0.0001185185246868059,-1,-2,0.0001185185246868059,2.880000114440918 +3394,15200,0.00010065788956126198,-1,-2,0.00010065788956126198,1.5299999713897705 +3395,22600,0.00021637167083099484,-1,-2,0.00021637167083099484,4.8899998664855957 +3396,34630,7.8255849075503647e-05,-1,-2,7.8255849075503647e-05,2.7100000381469727 +3397,40000,0.00013849999231752008,-1,-2,0.00013849999231752008,5.5399999618530273 +3398,50000,9.0600005933083594e-05,-1,-2,9.0600005933083594e-05,4.5300002098083496 +3399,14100,0.00022695036022923887,-1,-2,0.00022695036022923887,3.2000000476837158 +3400,0,inf,-1,-2,inf,3.2899999618530273 +3401,9560,0.00056589959422126412,-1,-2,0.00056589959422126412,5.4099998474121094 +3402,102000,2.2941176212043501e-05,-1,-2,2.2941176212043501e-05,2.3399999141693115 +3403,0,inf,-1,-2,inf,4.5 +3404,11620,5.59380350750871e-05,-1,-2,5.59380350750871e-05,0.64999997615814209 +3405,10200,5.1960782002424821e-05,-1,-2,5.1960782002424821e-05,0.52999997138977051 +3406,0,inf,-1,-2,inf,3.380000114440918 +3407,29000,1.7931033653439954e-05,-1,-2,1.7931033653439954e-05,0.51999998092651367 +3408,632600,7.3664241426740773e-06,-1,-2,7.3664241426740773e-06,4.6599998474121094 +3409,91000,2.5494504370726645e-05,-1,-2,2.5494504370726645e-05,2.3199999332427979 +3410,41500,7.0361449616029859e-05,-1,-2,7.0361449616029859e-05,2.9200000762939453 +3411,9500,0.00043999997433274984,-1,-2,0.00043999997433274984,4.179999828338623 +3412,96200,4.1580042307032272e-05,-1,-2,4.1580042307032272e-05,4 +3413,22600,8.2300888607278466e-05,-1,-2,8.2300888607278466e-05,1.8600000143051147 +3414,9200,0.00043586958781816065,-1,-2,0.00043586958781816065,4.0100002288818359 +3415,414000,4.7584539970557671e-06,-1,-2,4.7584539970557671e-06,1.9700000286102295 +3416,85900,2.5029105017893016e-05,-1,-2,2.5029105017893016e-05,2.1500000953674316 +3417,0,inf,-1,-2,inf,6.25 +3418,45000,5.8444446040084586e-05,-1,-2,5.8444446040084586e-05,2.630000114440918 +3419,93600,3.429487333050929e-05,-1,-2,3.429487333050929e-05,3.2100000381469727 +3420,9000,0.0003755555662792176,-1,-2,0.0003755555662792176,3.380000114440918 +3421,0,inf,-1,-2,inf,1.8999999761581421 +3422,40700,0.0001230958296218887,-1,-2,0.0001230958296218887,5.0100002288818359 +3423,17720,3.6681714846054092e-05,-1,-2,3.6681714846054092e-05,0.64999997615814209 +3424,0,inf,-1,-2,inf,3.9300000667572021 +3425,0,inf,-1,-2,inf,4.570000171661377 +3426,0,inf,-1,-2,inf,3.3499999046325684 +3427,80000,3.2500000088475645e-05,-1,-2,3.2500000088475645e-05,2.5999999046325684 +3428,27800,0.00017805754032451659,-1,-2,0.00017805754032451659,4.9499998092651367 +3429,37330,0.00012349316966719925,-1,-2,0.00012349316966719925,4.6100001335144043 +3430,17400,0.0002166666672565043,-1,-2,0.0002166666672565043,3.7699999809265137 +3431,37000,5.1081082347081974e-05,-1,-2,5.1081082347081974e-05,1.8899999856948853 +3432,3000,0.0012833332875743508,-1,-2,0.0012833332875743508,3.8499999046325684 +3433,38500,0.00014597401604987681,-1,-2,0.00014597401604987681,5.619999885559082 +3434,27900,0.00013835125719197094,-1,-2,0.00013835125719197094,3.8599998950958252 +3435,2800,0.0001857142779044807,-1,-2,0.0001857142779044807,0.51999998092651367 +3436,81000,4.4320986489765346e-05,-1,-2,4.4320986489765346e-05,3.5899999141693115 +3437,19400,0.00019690721819642931,-1,-2,0.00019690721819642931,3.8199999332427979 +3438,34700,0.00010951008152915165,-1,-2,0.00010951008152915165,3.7999999523162842 +3439,4500,0.00030000001424923539,-1,-2,0.00030000001424923539,1.3500000238418579 +3440,74300,7.1467024099547416e-05,-1,-2,7.1467024099547416e-05,5.309999942779541 +3441,0,inf,-1,-2,inf,5.190000057220459 +3442,16400,0.00010243902215734124,-1,-2,0.00010243902215734124,1.6799999475479126 +3443,8300,0.00046385542373172939,-1,-2,0.00046385542373172939,3.8499999046325684 +3444,12000,0.00063333334401249886,-1,-2,0.00063333334401249886,7.5999999046325684 +3445,32000,0.000110937500721775,-1,-2,0.000110937500721775,3.5499999523162842 +3446,62000,4.4677417463390157e-05,-1,-2,4.4677417463390157e-05,2.7699999809265137 +3447,388000,1.0154639312531799e-05,-1,-2,1.0154639312531799e-05,3.940000057220459 +3448,0,inf,-1,-2,inf,4.9499998092651367 +3449,10000,0.00023499998496845365,-1,-2,0.00023499998496845365,2.3499999046325684 +3450,157000,1.713375786493998e-05,-1,-2,1.713375786493998e-05,2.690000057220459 +3451,0,inf,-1,-2,inf,3.3399999141693115 +3452,55000,3.9272730646189302e-05,-1,-2,3.9272730646189302e-05,2.1600000858306885 +3453,30480,1.7716536603984423e-05,-1,-2,1.7716536603984423e-05,0.54000002145767212 +3454,38000,8.3421051385812461e-05,-1,-2,8.3421051385812461e-05,3.1700000762939453 +3455,20000,0.00031750000198371708,-1,-2,0.00031750000198371708,6.3499999046325684 +3456,17000,0.00029764705686829984,-1,-2,0.00029764705686829984,5.059999942779541 +3457,365400,1.3273124750412535e-05,-1,-2,1.3273124750412535e-05,4.8499999046325684 +3458,39000,8.9230772573500872e-05,-1,-2,8.9230772573500872e-05,3.4800000190734863 +3459,197000,1.0710659807955381e-05,-1,-2,1.0710659807955381e-05,2.1099998950958252 +3460,0,inf,-1,-2,inf,2.440000057220459 +3461,25000,0.00010959999781334773,-1,-2,0.00010959999781334773,2.7400000095367432 +3462,17000,0.00018352940969634801,-1,-2,0.00018352940969634801,3.119999885559082 +3463,56500,7.7168144343886524e-05,-1,-2,7.7168144343886524e-05,4.3600001335144043 +3464,242500,2.3216494810185395e-05,-1,-2,2.3216494810185395e-05,5.630000114440918 +3465,0,inf,-1,-2,inf,4.179999828338623 +3466,15200,0.00026118420646525919,-1,-2,0.00026118420646525919,3.9700000286102295 +3467,97000,4.4020616769557819e-05,-1,-2,4.4020616769557819e-05,4.2699999809265137 +3468,0,inf,-1,-2,inf,2.7599999904632568 +3469,62000,6.322580884443596e-05,-1,-2,6.322580884443596e-05,3.9200000762939453 +3470,14800,0.00026283785700798035,-1,-2,0.00026283785700798035,3.8900001049041748 +3471,37000,8.0270270700566471e-05,-1,-2,8.0270270700566471e-05,2.9700000286102295 +3472,58000,5.172413875698112e-05,-1,-2,5.172413875698112e-05,3 +3473,21000,0.00017952380585484207,-1,-2,0.00017952380585484207,3.7699999809265137 +3474,25000,0.00017159999697469175,-1,-2,0.00017159999697469175,4.2899999618530273 +3475,30800,0.00012662337394431233,-1,-2,0.00012662337394431233,3.9000000953674316 +3476,61000,6.7704917455557734e-05,-1,-2,6.7704917455557734e-05,4.130000114440918 +3477,29350,9.982964547816664e-05,-1,-2,9.982964547816664e-05,2.9300000667572021 +3478,80200,7.4189527367707342e-05,-1,-2,7.4189527367707342e-05,5.9499998092651367 +3479,14400,0.00012291666644159704,-1,-2,0.00012291666644159704,1.7699999809265137 +3480,18000,0.00010555555491009727,-1,-2,0.00010555555491009727,1.8999999761581421 +3481,28990,1.5522593457717448e-05,-1,-2,1.5522593457717448e-05,0.44999998807907104 +3482,43950,8.7827073002699763e-05,-1,-2,8.7827073002699763e-05,3.8599998950958252 +3483,19000,0.00020052630861755461,-1,-2,0.00020052630861755461,3.809999942779541 +3484,8000,0.00032249998184852302,-1,-2,0.00032249998184852302,2.5799999237060547 +3485,12000,0.00031249999301508069,-1,-2,0.00031249999301508069,3.75 +3486,9400,0.00061914895195513964,-1,-2,0.00061914895195513964,5.820000171661377 +3487,54400,5.422794129117392e-05,-1,-2,5.422794129117392e-05,2.9500000476837158 +3488,17300,0.00016184970445465297,-1,-2,0.00016184970445465297,2.7999999523162842 +3489,0,inf,-1,-2,inf,1.5800000429153442 +3490,0,inf,-1,-2,inf,1.9700000286102295 +3491,0,inf,-1,-2,inf,4.5199999809265137 +3492,7200,0.00030000001424923539,-1,-2,0.00030000001424923539,2.1600000858306885 +3493,133000,2.2330827050609514e-05,-1,-2,2.2330827050609514e-05,2.9700000286102295 +3494,10500,0.00027142855105921626,-1,-2,0.00027142855105921626,2.8499999046325684 +3495,78800,3.5025379474973306e-05,-1,-2,3.5025379474973306e-05,2.7599999904632568 +3496,13960,0.00034455588320270181,-1,-2,0.00034455588320270181,4.809999942779541 +3497,0,inf,-1,-2,inf,2.7000000476837158 +3498,7200,0.00030277780024334788,-1,-2,0.00030277780024334788,2.1800000667572021 +3499,23100,9.1341986262705177e-05,-1,-2,9.1341986262705177e-05,2.1099998950958252 +3500,17600,0.00021306818234734237,-1,-2,0.00021306818234734237,3.75 +3501,75000,6.6800006607081741e-05,-1,-2,6.6800006607081741e-05,5.0100002288818359 +3502,11500,0.00012608696124516428,-1,-2,0.00012608696124516428,1.4500000476837158 +3503,70000,6.1714286857750267e-05,-1,-2,6.1714286857750267e-05,4.320000171661377 +3504,0,inf,-1,-2,inf,3.119999885559082 +3505,152180,3.4630043955985457e-05,-1,-2,3.4630043955985457e-05,5.2699999809265137 +3506,325000,8.4615385276265442e-06,-1,-2,8.4615385276265442e-06,2.75 +3507,0,inf,-1,-2,inf,2.690000057220459 +3508,12700,0.0004220472474116832,-1,-2,0.0004220472474116832,5.3600001335144043 +3509,0,inf,-1,-2,inf,4.4699997901916504 +3510,15400,0.00038376622251234949,-1,-2,0.00038376622251234949,5.9099998474121094 +3511,46100,8.5466381278820336e-05,-1,-2,8.5466381278820336e-05,3.940000057220459 +3512,64300,4.2923795263050124e-05,-1,-2,4.2923795263050124e-05,2.7599999904632568 +3513,14000,0.00026928572333417833,-1,-2,0.00026928572333417833,3.7699999809265137 +3514,43300,1.0392609510745388e-05,-1,-2,1.0392609510745388e-05,0.44999998807907104 +3515,9104,0.00056348857469856739,-1,-2,0.00056348857469856739,5.130000114440918 +3516,25000,9.8399999842513353e-05,-1,-2,9.8399999842513353e-05,2.4600000381469727 +3517,67000,7.8656717960257083e-05,-1,-2,7.8656717960257083e-05,5.2699999809265137 +3518,0,inf,-1,-2,inf,4.8299999237060547 +3519,7200,0.00039583331090398133,-1,-2,0.00039583331090398133,2.8499999046325684 +3520,39000,6.692307215416804e-05,-1,-2,6.692307215416804e-05,2.6099998950958252 +3521,40000,0.00013450000551529229,-1,-2,0.00013450000551529229,5.380000114440918 +3522,149000,1.7852349628810771e-05,-1,-2,1.7852349628810771e-05,2.6600000858306885 +3523,7800,0.00023974358919076622,-1,-2,0.00023974358919076622,1.8700000047683716 +3524,30500,7.1147544076666236e-05,-1,-2,7.1147544076666236e-05,2.1700000762939453 +3525,8800,0.00037613636231981218,-1,-2,0.00037613636231981218,3.309999942779541 +3526,100000,2.3800001144991256e-05,-1,-2,2.3800001144991256e-05,2.380000114440918 +3527,39400,0.00010532994929235429,-1,-2,0.00010532994929235429,4.1500000953674316 +3528,8300,0.00022530120622832328,-1,-2,0.00022530120622832328,1.8700000047683716 +3529,45100,8.847006392898038e-05,-1,-2,8.847006392898038e-05,3.9900000095367432 +3530,0,inf,-1,-2,inf,3.3900001049041748 +3531,28900,0.000166782017913647,-1,-2,0.000166782017913647,4.820000171661377 +3532,224000,9.4196420832304284e-06,-1,-2,9.4196420832304284e-06,2.1099998950958252 +3533,0,inf,-1,-2,inf,3.7400000095367432 +3534,415380,9.9186281659058295e-06,-1,-2,9.9186281659058295e-06,4.119999885559082 +3535,220000,2.4409089746768586e-05,-1,-2,2.4409089746768586e-05,5.369999885559082 +3536,34300,0.00016413994308095425,-1,-2,0.00016413994308095425,5.630000114440918 +3537,8300,0.00054578314302489161,-1,-2,0.00054578314302489161,4.5300002098083496 +3538,22200,0.00012432431685738266,-1,-2,0.00012432431685738266,2.7599999904632568 +3539,177000,1.7740114344633184e-05,-1,-2,1.7740114344633184e-05,3.1400001049041748 +3540,43270,0.00015692165470682085,-1,-2,0.00015692165470682085,6.7899999618530273 +3541,0,inf,-1,-2,inf,1.4800000190734863 +3542,62000,8.1612903159111738e-05,-1,-2,8.1612903159111738e-05,5.059999942779541 +3543,74600,5.643431723001413e-05,-1,-2,5.643431723001413e-05,4.2100000381469727 +3544,55000,5.6181816034950316e-05,-1,-2,5.6181816034950316e-05,3.0899999141693115 +3545,79100,3.9317317714449018e-05,-1,-2,3.9317317714449018e-05,3.1099998950958252 +3546,45600,4.4078948121750727e-05,-1,-2,4.4078948121750727e-05,2.0099999904632568 +3547,20400,0.00012745097046718001,-1,-2,0.00012745097046718001,2.5999999046325684 +3548,6580,0.00041033435263670981,-1,-2,0.00041033435263670981,2.7000000476837158 +3549,34700,1.6138328646775335e-05,-1,-2,1.6138328646775335e-05,0.56000000238418579 +3550,157000,1.6433121345471591e-05,-1,-2,1.6433121345471591e-05,2.5799999237060547 +3551,2400,0.0022624998819082975,-1,-2,0.0022624998819082975,5.429999828338623 +3552,74900,2.0293724446673878e-05,-1,-2,2.0293724446673878e-05,1.5199999809265137 +3553,22000,0.00018999999156221747,-1,-2,0.00018999999156221747,4.179999828338623 +3554,150700,1.2939615771756507e-05,-1,-2,1.2939615771756507e-05,1.9500000476837158 +3555,4400,0.00069545453879982233,-1,-2,0.00069545453879982233,3.059999942779541 +3556,4800,0.00076666666427627206,-1,-2,0.00076666666427627206,3.6800000667572021 +3557,0,inf,-1,-2,inf,1.6499999761581421 +3558,30000,6.2333332607522607e-05,-1,-2,6.2333332607522607e-05,1.8700000047683716 +3559,38000,7.1315793320536613e-05,-1,-2,7.1315793320536613e-05,2.7100000381469727 +3560,28900,8.4775085269939154e-05,-1,-2,8.4775085269939154e-05,2.4500000476837158 +3561,35300,4.1076487832469866e-05,-1,-2,4.1076487832469866e-05,1.4500000476837158 +3562,12000,0.00020000000949949026,-1,-2,0.00020000000949949026,2.4000000953674316 +3563,15000,0.00032933332840912044,-1,-2,0.00032933332840912044,4.940000057220459 +3564,1500,0.00046666665002703667,-1,-2,0.00046666665002703667,0.69999998807907104 +3565,29000,6.6206892370246351e-05,-1,-2,6.6206892370246351e-05,1.9199999570846558 +3566,22800,0.00026096490910276771,-1,-2,0.00026096490910276771,5.9499998092651367 +3567,56200,3.683273826027289e-05,-1,-2,3.683273826027289e-05,2.0699999332427979 +3568,0,inf,-1,-2,inf,4.1500000953674316 +3569,3560,0.00094943825388327241,-1,-2,0.00094943825388327241,3.380000114440918 +3570,325000,1.1876923053932842e-05,-1,-2,1.1876923053932842e-05,3.8599998950958252 +3571,25600,0.00015703124518040568,-1,-2,0.00015703124518040568,4.0199999809265137 +3572,12000,0.00043333330540917814,-1,-2,0.00043333330540917814,5.1999998092651367 +3573,39980,0.00013456729357130826,-1,-2,0.00013456729357130826,5.380000114440918 +3574,54900,2.7322405003360473e-05,-1,-2,2.7322405003360473e-05,1.5 +3575,176300,9.1888823590124957e-06,-1,-2,9.1888823590124957e-06,1.6200000047683716 +3576,152180,2.3656195480725728e-05,-1,-2,2.3656195480725728e-05,3.5999999046325684 +3577,8300,0.00021204819495324045,-1,-2,0.00021204819495324045,1.7599999904632568 +3578,11600,0.00057844829279929399,-1,-2,0.00057844829279929399,6.7100000381469727 +3579,23000,0.00019652173796202987,-1,-2,0.00019652173796202987,4.5199999809265137 +3580,16800,0.00029345237999223173,-1,-2,0.00029345237999223173,4.929999828338623 +3581,70000,4.3857140553882346e-05,-1,-2,4.3857140553882346e-05,3.0699999332427979 +3582,4890,0.00027198364841751754,-1,-2,0.00027198364841751754,1.3300000429153442 +3583,23100,6.1038961575832218e-05,-1,-2,6.1038961575832218e-05,1.4099999666213989 +3584,0,inf,-1,-2,inf,2.9700000286102295 +3585,6300,0.00021111112437210977,-1,-2,0.00021111112437210977,1.3300000429153442 +3586,133000,3.1278195820050314e-05,-1,-2,3.1278195820050314e-05,4.1599998474121094 +3587,36500,7.3150687967427075e-05,-1,-2,7.3150687967427075e-05,2.6700000762939453 +3588,7400,0.00065810809610411525,-1,-2,0.00065810809610411525,4.869999885559082 +3589,0,inf,-1,-2,inf,5.690000057220459 +3590,0,inf,-1,-2,inf,4.4000000953674316 +3591,17200,0.00026802325737662613,-1,-2,0.00026802325737662613,4.6100001335144043 +3592,16000,0.00039187498623505235,-1,-2,0.00039187498623505235,6.2699999809265137 +3593,39000,7.1282047429122031e-05,-1,-2,7.1282047429122031e-05,2.7799999713897705 +3594,11500,0.00023652173695154488,-1,-2,0.00023652173695154488,2.7200000286102295 +3595,0,inf,-1,-2,inf,2.380000114440918 +3596,435000,1.2827586033381522e-05,-1,-2,1.2827586033381522e-05,5.5799999237060547 +3597,81000,2.0123456124565564e-05,-1,-2,2.0123456124565564e-05,1.6299999952316284 +3598,32500,5.1076920499326661e-05,-1,-2,5.1076920499326661e-05,1.6599999666213989 +3599,27600,7.7898555900901556e-05,-1,-2,7.7898555900901556e-05,2.1500000953674316 +3600,52600,5.0190115871373564e-05,-1,-2,5.0190115871373564e-05,2.6400001049041748 +3601,65300,3.6753448512172326e-05,-1,-2,3.6753448512172326e-05,2.4000000953674316 +3602,66300,1.9909502952941693e-05,-1,-2,1.9909502952941693e-05,1.3200000524520874 +3603,62000,6.6612905357033014e-05,-1,-2,6.6612905357033014e-05,4.130000114440918 +3604,35400,0.00014943502901587635,-1,-2,0.00014943502901587635,5.2899999618530273 +3605,0,inf,-1,-2,inf,3.9700000286102295 +3606,11900,0.00028907562955282629,-1,-2,0.00028907562955282629,3.440000057220459 +3607,28800,0.00012881944712717086,-1,-2,0.00012881944712717086,3.7100000381469727 +3608,12000,0.00022500001068692654,-1,-2,0.00022500001068692654,2.7000000476837158 +3609,141200,2.2662889023195021e-05,-1,-2,2.2662889023195021e-05,3.2000000476837158 +3610,8000,0.00013875000877305865,-1,-2,0.00013875000877305865,1.1100000143051147 +3611,24000,0.00015291667659766972,-1,-2,0.00015291667659766972,3.6700000762939453 +3612,21600,9.9074080935679376e-05,-1,-2,9.9074080935679376e-05,2.1400001049041748 +3613,80500,2.583850800874643e-05,-1,-2,2.583850800874643e-05,2.0799999237060547 +3614,14600,0.00018493151583243161,-1,-2,0.00018493151583243161,2.7000000476837158 +3615,69200,6.2716768297832459e-05,-1,-2,6.2716768297832459e-05,4.3400001525878906 +3616,23510,0.00014036579523235559,-1,-2,0.00014036579523235559,3.2999999523162842 +3617,0,inf,-1,-2,inf,1.3400000333786011 +3618,61500,5.8373982028570026e-05,-1,-2,5.8373982028570026e-05,3.5899999141693115 +3619,350000,8.6285717770806514e-06,-1,-2,8.6285717770806514e-06,3.0199999809265137 +3620,0,inf,-1,-2,inf,5.0799999237060547 +3621,14300,0.00034615382901392877,-1,-2,0.00034615382901392877,4.9499998092651367 +3622,29700,0.00018754210032057017,-1,-2,0.00018754210032057017,5.570000171661377 +3623,5000,0.00043200002983212471,-1,-2,0.00043200002983212471,2.1600000858306885 +3624,9300,0.00031182795646600425,-1,-2,0.00031182795646600425,2.9000000953674316 +3625,58100,7.6419964898377657e-05,-1,-2,7.6419964898377657e-05,4.440000057220459 +3626,12650,0.00013992094318382442,-1,-2,0.00013992094318382442,1.7699999809265137 +3627,39400,9.8984775831922889e-05,-1,-2,9.8984775831922889e-05,3.9000000953674316 +3628,69800,6.7335240601096302e-05,-1,-2,6.7335240601096302e-05,4.6999998092651367 +3629,27100,8.3394836110528558e-05,-1,-2,8.3394836110528558e-05,2.2599999904632568 +3630,59220,5.6062141084112227e-05,-1,-2,5.6062141084112227e-05,3.3199999332427979 +3631,41400,6.6666667407844216e-05,-1,-2,6.6666667407844216e-05,2.7599999904632568 +3632,71000,1.3098591807647608e-05,-1,-2,1.3098591807647608e-05,0.93000000715255737 +3633,103000,3.5922330425819382e-05,-1,-2,3.5922330425819382e-05,3.7000000476837158 +3634,28900,0.00012802767741959542,-1,-2,0.00012802767741959542,3.7000000476837158 +3635,40400,0.00010024753282777965,-1,-2,0.00010024753282777965,4.0500001907348633 +3636,335000,8.2388060036464594e-06,-1,-2,8.2388060036464594e-06,2.7599999904632568 +3637,70000,3.9142858440754935e-05,-1,-2,3.9142858440754935e-05,2.7400000095367432 +3638,1100,0.0015363637357950211,-1,-2,0.0015363637357950211,1.690000057220459 +3639,3400,0.0006441176519729197,-1,-2,0.0006441176519729197,2.190000057220459 +3640,14500,0.00035172412754036486,-1,-2,0.00035172412754036486,5.0999999046325684 +3641,37500,8.8533328380435705e-05,-1,-2,8.8533328380435705e-05,3.3199999332427979 +3642,8800,0.00037727272137999535,-1,-2,0.00037727272137999535,3.3199999332427979 +3643,21320,0.00016697935643605888,-1,-2,0.00016697935643605888,3.559999942779541 +3644,100000,4.0799997805152088e-05,-1,-2,4.0799997805152088e-05,4.0799999237060547 +3645,43600,6.6284403146710247e-05,-1,-2,6.6284403146710247e-05,2.8900001049041748 +3646,11500,0.00031304347794502974,-1,-2,0.00031304347794502974,3.5999999046325684 +3647,37000,8.7297295976895839e-05,-1,-2,8.7297295976895839e-05,3.2300000190734863 +3648,66000,4.9696969654178247e-05,-1,-2,4.9696969654178247e-05,3.2799999713897705 +3649,25000,9.5600007625762373e-05,-1,-2,9.5600007625762373e-05,2.3900001049041748 +3650,4300,0.00048139534192159772,-1,-2,0.00048139534192159772,2.0699999332427979 +3651,137000,8.9781024144031107e-06,-1,-2,8.9781024144031107e-06,1.2300000190734863 +3652,85900,2.1071011360618286e-05,-1,-2,2.1071011360618286e-05,1.809999942779541 +3653,500,0.0065000001341104507,-1,-2,0.0065000001341104507,3.25 +3654,27400,0.000139416049933061,-1,-2,0.000139416049933061,3.8199999332427979 +3655,19700,0.00014720812032464892,-1,-2,0.00014720812032464892,2.9000000953674316 +3656,0,inf,-1,-2,inf,3.3499999046325684 +3657,1000,0.0061099999584257603,-1,-2,0.0061099999584257603,6.1100001335144043 +3658,0,inf,-1,-2,inf,2.6500000953674316 +3659,0,inf,-1,-2,inf,4.630000114440918 +3660,0,inf,-1,-2,inf,3.7599999904632568 +3661,8310,0.0003321299736853689,-1,-2,0.0003321299736853689,2.7599999904632568 +3662,70300,5.3058320190757513e-05,-1,-2,5.3058320190757513e-05,3.7300000190734863 +3663,7600,0.00054342107614502311,-1,-2,0.00054342107614502311,4.130000114440918 +3664,16400,9.268292342312634e-05,-1,-2,9.268292342312634e-05,1.5199999809265137 +3665,12630,0.00032224864116869867,-1,-2,0.00032224864116869867,4.070000171661377 +3666,9000,8.4444443928077817e-05,-1,-2,8.4444443928077817e-05,0.75999999046325684 +3667,0,inf,-1,-2,inf,3.4500000476837158 +3668,6000,0.00042999998549930751,-1,-2,0.00042999998549930751,2.5799999237060547 +3669,51480,1.76767680386547e-05,-1,-2,1.76767680386547e-05,0.9100000262260437 +3670,414000,6.4009664129116572e-06,-1,-2,6.4009664129116572e-06,2.6500000953674316 +3671,28000,0.00010821428440976888,-1,-2,0.00010821428440976888,3.0299999713897705 +3672,8100,0.00053333333926275373,-1,-2,0.00053333333926275373,4.320000171661377 +3673,0,inf,-1,-2,inf,2.9300000667572021 +3674,9800,0.0001775510172592476,-1,-2,0.0001775510172592476,1.7400000095367432 +3675,0,inf,-1,-2,inf,1.3400000333786011 +3676,13600,0.00056102941744029522,-1,-2,0.00056102941744029522,7.630000114440918 +3677,28000,4.6428569476120174e-05,-1,-2,4.6428569476120174e-05,1.2999999523162842 +3678,5700,0.00051403511315584183,-1,-2,0.00051403511315584183,2.9300000667572021 +3679,0,inf,-1,-2,inf,2.380000114440918 +3680,91900,3.8520131056429818e-05,-1,-2,3.8520131056429818e-05,3.5399999618530273 +3681,80000,3.8624999433523044e-05,-1,-2,3.8624999433523044e-05,3.0899999141693115 +3682,61000,1.4918033230060246e-05,-1,-2,1.4918033230060246e-05,0.9100000262260437 +3683,327000,2.3241589133249363e-06,-1,-2,2.3241589133249363e-06,0.75999999046325684 +3684,62000,8.2580641901586205e-05,-1,-2,8.2580641901586205e-05,5.119999885559082 +3685,80600,4.5781638618791476e-05,-1,-2,4.5781638618791476e-05,3.690000057220459 +3686,39400,0.00010532994929235429,-1,-2,0.00010532994929235429,4.1500000953674316 +3687,9000,0.00046888887300156057,-1,-2,0.00046888887300156057,4.2199997901916504 +3688,39700,0.00012921914458274841,-1,-2,0.00012921914458274841,5.130000114440918 +3689,9104,0.00020540421246550977,-1,-2,0.00020540421246550977,1.8700000047683716 +3690,38000,5.2368421165738255e-05,-1,-2,5.2368421165738255e-05,1.9900000095367432 +3691,326700,1.0621365618135314e-05,-1,-2,1.0621365618135314e-05,3.4700000286102295 +3692,11500,0.00028869564994238317,-1,-2,0.00028869564994238317,3.3199999332427979 +3693,25790,0.00022411788813769817,-1,-2,0.00022411788813769817,5.7800002098083496 +3694,14400,0.00015763888950459659,-1,-2,0.00015763888950459659,2.2699999809265137 +3695,100000,2.7100000806967728e-05,-1,-2,2.7100000806967728e-05,2.7100000381469727 +3696,28990,1.3452914572553709e-05,-1,-2,1.3452914572553709e-05,0.38999998569488525 +3697,9600,0.00037604165845550597,-1,-2,0.00037604165845550597,3.6099998950958252 +3698,0,inf,-1,-2,inf,4.6399998664855957 +3699,0,inf,-1,-2,inf,2.7000000476837158 +3700,12000,0.00023333332501351833,-1,-2,0.00023333332501351833,2.7999999523162842 +3701,12000,0.00032083332189358771,-1,-2,0.00032083332189358771,3.8499999046325684 +3702,0,inf,-1,-2,inf,3.3199999332427979 +3703,15000,0.00044666664325632155,-1,-2,0.00044666664325632155,6.6999998092651367 +3704,66000,5.7272725825896487e-05,-1,-2,5.7272725825896487e-05,3.7799999713897705 +3705,8000,0.00037625001277774572,-1,-2,0.00037625001277774572,3.0099999904632568 +3706,10000,0.00040300001273863018,-1,-2,0.00040300001273863018,4.0300002098083496 +3707,0,inf,-1,-2,inf,4.1500000953674316 +3708,14400,0.00015069445362314582,-1,-2,0.00015069445362314582,2.1700000762939453 +3709,30000,0.0002119999990100041,-1,-2,0.0002119999990100041,6.3600001335144043 +3710,0,inf,-1,-2,inf,1.6499999761581421 +3711,3560,0.0014382022200152278,-1,-2,0.0014382022200152278,5.119999885559082 +3712,0,inf,-1,-2,inf,1.6799999475479126 +3713,30200,8.9735098299570382e-05,-1,-2,8.9735098299570382e-05,2.7100000381469727 +3714,8400,0.00032261904561892152,-1,-2,0.00032261904561892152,2.7100000381469727 +3715,3600,0.0012138888705521822,-1,-2,0.0012138888705521822,4.369999885559082 +3716,58160,4.5220083848107606e-05,-1,-2,4.5220083848107606e-05,2.630000114440918 +3717,1804,0.0012305986601859331,-1,-2,0.0012305986601859331,2.2200000286102295 +3718,18000,0.00020777777535840869,-1,-2,0.00020777777535840869,3.7400000095367432 +3719,75000,5.6933331507025287e-05,-1,-2,5.6933331507025287e-05,4.2699999809265137 +3720,59500,7.5966388976667076e-05,-1,-2,7.5966388976667076e-05,4.5199999809265137 +3721,8200,0.00042439025128260255,-1,-2,0.00042439025128260255,3.4800000190734863 +3722,10100,0.00023663367028348148,-1,-2,0.00023663367028348148,2.3900001049041748 +3723,158000,3.6202531191520393e-05,-1,-2,3.6202531191520393e-05,5.7199997901916504 +3724,17400,4.8850575694814324e-05,-1,-2,4.8850575694814324e-05,0.85000002384185791 +3725,174500,2.3954153220984153e-05,-1,-2,2.3954153220984153e-05,4.179999828338623 +3726,23000,8.4347826486919075e-05,-1,-2,8.4347826486919075e-05,1.940000057220459 +3727,33370,4.6149234549375251e-05,-1,-2,4.6149234549375251e-05,1.5399999618530273 +3728,12000,0.00023000000510364771,-1,-2,0.00023000000510364771,2.7599999904632568 +3729,160800,2.848258736776188e-05,-1,-2,2.848258736776188e-05,4.5799999237060547 +3730,11900,0.00020084033894818276,-1,-2,0.00020084033894818276,2.3900001049041748 +3731,12000,0.00049083330668509007,-1,-2,0.00049083330668509007,5.8899998664855957 +3732,0,inf,-1,-2,inf,1.9900000095367432 +3733,109500,5.7625569752417505e-05,-1,-2,5.7625569752417505e-05,6.309999942779541 +3734,9104,0.00039323372766375542,-1,-2,0.00039323372766375542,3.5799999237060547 +3735,70000,1.3000000762986019e-05,-1,-2,1.3000000762986019e-05,0.9100000262260437 +3736,16800,3.8690475776093081e-05,-1,-2,3.8690475776093081e-05,0.64999997615814209 +3737,160800,2.6430348952999339e-05,-1,-2,2.6430348952999339e-05,4.25 +3738,51000,4.8627451178617775e-05,-1,-2,4.8627451178617775e-05,2.4800000190734863 +3739,0,inf,-1,-2,inf,2.690000057220459 +3740,110000,2.1818183085997589e-05,-1,-2,2.1818183085997589e-05,2.4000000953674316 +3741,179000,1.212290590046905e-05,-1,-2,1.212290590046905e-05,2.1700000762939453 +3742,0,inf,-1,-2,inf,4.0799999237060547 +3743,50000,3.9400001696776599e-05,-1,-2,3.9400001696776599e-05,1.9700000286102295 +3744,400000,8.9999994088429958e-06,-1,-2,8.9999994088429958e-06,3.5999999046325684 +3745,10000,0.00067699997453019023,-1,-2,0.00067699997453019023,6.7699999809265137 +3746,100000,3.0400000468944199e-05,-1,-2,3.0400000468944199e-05,3.0399999618530273 +3747,8100,0.00050987658323720098,-1,-2,0.00050987658323720098,4.130000114440918 +3748,33050,0.00022874432033859193,-1,-2,0.00022874432033859193,7.559999942779541 +3749,25000,0.0001235999952768907,-1,-2,0.0001235999952768907,3.0899999141693115 +3750,18100,0.00020939226669725031,-1,-2,0.00020939226669725031,3.7899999618530273 +3751,435000,4.3448276301205624e-06,-1,-2,4.3448276301205624e-06,1.8899999856948853 +3752,62000,4.2741936340462416e-05,-1,-2,4.2741936340462416e-05,2.6500000953674316 +3753,47000,4.7872341383481398e-05,-1,-2,4.7872341383481398e-05,2.25 +3754,115000,9.7391302915639244e-06,-1,-2,9.7391302915639244e-06,1.1200000047683716 +3755,11000,0.00014999999257270247,-1,-2,0.00014999999257270247,1.6499999761581421 +3756,0,inf,-1,-2,inf,4.5799999237060547 +3757,197000,1.4010151971888263e-05,-1,-2,1.4010151971888263e-05,2.7599999904632568 +3758,34400,8.779070049058646e-05,-1,-2,8.779070049058646e-05,3.0199999809265137 +3759,43000,9.1627909569069743e-05,-1,-2,9.1627909569069743e-05,3.940000057220459 +3760,62050,2.3368251277133822e-05,-1,-2,2.3368251277133822e-05,1.4500000476837158 +3761,16800,0.00029166668537072837,-1,-2,0.00029166668537072837,4.9000000953674316 +3762,133000,3.0150376915116794e-05,-1,-2,3.0150376915116794e-05,4.0100002288818359 +3763,90000,3.622222357080318e-05,-1,-2,3.622222357080318e-05,3.2599999904632568 +3764,223900,1.0897722859226633e-05,-1,-2,1.0897722859226633e-05,2.440000057220459 +3765,97000,1.3917526302975602e-05,-1,-2,1.3917526302975602e-05,1.3500000238418579 +3766,32500,0.00013661538832820952,-1,-2,0.00013661538832820952,4.440000057220459 +3767,0,inf,-1,-2,inf,4.179999828338623 +3768,0,inf,-1,-2,inf,2.6400001049041748 +3769,3000,0.00050999998347833753,-1,-2,0.00050999998347833753,1.5299999713897705 +3770,13500,0.00014814814494457096,-1,-2,0.00014814814494457096,2 +3771,25000,0.00013559999933931977,-1,-2,0.00013559999933931977,3.3900001049041748 +3772,29000,0.00011620689474511892,-1,-2,0.00011620689474511892,3.369999885559082 +3773,9300,0.0002838709915522486,-1,-2,0.0002838709915522486,2.6400001049041748 +3774,20000,0.00010299999848939478,-1,-2,0.00010299999848939478,2.059999942779541 +3775,0,inf,-1,-2,inf,1.8700000047683716 +3776,5700,0.0006596491439267993,-1,-2,0.0006596491439267993,3.7599999904632568 +3777,6400,0.00075000000651925802,-1,-2,0.00075000000651925802,4.8000001907348633 +3778,8300,0.00044578313827514648,-1,-2,0.00044578313827514648,3.7000000476837158 +3779,11500,0.00014782609650865197,-1,-2,0.00014782609650865197,1.7000000476837158 +3780,20900,9.9521530501078814e-05,-1,-2,9.9521530501078814e-05,2.0799999237060547 +3781,8700,0.00045977011905051768,-1,-2,0.00045977011905051768,4 +3782,82000,3.6463414289755747e-05,-1,-2,3.6463414289755747e-05,2.9900000095367432 +3783,47000,8.8936169049702585e-05,-1,-2,8.8936169049702585e-05,4.179999828338623 +3784,70000,7.3285715188831091e-05,-1,-2,7.3285715188831091e-05,5.130000114440918 +3785,102000,2.7156862415722571e-05,-1,-2,2.7156862415722571e-05,2.7699999809265137 +3786,338000,2.8994084004807519e-06,-1,-2,2.8994084004807519e-06,0.98000001907348633 +3787,99200,4.838709719479084e-05,-1,-2,4.838709719479084e-05,4.8000001907348633 +3788,12000,0.00016999999934341758,-1,-2,0.00016999999934341758,2.0399999618530273 +3789,4908,0.000890383031219244,-1,-2,0.000890383031219244,4.369999885559082 +3790,27400,9.6715331892482936e-05,-1,-2,9.6715331892482936e-05,2.6500000953674316 +3791,43000,0.00010348836804041639,-1,-2,0.00010348836804041639,4.4499998092651367 +3792,26000,0.00013076922914478928,-1,-2,0.00013076922914478928,3.4000000953674316 +3793,0,inf,-1,-2,inf,0.81000000238418579 +3794,13600,0.00044485295074991882,-1,-2,0.00044485295074991882,6.0500001907348633 +3795,12100,0.0001859504118328914,-1,-2,0.0001859504118328914,2.25 +3796,44000,6.0681821196340024e-05,-1,-2,6.0681821196340024e-05,2.6700000762939453 +3797,1890,0.0023068783339112997,-1,-2,0.0023068783339112997,4.3600001335144043 +3798,9500,0.00035263155587017536,-1,-2,0.00035263155587017536,3.3499999046325684 +3799,24000,0.00012500000593718141,-1,-2,0.00012500000593718141,3 +3800,11600,0.00024396550725214183,-1,-2,0.00024396550725214183,2.8299999237060547 +3801,28000,9.8928569059353322e-05,-1,-2,9.8928569059353322e-05,2.7699999809265137 +3802,9000,0.00029555556830018759,-1,-2,0.00029555556830018759,2.6600000858306885 +3803,12700,0.00036929134512320161,-1,-2,0.00036929134512320161,4.690000057220459 +3804,53700,6.2011175032239407e-05,-1,-2,6.2011175032239407e-05,3.3299999237060547 +3805,179000,2.983240301546175e-05,-1,-2,2.983240301546175e-05,5.3400001525878906 +3806,41400,7.4154588219244033e-05,-1,-2,7.4154588219244033e-05,3.0699999332427979 +3807,66400,3.9759037463227287e-05,-1,-2,3.9759037463227287e-05,2.6400001049041748 +3808,660000,4.3939394345215987e-06,-1,-2,4.3939394345215987e-06,2.9000000953674316 +3809,160800,2.9228855055407621e-05,-1,-2,2.9228855055407621e-05,4.6999998092651367 +3810,23510,0.00016588685684837401,-1,-2,0.00016588685684837401,3.9000000953674316 +3811,24600,0.00011382113734725863,-1,-2,0.00011382113734725863,2.7999999523162842 +3812,77970,2.0777222744072787e-05,-1,-2,2.0777222744072787e-05,1.6200000047683716 +3813,66000,4.6060606109676883e-05,-1,-2,4.6060606109676883e-05,3.0399999618530273 +3814,79000,5.8607594837667421e-05,-1,-2,5.8607594837667421e-05,4.630000114440918 +3815,100000,3.35000004270114e-05,-1,-2,3.35000004270114e-05,3.3499999046325684 +3816,20000,0.00019400000746827573,-1,-2,0.00019400000746827573,3.880000114440918 +3817,3400,0.00059999997029080987,-1,-2,0.00059999997029080987,2.0399999618530273 +3818,66400,7.6204814831726253e-05,-1,-2,7.6204814831726253e-05,5.059999942779541 +3819,92700,7.2276154241990298e-05,-1,-2,7.2276154241990298e-05,6.6999998092651367 +3820,21000,0.00019190477905794978,-1,-2,0.00019190477905794978,4.0300002098083496 +3821,101000,3.4851484087994322e-05,-1,-2,3.4851484087994322e-05,3.5199999809265137 +3822,51000,5.0392154662404209e-05,-1,-2,5.0392154662404209e-05,2.5699999332427979 +3823,113500,3.9207046938827261e-05,-1,-2,3.9207046938827261e-05,4.4499998092651367 +3824,22930,0.00013301351282279938,-1,-2,0.00013301351282279938,3.0499999523162842 +3825,6430,0.0008880248642526567,-1,-2,0.0008880248642526567,5.7100000381469727 +3826,9100,0.0003780219703912735,-1,-2,0.0003780219703912735,3.440000057220459 +3827,9200,0.00040760869160294533,-1,-2,0.00040760869160294533,3.75 +3828,18000,0.00020277778094168752,-1,-2,0.00020277778094168752,3.6500000953674316 +3829,0,inf,-1,-2,inf,2.7699999809265137 +3830,50000,0.00010540000221226364,-1,-2,0.00010540000221226364,5.2699999809265137 +3831,9600,0.00041145834256894886,-1,-2,0.00041145834256894886,3.9500000476837158 +3832,122500,2.4979592126328498e-05,-1,-2,2.4979592126328498e-05,3.059999942779541 +3833,14200,5.7746477978071198e-05,-1,-2,5.7746477978071198e-05,0.81999999284744263 +3834,30480,7.6771648309659213e-05,-1,-2,7.6771648309659213e-05,2.3399999141693115 +3835,0,inf,-1,-2,inf,2.0099999904632568 +3836,86400,3.2407406251877546e-05,-1,-2,3.2407406251877546e-05,2.7999999523162842 +3837,48000,6.2083330703899264e-05,-1,-2,6.2083330703899264e-05,2.9800000190734863 +3838,39000,8.6153842858038843e-05,-1,-2,8.6153842858038843e-05,3.3599998950958252 +3839,33500,0.0001319402945227921,-1,-2,0.0001319402945227921,4.4200000762939453 +3840,414000,7.5603866207529791e-06,-1,-2,7.5603866207529791e-06,3.130000114440918 +3841,9100,0.00048571429215371609,-1,-2,0.00048571429215371609,4.4200000762939453 +3842,41500,6.9879519287496805e-05,-1,-2,6.9879519287496805e-05,2.9000000953674316 +3843,50000,4.1999999666586518e-05,-1,-2,4.1999999666586518e-05,2.0999999046325684 +3844,26120,0.00024157733423635364,-1,-2,0.00024157733423635364,6.309999942779541 +3845,32000,9.5625000540167093e-05,-1,-2,9.5625000540167093e-05,3.059999942779541 +3846,12700,0.00013858267629984766,-1,-2,0.00013858267629984766,1.7599999904632568 +3847,25000,6.5599997469689697e-05,-1,-2,6.5599997469689697e-05,1.6399999856948853 +3848,21700,0.0001921658986248076,-1,-2,0.0001921658986248076,4.1700000762939453 +3849,10000,0.00038900002255104482,-1,-2,0.00038900002255104482,3.8900001049041748 +3850,133480,2.3973629140527919e-05,-1,-2,2.3973629140527919e-05,3.2000000476837158 +3851,15500,0.00022387097124010324,-1,-2,0.00022387097124010324,3.4700000286102295 +3852,0,inf,-1,-2,inf,0.46000000834465027 +3853,0,inf,-1,-2,inf,1.6499999761581421 +3854,8100,0.00031111110001802444,-1,-2,0.00031111110001802444,2.5199999809265137 +3855,0,inf,-1,-2,inf,2.4000000953674316 +3856,62000,4.4516127672977746e-05,-1,-2,4.4516127672977746e-05,2.7599999904632568 +3857,22200,7.4324321758467704e-05,-1,-2,7.4324321758467704e-05,1.6499999761581421 +3858,9400,0.00017553190991748124,-1,-2,0.00017553190991748124,1.6499999761581421 +3859,68000,2.9558823371189646e-05,-1,-2,2.9558823371189646e-05,2.0099999904632568 +3860,11900,8.7394953879993409e-05,-1,-2,8.7394953879993409e-05,1.0399999618530273 +3861,36200,0.00012265193799976259,-1,-2,0.00012265193799976259,4.440000057220459 +3862,38000,7.15789501555264e-05,-1,-2,7.15789501555264e-05,2.7200000286102295 +3863,8700,0.00024367815058212727,-1,-2,0.00024367815058212727,2.119999885559082 +3864,7400,0.00043648650171235204,-1,-2,0.00043648650171235204,3.2300000190734863 +3865,22800,0.00021447367907967418,-1,-2,0.00021447367907967418,4.8899998664855957 +3866,39000,0.00012974358105566353,-1,-2,0.00012974358105566353,5.059999942779541 +3867,50000,5.2600003982661292e-05,-1,-2,5.2600003982661292e-05,2.630000114440918 +3868,8800,0.00015113636618480086,-1,-2,0.00015113636618480086,1.3300000429153442 +3869,205400,1.83057454705704e-05,-1,-2,1.83057454705704e-05,3.7599999904632568 +3870,200000,1.8700000509852543e-05,-1,-2,1.8700000509852543e-05,3.7400000095367432 +3871,33040,5.3571427997667342e-05,-1,-2,5.3571427997667342e-05,1.7699999809265137 +3872,10200,0.00062352942768484354,-1,-2,0.00062352942768484354,6.3600001335144043 +3873,112000,3.6071429349249229e-05,-1,-2,3.6071429349249229e-05,4.0399999618530273 +3874,7000,0.0007157142972573638,-1,-2,0.0007157142972573638,5.0100002288818359 +3875,10180,0.00020530451729428023,-1,-2,0.00020530451729428023,2.0899999141693115 +3876,36000,0.00010305555770173669,-1,-2,0.00010305555770173669,3.7100000381469727 +3877,0,inf,-1,-2,inf,3.8599998950958252 +3878,21700,0.00015345621795859188,-1,-2,0.00015345621795859188,3.3299999237060547 +3879,8300,0.00016987950948532671,-1,-2,0.00016987950948532671,1.4099999666213989 +3880,15000,0.00020866667910013348,-1,-2,0.00020866667910013348,3.130000114440918 +3881,26100,0.00014942529378458858,-1,-2,0.00014942529378458858,3.9000000953674316 +3882,22100,0.00015746607095934451,-1,-2,0.00015746607095934451,3.4800000190734863 +3883,67000,4.1194030927726999e-05,-1,-2,4.1194030927726999e-05,2.7599999904632568 +3884,83700,1.7323776773991995e-05,-1,-2,1.7323776773991995e-05,1.4500000476837158 +3885,15900,0.00015345912834163755,-1,-2,0.00015345912834163755,2.440000057220459 +3886,0,inf,-1,-2,inf,3.9900000095367432 +3887,14800,0.00027635134756565094,-1,-2,0.00027635134756565094,4.0900001525878906 +3888,41500,0.0001168674643849954,-1,-2,0.0001168674643849954,4.8499999046325684 +3889,75000,5.7066670706262812e-05,-1,-2,5.7066670706262812e-05,4.2800002098083496 +3890,69540,6.2697727116756141e-05,-1,-2,6.2697727116756141e-05,4.3600001335144043 +3891,21540,0.0001350974926026538,-1,-2,0.0001350974926026538,2.9100000858306885 +3892,21700,9.3087553977966309e-05,-1,-2,9.3087553977966309e-05,2.0199999809265137 +3893,22000,0.00012318181688897312,-1,-2,0.00012318181688897312,2.7100000381469727 +3894,18000,0.00026111109764315188,-1,-2,0.00026111109764315188,4.6999998092651367 +3895,0,inf,-1,-2,inf,4.4200000762939453 +3896,0,inf,-1,-2,inf,3.9700000286102295 +3897,0,inf,-1,-2,inf,4.8499999046325684 +3898,101500,4.5024633436696604e-05,-1,-2,4.5024633436696604e-05,4.570000171661377 +3899,0,inf,-1,-2,inf,5.2899999618530273 +3900,46330,7.2091512265615165e-05,-1,-2,7.2091512265615165e-05,3.3399999141693115 +3901,30,0.1106666624546051,-1,-2,0.1106666624546051,3.3199999332427979 +3902,18000,0.00027222224161960185,-1,-2,0.00027222224161960185,4.9000000953674316 +3903,14500,0.00035862068762071431,-1,-2,0.00035862068762071431,5.1999998092651367 +3904,6000,0.00077999994391575456,-1,-2,0.00077999994391575456,4.679999828338623 +3905,0,inf,-1,-2,inf,4.2199997901916504 +3906,89900,1.8020022253040224e-05,-1,-2,1.8020022253040224e-05,1.6200000047683716 +3907,160000,2.168749961128924e-05,-1,-2,2.168749961128924e-05,3.4700000286102295 +3908,204900,1.6251829947577789e-05,-1,-2,1.6251829947577789e-05,3.3299999237060547 +3909,128690,4.3748543248511851e-05,-1,-2,4.3748543248511851e-05,5.630000114440918 +3910,142000,2.3309858079301193e-05,-1,-2,2.3309858079301193e-05,3.309999942779541 +3911,25300,0.00024782607215456665,-1,-2,0.00024782607215456665,6.2699999809265137 +3912,16400,0.00014085364819038659,-1,-2,0.00014085364819038659,2.309999942779541 +3913,0,inf,-1,-2,inf,3.75 +3914,0,inf,-1,-2,inf,2.6800000667572021 +3915,0,inf,-1,-2,inf,3.5899999141693115 +3916,0,inf,-1,-2,inf,0.75999999046325684 +3917,8400,0.00039404761628247797,-1,-2,0.00039404761628247797,3.309999942779541 +3918,8300,0.00054457830265164375,-1,-2,0.00054457830265164375,4.5199999809265137 +3919,1560,0.0025320514105260372,-1,-2,0.0025320514105260372,3.9500000476837158 +3920,44050,9.262201638193801e-05,-1,-2,9.262201638193801e-05,4.0799999237060547 +3921,158200,2.7496838811202906e-05,-1,-2,2.7496838811202906e-05,4.3499999046325684 +3922,20500,0.00021853658836334944,-1,-2,0.00021853658836334944,4.4800000190734863 +3923,7900,0.00031012657564133406,-1,-2,0.00031012657564133406,2.4500000476837158 +3924,0,inf,-1,-2,inf,4.119999885559082 +3925,50000,6.9599998823832721e-05,-1,-2,6.9599998823832721e-05,3.4800000190734863 +3926,15600,0.00018782052211463451,-1,-2,0.00018782052211463451,2.9300000667572021 +3927,34630,0.00010482241486897692,-1,-2,0.00010482241486897692,3.630000114440918 +3928,66270,7.6203410571906716e-05,-1,-2,7.6203410571906716e-05,5.0500001907348633 +3929,115000,2.5826087949099019e-05,-1,-2,2.5826087949099019e-05,2.9700000286102295 +3930,10700,0.00048691590200178325,-1,-2,0.00048691590200178325,5.2100000381469727 +3931,23000,8.6956519226077944e-05,-1,-2,8.6956519226077944e-05,2 +3932,163000,2.2699387045577168e-05,-1,-2,2.2699387045577168e-05,3.7000000476837158 +3933,37750,0.00011682118929456919,-1,-2,0.00011682118929456919,4.4099998474121094 +3934,31400,0.00010445859516039491,-1,-2,0.00010445859516039491,3.2799999713897705 +3935,0,inf,-1,-2,inf,4.380000114440918 +3936,21700,0.0001539170480100438,-1,-2,0.0001539170480100438,3.3399999141693115 +3937,25000,0.00011039999662898481,-1,-2,0.00011039999662898481,2.7599999904632568 +3938,17720,0.00016760722792241722,-1,-2,0.00016760722792241722,2.9700000286102295 +3939,0,inf,-1,-2,inf,4.4200000762939453 +3940,58260,5.2694816986331716e-05,-1,-2,5.2694816986331716e-05,3.0699999332427979 +3941,0,inf,-1,-2,inf,3.1600000858306885 +3942,8200,0.00049756094813346863,-1,-2,0.00049756094813346863,4.0799999237060547 +3943,62000,7.3709677963051945e-05,-1,-2,7.3709677963051945e-05,4.570000171661377 +3944,13600,0.00027720589423552155,-1,-2,0.00027720589423552155,3.7699999809265137 +3945,18000,0.00027499999850988388,-1,-2,0.00027499999850988388,4.9499998092651367 +3946,9000,0.00034666666761040688,-1,-2,0.00034666666761040688,3.119999885559082 +3947,28000,0.00011214285768801346,-1,-2,0.00011214285768801346,3.1400001049041748 +3948,10100,0.00066237623104825616,-1,-2,0.00066237623104825616,6.690000057220459 +3949,22000,0.00015181818162091076,-1,-2,0.00015181818162091076,3.3399999141693115 +3950,12000,0.00018666667165234685,-1,-2,0.00018666667165234685,2.2400000095367432 +3951,26620,0.00014838467177469283,-1,-2,0.00014838467177469283,3.9500000476837158 +3952,103370,4.2952502553816885e-05,-1,-2,4.2952502553816885e-05,4.440000057220459 +3953,18700,0.00017754010332282633,-1,-2,0.00017754010332282633,3.3199999332427979 +3954,27650,0.00021084990294184536,-1,-2,0.00021084990294184536,5.8299999237060547 +3955,14400,0.00028194443439133465,-1,-2,0.00028194443439133465,4.059999942779541 +3956,10200,0.0003499999875202775,-1,-2,0.0003499999875202775,3.5699999332427979 +3957,27000,0.00018740740779321641,-1,-2,0.00018740740779321641,5.059999942779541 +3958,24900,0.00012329316814430058,-1,-2,0.00012329316814430058,3.0699999332427979 +3959,9500,0.00014000000373926014,-1,-2,0.00014000000373926014,1.3300000429153442 +3960,40000,0.00011050000466639176,-1,-2,0.00011050000466639176,4.4200000762939453 +3961,0,inf,-1,-2,inf,5.0199999809265137 +3962,37710,0.0001172102929558605,-1,-2,0.0001172102929558605,4.4200000762939453 +3963,7000,9.2857138952240348e-05,-1,-2,9.2857138952240348e-05,0.64999997615814209 +3964,37700,8.8063658040482551e-05,-1,-2,8.8063658040482551e-05,3.3199999332427979 +3965,11030,0.00053490482969209552,-1,-2,0.00053490482969209552,5.9000000953674316 +3966,47000,4.7659574192948639e-05,-1,-2,4.7659574192948639e-05,2.2400000095367432 +3967,29500,9.3898306658957154e-05,-1,-2,9.3898306658957154e-05,2.7699999809265137 +3968,302000,9.2052978288847953e-06,-1,-2,9.2052978288847953e-06,2.7799999713897705 +3969,0,inf,-1,-2,inf,4.9499998092651367 +3970,64200,3.3644861105130985e-05,-1,-2,3.3644861105130985e-05,2.1600000858306885 +3971,139230,2.4060906071099453e-05,-1,-2,2.4060906071099453e-05,3.3499999046325684 +3972,8700,0.00031839081202633679,-1,-2,0.00031839081202633679,2.7699999809265137 +3973,0,inf,-1,-2,inf,0.77999997138977051 +3974,9900,0.00026262624305672944,-1,-2,0.00026262624305672944,2.5999999046325684 +3975,23400,6.6666667407844216e-05,-1,-2,6.6666667407844216e-05,1.559999942779541 +3976,18200,0.00027747254353016615,-1,-2,0.00027747254353016615,5.0500001907348633 +3977,48800,0.00010512295557418838,-1,-2,0.00010512295557418838,5.130000114440918 +3978,0,inf,-1,-2,inf,4 +3979,8400,0.00031547620892524719,-1,-2,0.00031547620892524719,2.6500000953674316 +3980,0,inf,-1,-2,inf,0.79000002145767212 +3981,72000,5.6527780543547124e-05,-1,-2,5.6527780543547124e-05,4.070000171661377 +3982,0,inf,-1,-2,inf,4.8299999237060547 +3983,104700,3.3333333703922108e-05,-1,-2,3.3333333703922108e-05,3.4900000095367432 +3984,18800,2.4999999368446879e-05,-1,-2,2.4999999368446879e-05,0.4699999988079071 +3985,13900,0.00011007193825207651,-1,-2,0.00011007193825207651,1.5299999713897705 +3986,130000,2.6384615921415389e-05,-1,-2,2.6384615921415389e-05,3.4300000667572021 +3987,1100,0.0026545454747974873,-1,-2,0.0026545454747974873,2.9200000762939453 +3988,560,0.0043571428395807743,-1,-2,0.0043571428395807743,2.440000057220459 +3989,26600,6.3157895056065172e-05,-1,-2,6.3157895056065172e-05,1.6799999475479126 +3990,36900,0.00016910568228922784,-1,-2,0.00016910568228922784,6.2399997711181641 +3991,65600,3.6432928027352318e-05,-1,-2,3.6432928027352318e-05,2.3900001049041748 +3992,92700,2.3516720830230042e-05,-1,-2,2.3516720830230042e-05,2.1800000667572021 +3993,12000,0.00013333333481568843,-1,-2,0.00013333333481568843,1.6000000238418579 +3994,77970,2.8985507015022449e-05,-1,-2,2.8985507015022449e-05,2.2599999904632568 +3995,41800,1.2918661013827659e-05,-1,-2,1.2918661013827659e-05,0.54000002145767212 +3996,21000,0.00015333334158640355,-1,-2,0.00015333334158640355,3.2200000286102295 +3997,0,inf,-1,-2,inf,4.5199999809265137 +3998,15200,0.00033223684295080602,-1,-2,0.00033223684295080602,5.0500001907348633 +3999,18700,0.00021390373876783997,-1,-2,0.00021390373876783997,4 +4000,34400,8.139534475049004e-05,-1,-2,8.139534475049004e-05,2.7999999523162842 +4001,15100,0.00029867549892514944,-1,-2,0.00029867549892514944,4.5100002288818359 +4002,8700,0.00055172416614368558,-1,-2,0.00055172416614368558,4.8000001907348633 +4003,9200,0.00044347826042212546,-1,-2,0.00044347826042212546,4.0799999237060547 +4004,85800,3.6596738937078044e-05,-1,-2,3.6596738937078044e-05,3.1400001049041748 +4005,19600,0.00014438775542657822,-1,-2,0.00014438775542657822,2.8299999237060547 +4006,0,inf,-1,-2,inf,3.4200000762939453 +4007,0,inf,-1,-2,inf,2.5 +4008,0,inf,-1,-2,inf,1.8700000047683716 +4009,0,inf,-1,-2,inf,4.0100002288818359 +4010,7900,0.00030379748204723001,-1,-2,0.00030379748204723001,2.4000000953674316 +4011,8000,0.00094499997794628143,-1,-2,0.00094499997794628143,7.559999942779541 +4012,8400,0.0006750000175088644,-1,-2,0.0006750000175088644,5.6700000762939453 +4013,130000,1.146153863373911e-05,-1,-2,1.146153863373911e-05,1.4900000095367432 +4014,0,inf,-1,-2,inf,0.38999998569488525 +4015,97200,3.8786009099567309e-05,-1,-2,3.8786009099567309e-05,3.7699999809265137 +4016,700,0.0029571426566690207,-1,-2,0.0029571426566690207,2.0699999332427979 +4017,0,inf,-1,-2,inf,3.869999885559082 +4018,8300,0.00043614456080831587,-1,-2,0.00043614456080831587,3.619999885559082 +4019,11500,0.00031999999191612005,-1,-2,0.00031999999191612005,3.6800000667572021 +4020,0,inf,-1,-2,inf,2.7699999809265137 +4021,0,inf,-1,-2,inf,3.5899999141693115 +4022,0,inf,-1,-2,inf,4 +4023,12400,0.0001290322543354705,-1,-2,0.0001290322543354705,1.6000000238418579 +4024,50400,3.2936506613623351e-05,-1,-2,3.2936506613623351e-05,1.6599999666213989 +4025,206800,1.8278529751114547e-05,-1,-2,1.8278529751114547e-05,3.7799999713897705 +4026,8800,0.00020340908668003976,-1,-2,0.00020340908668003976,1.7899999618530273 +4027,37910,0.00010735954128904268,-1,-2,0.00010735954128904268,4.070000171661377 +4028,59000,2.7627118470263667e-05,-1,-2,2.7627118470263667e-05,1.6299999952316284 +4029,43100,5.6612530897837132e-05,-1,-2,5.6612530897837132e-05,2.440000057220459 +4030,14000,0.00028357142582535744,-1,-2,0.00028357142582535744,3.9700000286102295 +4031,24150,4.5962733565829694e-05,-1,-2,4.5962733565829694e-05,1.1100000143051147 +4032,0,inf,-1,-2,inf,3.5899999141693115 +4033,174500,1.9541546862456016e-05,-1,-2,1.9541546862456016e-05,3.4100000858306885 +4034,0,inf,-1,-2,inf,3.5899999141693115 +4035,16800,9.8214281024411321e-05,-1,-2,9.8214281024411321e-05,1.6499999761581421 +4036,83000,4.3975906010018662e-05,-1,-2,4.3975906010018662e-05,3.6500000953674316 +4037,60000,8.6666659626644105e-06,-1,-2,8.6666659626644105e-06,0.51999998092651367 +4038,18800,0.00014680851018056273,-1,-2,0.00014680851018056273,2.7599999904632568 +4039,114000,3.956140426453203e-05,-1,-2,3.956140426453203e-05,4.5100002288818359 +4040,4890,0.00071779143763706088,-1,-2,0.00071779143763706088,3.5099999904632568 +4041,0,inf,-1,-2,inf,4.820000171661377 +4042,101000,2.9108910894137807e-05,-1,-2,2.9108910894137807e-05,2.940000057220459 +4043,84400,3.5781991755357012e-05,-1,-2,3.5781991755357012e-05,3.0199999809265137 +4044,141200,2.4999999368446879e-05,-1,-2,2.4999999368446879e-05,3.5299999713897705 +4045,0,inf,-1,-2,inf,5.619999885559082 +4046,560,0.0072857141494750977,-1,-2,0.0072857141494750977,4.0799999237060547 +4047,17050,0.00020997067622374743,-1,-2,0.00020997067622374743,3.5799999237060547 +4048,25600,9.3750000814907253e-05,-1,-2,9.3750000814907253e-05,2.4000000953674316 +4049,42000,6.4523810578975827e-05,-1,-2,6.4523810578975827e-05,2.7100000381469727 +4050,74000,4.5675678848056123e-05,-1,-2,4.5675678848056123e-05,3.380000114440918 +4051,10900,0.0002880734100472182,-1,-2,0.0002880734100472182,3.1400001049041748 +4052,0,inf,-1,-2,inf,4.0100002288818359 +4053,8500,0.00055764702847227454,-1,-2,0.00055764702847227454,4.7399997711181641 +4054,72800,4.285714021534659e-05,-1,-2,4.285714021534659e-05,3.119999885559082 +4055,16000,0.00033437498495914042,-1,-2,0.00033437498495914042,5.3499999046325684 +4056,185450,1.3103262972435914e-05,-1,-2,1.3103262972435914e-05,2.4300000667572021 +4057,0,inf,-1,-2,inf,3.9700000286102295 +4058,22300,0.00012152466661063954,-1,-2,0.00012152466661063954,2.7100000381469727 +4059,25000,5.9199999668635428e-05,-1,-2,5.9199999668635428e-05,1.4800000190734863 +4060,5700,0.00048596490523777902,-1,-2,0.00048596490523777902,2.7699999809265137 +4061,0,inf,-1,-2,inf,2.9500000476837158 +4062,7000,0.00072285713395103812,-1,-2,0.00072285713395103812,5.059999942779541 +4063,68000,6.5000000176951289e-05,-1,-2,6.5000000176951289e-05,4.4200000762939453 +4064,0,inf,-1,-2,inf,4.5999999046325684 +4065,0,inf,-1,-2,inf,5.7800002098083496 +4066,7200,0.00045972221414558589,-1,-2,0.00045972221414558589,3.309999942779541 +4067,0,inf,-1,-2,inf,1.809999942779541 +4068,22890,0.00011839231592603028,-1,-2,0.00011839231592603028,2.7100000381469727 +4069,8700,0.00050689652562141418,-1,-2,0.00050689652562141418,4.4099998474121094 +4070,58000,5.2241379307815805e-05,-1,-2,5.2241379307815805e-05,3.0299999713897705 +4071,0,inf,-1,-2,inf,0.69999998807907104 +4072,18000,0.00014444443513639271,-1,-2,0.00014444443513639271,2.5999999046325684 +4073,8000,0.00074500002665445209,-1,-2,0.00074500002665445209,5.9600000381469727 +4074,18000,0.00032333334092982113,-1,-2,0.00032333334092982113,5.820000171661377 +4075,0,inf,-1,-2,inf,3.5199999809265137 +4076,30100,0.00010996677883667871,-1,-2,0.00010996677883667871,3.309999942779541 +4077,33450,0.00013423018390312791,-1,-2,0.00013423018390312791,4.4899997711181641 +4078,8300,9.3975897470954806e-05,-1,-2,9.3975897470954806e-05,0.77999997138977051 +4079,16000,0.00030874999356456101,-1,-2,0.00030874999356456101,4.940000057220459 +4080,25600,0.0001687500043772161,-1,-2,0.0001687500043772161,4.320000171661377 +4081,80400,2.6119401809410192e-05,-1,-2,2.6119401809410192e-05,2.0999999046325684 +4082,8700,0.00021724138059653342,-1,-2,0.00021724138059653342,1.8899999856948853 +4083,79000,2.3924050765344873e-05,-1,-2,2.3924050765344873e-05,1.8899999856948853 +4084,325014,7.7535123637062497e-06,-1,-2,7.7535123637062497e-06,2.5199999809265137 +4085,0,inf,-1,-2,inf,4.5 +4086,137000,3.1167881388682872e-05,-1,-2,3.1167881388682872e-05,4.2699999809265137 +4087,11000,0.00040181819349527359,-1,-2,0.00040181819349527359,4.4200000762939453 +4088,0,inf,-1,-2,inf,3.6800000667572021 +4089,64300,7.1073096478357911e-05,-1,-2,7.1073096478357911e-05,4.570000171661377 +4090,7500,0.00039999998989515007,-1,-2,0.00039999998989515007,3 +4091,87600,2.260274050058797e-05,-1,-2,2.260274050058797e-05,1.9800000190734863 +4092,106120,6.125141226220876e-06,-1,-2,6.125141226220876e-06,0.64999997615814209 +4093,0,inf,-1,-2,inf,2.6600000858306885 +4094,24000,0.00011874999472638592,-1,-2,0.00011874999472638592,2.8499999046325684 +4095,16800,6.6071428591385484e-05,-1,-2,6.6071428591385484e-05,1.1100000143051147 +4096,0,inf,-1,-2,inf,1.0399999618530273 +4097,84000,2.4404760551988147e-05,-1,-2,2.4404760551988147e-05,2.0499999523162842 +4098,0,inf,-1,-2,inf,2.6800000667572021 +4099,35300,7.3937677370849997e-05,-1,-2,7.3937677370849997e-05,2.6099998950958252 +4100,55500,7.9279279816546477e-06,-1,-2,7.9279279816546477e-06,0.43999999761581421 +4101,70000,7.9142853792291135e-05,-1,-2,7.9142853792291135e-05,5.5399999618530273 +4102,11500,0.0001217391254613176,-1,-2,0.0001217391254613176,1.3999999761581421 +4103,112500,2.8088888939237222e-05,-1,-2,2.8088888939237222e-05,3.1600000858306885 +4104,45000,6.7777778895106167e-05,-1,-2,6.7777778895106167e-05,3.0499999523162842 +4105,0,inf,-1,-2,inf,3.059999942779541 +4106,0,inf,-1,-2,inf,2.6700000762939453 +4107,25000,0.00026239998987875879,-1,-2,0.00026239998987875879,6.559999942779541 +4108,290000,7.3448281909804791e-06,-1,-2,7.3448281909804791e-06,2.130000114440918 +4109,8400,0.00031071426928974688,-1,-2,0.00031071426928974688,2.6099998950958252 +4110,144100,2.3455933842342347e-05,-1,-2,2.3455933842342347e-05,3.380000114440918 +4111,0,inf,-1,-2,inf,2.7100000381469727 +4112,21200,9.1981135483365506e-05,-1,-2,9.1981135483365506e-05,1.9500000476837158 +4113,0,inf,-1,-2,inf,4.5300002098083496 +4114,52800,5.3030300477985293e-05,-1,-2,5.3030300477985293e-05,2.7999999523162842 +4115,46400,3.9655173168284819e-05,-1,-2,3.9655173168284819e-05,1.8400000333786011 +4116,0,inf,-1,-2,inf,3.119999885559082 +4117,42900,6.1072256357874721e-05,-1,-2,6.1072256357874721e-05,2.619999885559082 +4118,41500,7.9759032814763486e-05,-1,-2,7.9759032814763486e-05,3.309999942779541 +4119,7200,0.00047500000800937414,-1,-2,0.00047500000800937414,3.4200000762939453 +4120,45000,0.00011511110642459244,-1,-2,0.00011511110642459244,5.179999828338623 +4121,127900,3.3541829907335341e-05,-1,-2,3.3541829907335341e-05,4.2899999618530273 +4122,8200,0.00031829267391003668,-1,-2,0.00031829267391003668,2.6099998950958252 +4123,161300,2.7898324788111495e-06,-1,-2,2.7898324788111495e-06,0.44999998807907104 +4124,161300,2.5976441975217313e-05,-1,-2,2.5976441975217313e-05,4.190000057220459 +4125,17600,0.00013352272799238563,-1,-2,0.00013352272799238563,2.3499999046325684 +4126,56100,3.1372550438391045e-05,-1,-2,3.1372550438391045e-05,1.7599999904632568 +4127,39000,4.9743590352591127e-05,-1,-2,4.9743590352591127e-05,1.940000057220459 +4128,133000,2.0751878764713183e-05,-1,-2,2.0751878764713183e-05,2.7599999904632568 +4129,13500,9.9259261332917958e-05,-1,-2,9.9259261332917958e-05,1.3400000333786011 +4130,29300,0.00019215016800444573,-1,-2,0.00019215016800444573,5.630000114440918 +4131,0,inf,-1,-2,inf,4.1999998092651367 +4132,0,inf,-1,-2,inf,3.2000000476837158 +4133,57600,8.3159720816183835e-05,-1,-2,8.3159720816183835e-05,4.7899999618530273 +4134,74000,5.0540540541987866e-05,-1,-2,5.0540540541987866e-05,3.7400000095367432 +4135,52000,9.7692303825169802e-05,-1,-2,9.7692303825169802e-05,5.0799999237060547 +4136,15000,0.00030466666794382036,-1,-2,0.00030466666794382036,4.570000171661377 +4137,37900,2.0580473574227653e-05,-1,-2,2.0580473574227653e-05,0.77999997138977051 +4138,14300,0.00034545455127954483,-1,-2,0.00034545455127954483,4.940000057220459 +4139,0,inf,-1,-2,inf,3.559999942779541 +4140,70900,4.2313116864534095e-05,-1,-2,4.2313116864534095e-05,3 +4141,115700,4.1659466660348698e-05,-1,-2,4.1659466660348698e-05,4.820000171661377 +4142,29704,7.3390794568695128e-05,-1,-2,7.3390794568695128e-05,2.1800000667572021 +4143,8400,0.00032142858253791928,-1,-2,0.00032142858253791928,2.7000000476837158 +4144,7000,0.00039428571471944451,-1,-2,0.00039428571471944451,2.7599999904632568 +4145,77970,3.4885211789514869e-05,-1,-2,3.4885211789514869e-05,2.7200000286102295 +4146,8300,0.00042771082371473312,-1,-2,0.00042771082371473312,3.5499999523162842 +4147,11500,0.00027217392926104367,-1,-2,0.00027217392926104367,3.130000114440918 +4148,62530,9.9952019809279591e-05,-1,-2,9.9952019809279591e-05,6.25 +4149,112000,9.4642855401616544e-06,-1,-2,9.4642855401616544e-06,1.059999942779541 +4150,10000,0.00055799999972805381,-1,-2,0.00055799999972805381,5.5799999237060547 +4151,35400,8.1073441833723336e-05,-1,-2,8.1073441833723336e-05,2.869999885559082 +4152,224000,2.2187499780557118e-05,-1,-2,2.2187499780557118e-05,4.9699997901916504 +4153,24600,0.00018292682943865657,-1,-2,0.00018292682943865657,4.5 +4154,110000,3.5090906749246642e-05,-1,-2,3.5090906749246642e-05,3.8599998950958252 +4155,35500,4.0845072362571955e-05,-1,-2,4.0845072362571955e-05,1.4500000476837158 +4156,0,inf,-1,-2,inf,3.5399999618530273 +4157,8600,0.00051744183292612433,-1,-2,0.00051744183292612433,4.4499998092651367 +4158,25400,0.00018149607058148831,-1,-2,0.00018149607058148831,4.6100001335144043 +4159,0,inf,-1,-2,inf,3.119999885559082 +4160,65000,3.0923078156774864e-05,-1,-2,3.0923078156774864e-05,2.0099999904632568 +4161,140000,4.3000000005122274e-05,-1,-2,4.3000000005122274e-05,6.0199999809265137 +4162,21000,0.00027904761373065412,-1,-2,0.00027904761373065412,5.8600001335144043 +4163,8200,4.0243903640657663e-05,-1,-2,4.0243903640657663e-05,0.33000001311302185 +4164,0,inf,-1,-2,inf,3.6800000667572021 +4165,9100,0.00017802197544369847,-1,-2,0.00017802197544369847,1.6200000047683716 +4166,30040,9.0213048679288477e-05,-1,-2,9.0213048679288477e-05,2.7100000381469727 +4167,163000,1.2331288417044561e-05,-1,-2,1.2331288417044561e-05,2.0099999904632568 +4168,16800,8.6904765339568257e-05,-1,-2,8.6904765339568257e-05,1.4600000381469727 +4169,25000,0.00014399999054148793,-1,-2,0.00014399999054148793,3.5999999046325684 +4170,6000,0.00036000000545755029,-1,-2,0.00036000000545755029,2.1600000858306885 +4171,69400,4.6397693949984387e-05,-1,-2,4.6397693949984387e-05,3.2200000286102295 +4172,0,inf,-1,-2,inf,3.1600000858306885 +4173,51480,0.00010936285980278626,-1,-2,0.00010936285980278626,5.630000114440918 +4174,20000,3.35000004270114e-05,-1,-2,3.35000004270114e-05,0.67000001668930054 +4175,3000,0.0018599999602884054,-1,-2,0.0018599999602884054,5.5799999237060547 +4176,251000,7.4501990638964344e-06,-1,-2,7.4501990638964344e-06,1.8700000047683716 +4177,12000,0.00031500001205131412,-1,-2,0.00031500001205131412,3.7799999713897705 +4178,8100,0.00049753091298043728,-1,-2,0.00049753091298043728,4.0300002098083496 +4179,0,inf,-1,-2,inf,2.7599999904632568 +4180,26050,0.00014664107584394515,-1,-2,0.00014664107584394515,3.8199999332427979 +4181,0,inf,-1,-2,inf,1.059999942779541 +4182,8300,0.00035783133353106678,-1,-2,0.00035783133353106678,2.9700000286102295 +4183,4860,0.001010288018733263,-1,-2,0.001010288018733263,4.9099998474121094 +4184,21800,0.00020871560263913125,-1,-2,0.00020871560263913125,4.5500001907348633 +4185,46200,6.6017317294608802e-05,-1,-2,6.6017317294608802e-05,3.0499999523162842 +4186,14700,0.00013809523079544306,-1,-2,0.00013809523079544306,2.0299999713897705 +4187,63000,5.2539682656060904e-05,-1,-2,5.2539682656060904e-05,3.309999942779541 +4188,0,inf,-1,-2,inf,3.1700000762939453 +4189,80600,9.4416878710035235e-05,-1,-2,9.4416878710035235e-05,7.6100001335144043 +4190,24000,8.2083337474614382e-05,-1,-2,8.2083337474614382e-05,1.9700000286102295 +4191,9000,0.00037666669231839478,-1,-2,0.00037666669231839478,3.3900001049041748 +4192,26240,0.00019283535948488861,-1,-2,0.00019283535948488861,5.059999942779541 +4193,310000,1.00967745311209e-05,-1,-2,1.00967745311209e-05,3.130000114440918 +4194,33000,5.1818184147123247e-05,-1,-2,5.1818184147123247e-05,1.7100000381469727 +4195,60000,1.316666657658061e-05,-1,-2,1.316666657658061e-05,0.79000002145767212 +4196,37900,7.5461735832504928e-05,-1,-2,7.5461735832504928e-05,2.8599998950958252 +4197,15110,0.00029715418349951506,-1,-2,0.00029715418349951506,4.4899997711181641 +4198,28000,0.00020535713701974601,-1,-2,0.00020535713701974601,5.75 +4199,8700,0.00029999998514540493,-1,-2,0.00029999998514540493,2.6099998950958252 +4200,68000,2.3823529772926122e-05,-1,-2,2.3823529772926122e-05,1.6200000047683716 +4201,76150,3.9264610677491874e-05,-1,-2,3.9264610677491874e-05,2.9900000095367432 +4202,62500,2.6399999114801176e-05,-1,-2,2.6399999114801176e-05,1.6499999761581421 +4203,37900,6.1741418903693557e-05,-1,-2,6.1741418903693557e-05,2.3399999141693115 +4204,270000,1.7148147890111431e-05,-1,-2,1.7148147890111431e-05,4.630000114440918 +4205,351000,9.0313396867713891e-06,-1,-2,9.0313396867713891e-06,3.1700000762939453 +4206,125000,4.9599998419580515e-06,-1,-2,4.9599998419580515e-06,0.62000000476837158 +4207,107210,4.943569001625292e-05,-1,-2,4.943569001625292e-05,5.3000001907348633 +4208,9500,0.00040631578303873539,-1,-2,0.00040631578303873539,3.8599998950958252 +4209,137000,2.5766423277673312e-05,-1,-2,2.5766423277673312e-05,3.5299999713897705 +4210,8700,0.00027011492056772113,-1,-2,0.00027011492056772113,2.3499999046325684 +4211,35000,0.0001491428556619212,-1,-2,0.0001491428556619212,5.2199997901916504 +4212,41200,4.7815534344408661e-05,-1,-2,4.7815534344408661e-05,1.9700000286102295 +4213,137000,3.1313869840232655e-05,-1,-2,3.1313869840232655e-05,4.2899999618530273 +4214,8000,0.00051124999299645424,-1,-2,0.00051124999299645424,4.0900001525878906 +4215,184900,2.3255813630385092e-06,-1,-2,2.3255813630385092e-06,0.43000000715255737 +4216,162000,1.8271604858455248e-05,-1,-2,1.8271604858455248e-05,2.9600000381469727 +4217,17000,0.00025823528994806111,-1,-2,0.00025823528994806111,4.3899998664855957 +4218,0,inf,-1,-2,inf,3.75 +4219,52000,6.3846149714663625e-05,-1,-2,6.3846149714663625e-05,3.3199999332427979 +4220,29500,8.8135588157456368e-05,-1,-2,8.8135588157456368e-05,2.5999999046325684 +4221,74980,3.0141371098579839e-05,-1,-2,3.0141371098579839e-05,2.2599999904632568 +4222,0,inf,-1,-2,inf,3.119999885559082 +4223,69200,7.7167635026853532e-05,-1,-2,7.7167635026853532e-05,5.3400001525878906 +4224,69200,1.8786126020131633e-05,-1,-2,1.8786126020131633e-05,1.2999999523162842 +4225,64200,6.5887848904822022e-05,-1,-2,6.5887848904822022e-05,4.2300000190734863 +4226,8300,0.00020240963203832507,-1,-2,0.00020240963203832507,1.6799999475479126 +4227,30900,1.715210237307474e-05,-1,-2,1.715210237307474e-05,0.52999997138977051 +4228,8800,0.00038522729300893843,-1,-2,0.00038522729300893843,3.3900001049041748 +4229,74100,4.9122809286927804e-05,-1,-2,4.9122809286927804e-05,3.6400001049041748 +4230,0,inf,-1,-2,inf,4.820000171661377 +4231,133000,2.8571428629220463e-05,-1,-2,2.8571428629220463e-05,3.7999999523162842 +4232,42500,9.505882189841941e-05,-1,-2,9.505882189841941e-05,4.0399999618530273 +4233,197000,1.0304568604624365e-05,-1,-2,1.0304568604624365e-05,2.0299999713897705 +4234,335000,1.0179104720009491e-05,-1,-2,1.0179104720009491e-05,3.4100000858306885 +4235,80000,4.5625001803273335e-05,-1,-2,4.5625001803273335e-05,3.6500000953674316 +4236,75000,7.5333337008487433e-05,-1,-2,7.5333337008487433e-05,5.6500000953674316 +4237,22890,0.00019266054732725024,-1,-2,0.00019266054732725024,4.4099998474121094 +4238,42000,7.1190479502547532e-05,-1,-2,7.1190479502547532e-05,2.9900000095367432 +4239,163000,4.7852759053057525e-06,-1,-2,4.7852759053057525e-06,0.77999997138977051 +4240,146220,2.1884830857743509e-05,-1,-2,2.1884830857743509e-05,3.2000000476837158 +4241,97000,2.8556700272019953e-05,-1,-2,2.8556700272019953e-05,2.7699999809265137 +4242,8100,0.00033456791425123811,-1,-2,0.00033456791425123811,2.7100000381469727 +4243,19300,0.00017512953490950167,-1,-2,0.00017512953490950167,3.380000114440918 +4244,45600,1.1842105777759571e-05,-1,-2,1.1842105777759571e-05,0.54000002145767212 +4245,8500,0.000350588234141469,-1,-2,0.000350588234141469,2.9800000190734863 +4246,435000,7.057471066218568e-06,-1,-2,7.057471066218568e-06,3.0699999332427979 +4247,15000,0.00027266668621450663,-1,-2,0.00027266668621450663,4.0900001525878906 +4248,40000,0.00014474999625235796,-1,-2,0.00014474999625235796,5.7899999618530273 +4249,18000,0.00012444444291759282,-1,-2,0.00012444444291759282,2.2400000095367432 +4250,10300,0.00013106796541251242,-1,-2,0.00013106796541251242,1.3500000238418579 +4251,11400,0.00031578945345245302,-1,-2,0.00031578945345245302,3.5999999046325684 +4252,46400,3.6853449273621663e-05,-1,-2,3.6853449273621663e-05,1.7100000381469727 +4253,14500,0.00016206895816139877,-1,-2,0.00016206895816139877,2.3499999046325684 +4254,34400,0.00012761628022417426,-1,-2,0.00012761628022417426,4.3899998664855957 +4255,101000,2.6237625206704251e-05,-1,-2,2.6237625206704251e-05,2.6500000953674316 +4256,49300,3.4685599530348554e-05,-1,-2,3.4685599530348554e-05,1.7100000381469727 +4257,8300,0.00031445780768990517,-1,-2,0.00031445780768990517,2.6099998950958252 +4258,19200,0.00025781249860301614,-1,-2,0.00025781249860301614,4.9499998092651367 +4259,215000,1.4976744751038495e-05,-1,-2,1.4976744751038495e-05,3.2200000286102295 +4260,18000,0.00022222222469281405,-1,-2,0.00022222222469281405,4 +4261,325000,1.17846147986711e-05,-1,-2,1.17846147986711e-05,3.8299999237060547 +4262,21800,0.0001266055041924119,-1,-2,0.0001266055041924119,2.7599999904632568 +4263,0,inf,-1,-2,inf,2.940000057220459 +4264,54000,3.5555553040467203e-05,-1,-2,3.5555553040467203e-05,1.9199999570846558 +4265,40000,9.349999891128391e-05,-1,-2,9.349999891128391e-05,3.7400000095367432 +4266,103370,3.4632870665518567e-05,-1,-2,3.4632870665518567e-05,3.5799999237060547 +4267,68000,9.2058828158769757e-05,-1,-2,9.2058828158769757e-05,6.2600002288818359 +4268,25000,5.32000012753997e-05,-1,-2,5.32000012753997e-05,1.3300000429153442 +4269,52000,5.7884615671355277e-05,-1,-2,5.7884615671355277e-05,3.0099999904632568 +4270,18100,0.00027016573585569859,-1,-2,0.00027016573585569859,4.8899998664855957 +4271,101400,3.6982248275307938e-05,-1,-2,3.6982248275307938e-05,3.75 +4272,0,inf,-1,-2,inf,4.0799999237060547 +4273,56000,0.00010553571337368339,-1,-2,0.00010553571337368339,5.9099998474121094 +4274,32000,0.00010562500392552465,-1,-2,0.00010562500392552465,3.380000114440918 +4275,8200,0.00015853658260311931,-1,-2,0.00015853658260311931,1.2999999523162842 +4276,62500,5.9840000176336616e-05,-1,-2,5.9840000176336616e-05,3.7400000095367432 +4277,0,inf,-1,-2,inf,2.6700000762939453 +4278,56500,7.8053097240626812e-05,-1,-2,7.8053097240626812e-05,4.4099998474121094 +4279,22000,0.00029727272340096533,-1,-2,0.00029727272340096533,6.5399999618530273 +4280,48000,5.5625001550652087e-05,-1,-2,5.5625001550652087e-05,2.6700000762939453 +4281,44000,0.00017295454745180905,-1,-2,0.00017295454745180905,7.6100001335144043 +4282,0,inf,-1,-2,inf,1.8700000047683716 +4283,0,inf,-1,-2,inf,2.0099999904632568 +4284,16000,0.00023562500427942723,-1,-2,0.00023562500427942723,3.7699999809265137 +4285,200000,9.5499999588355422e-06,-1,-2,9.5499999588355422e-06,1.9099999666213989 +4286,10200,0.00035784314968623221,-1,-2,0.00035784314968623221,3.6500000953674316 +4287,17850,0.00017142857541330159,-1,-2,0.00017142857541330159,3.059999942779541 +4288,8200,0.00023048779985401779,-1,-2,0.00023048779985401779,1.8899999856948853 +4289,15900,0.00013522013614419848,-1,-2,0.00013522013614419848,2.1500000953674316 +4290,30000,7.0666661486029625e-05,-1,-2,7.0666661486029625e-05,2.119999885559082 +4291,11700,0.00023418803175445646,-1,-2,0.00023418803175445646,2.7400000095367432 +4292,206800,1.6537718693143688e-05,-1,-2,1.6537718693143688e-05,3.4200000762939453 +4293,144100,2.7827898520627059e-05,-1,-2,2.7827898520627059e-05,4.0100002288818359 +4294,62000,7.9032259236555547e-05,-1,-2,7.9032259236555547e-05,4.9000000953674316 +4295,58000,8.8448279711883515e-05,-1,-2,8.8448279711883515e-05,5.130000114440918 +4296,9000,0.00029777779127471149,-1,-2,0.00029777779127471149,2.6800000667572021 +4297,20200,0.0002445544523652643,-1,-2,0.0002445544523652643,4.940000057220459 +4298,7600,0.00059605267597362399,-1,-2,0.00059605267597362399,4.5300002098083496 +4299,99700,5.0752256356645375e-05,-1,-2,5.0752256356645375e-05,5.059999942779541 +4300,8100,9.6296294941566885e-05,-1,-2,9.6296294941566885e-05,0.77999997138977051 +4301,31000,0.0001583870907779783,-1,-2,0.0001583870907779783,4.9099998474121094 +4302,40000,9.3750000814907253e-05,-1,-2,9.3750000814907253e-05,3.75 +4303,30000,6.3999999838415533e-05,-1,-2,6.3999999838415533e-05,1.9199999570846558 +4304,16400,0.00015243902453221381,-1,-2,0.00015243902453221381,2.5 +4305,42700,0.00018220141646452248,-1,-2,0.00018220141646452248,7.7800002098083496 +4306,41900,0.00012362768757157028,-1,-2,0.00012362768757157028,5.179999828338623 +4307,365300,5.9676981436496135e-06,-1,-2,5.9676981436496135e-06,2.1800000667572021 +4308,29000,0.00010827586811501533,-1,-2,0.00010827586811501533,3.1400001049041748 +4309,9900,5.3535350161837414e-05,-1,-2,5.3535350161837414e-05,0.52999997138977051 +4310,10200,0.00029019606881774962,-1,-2,0.00029019606881774962,2.9600000381469727 +4311,0,inf,-1,-2,inf,4.5199999809265137 +4312,125000,2.128000051015988e-05,-1,-2,2.128000051015988e-05,2.6600000858306885 +4313,39220,0.00011065783473895863,-1,-2,0.00011065783473895863,4.3400001525878906 +4314,25910,0.00017020454106386751,-1,-2,0.00017020454106386751,4.4099998474121094 +4315,50200,7.5099604146089405e-05,-1,-2,7.5099604146089405e-05,3.7699999809265137 +4316,14600,0.00030821916880086064,-1,-2,0.00030821916880086064,4.5 +4317,14800,9.1216221335344017e-05,-1,-2,9.1216221335344017e-05,1.3500000238418579 +4318,8800,0.0005522727151401341,-1,-2,0.0005522727151401341,4.8600001335144043 +4319,29000,0.0001731034426484257,-1,-2,0.0001731034426484257,5.0199999809265137 +4320,24200,0.00018264462414663285,-1,-2,0.00018264462414663285,4.4200000762939453 +4321,127900,2.1422987629193813e-05,-1,-2,2.1422987629193813e-05,2.7400000095367432 +4322,7200,0.00042500000563450158,-1,-2,0.00042500000563450158,3.059999942779541 +4323,20000,0.00010150000161956996,-1,-2,0.00010150000161956996,2.0299999713897705 +4324,65000,7.892307621659711e-05,-1,-2,7.892307621659711e-05,5.130000114440918 +4325,209600,1.0305343494110275e-05,-1,-2,1.0305343494110275e-05,2.1600000858306885 +4326,68100,8.3553597505670041e-05,-1,-2,8.3553597505670041e-05,5.690000057220459 +4327,200000,9.8500004241941497e-06,-1,-2,9.8500004241941497e-06,1.9700000286102295 +4328,64100,3.3073320082621649e-05,-1,-2,3.3073320082621649e-05,2.119999885559082 +4329,8300,0.0006048192735761404,-1,-2,0.0006048192735761404,5.0199999809265137 +4330,8200,0.00027439024415798485,-1,-2,0.00027439024415798485,2.25 +4331,67000,5.0895523600047454e-05,-1,-2,5.0895523600047454e-05,3.4100000858306885 +4332,19000,0.00034526316449046135,-1,-2,0.00034526316449046135,6.559999942779541 +4333,0,inf,-1,-2,inf,5.690000057220459 +4334,14300,0.00046923078480176628,-1,-2,0.00046923078480176628,6.7100000381469727 +4335,141200,2.5566570911905728e-05,-1,-2,2.5566570911905728e-05,3.6099998950958252 +4336,8680,0.00021313363686203957,-1,-2,0.00021313363686203957,1.8500000238418579 +4337,0,inf,-1,-2,inf,2.3499999046325684 +4338,70300,6.5433850977569818e-05,-1,-2,6.5433850977569818e-05,4.5999999046325684 +4339,0,inf,-1,-2,inf,3.6600000858306885 +4340,70300,4.6941677283030003e-05,-1,-2,4.6941677283030003e-05,3.2999999523162842 +4341,14000,0.00017428571300115436,-1,-2,0.00017428571300115436,2.440000057220459 +4342,75000,3.6533332604449242e-05,-1,-2,3.6533332604449242e-05,2.7400000095367432 +4343,54600,3.7912086554570124e-05,-1,-2,3.7912086554570124e-05,2.0699999332427979 +4344,14800,0.00035945946001447737,-1,-2,0.00035945946001447737,5.320000171661377 +4345,18000,8.0000005254987627e-05,-1,-2,8.0000005254987627e-05,1.440000057220459 +4346,73300,2.6875852199736983e-05,-1,-2,2.6875852199736983e-05,1.9700000286102295 +4347,70920,3.6943034501746297e-05,-1,-2,3.6943034501746297e-05,2.619999885559082 +4348,9000,0.00054000003729015589,-1,-2,0.00054000003729015589,4.8600001335144043 +4349,24200,2.2314050511340611e-05,-1,-2,2.2314050511340611e-05,0.54000002145767212 +4350,8400,0.00041071430314332247,-1,-2,0.00041071430314332247,3.4500000476837158 +4351,5700,0.00094210525276139379,-1,-2,0.00094210525276139379,5.369999885559082 +4352,650000,1.5999999050109182e-06,-1,-2,1.5999999050109182e-06,1.0399999618530273 +4353,62200,5.6591637985548005e-05,-1,-2,5.6591637985548005e-05,3.5199999809265137 +4354,10180,0.00048133597010746598,-1,-2,0.00048133597010746598,4.9000000953674316 +4355,200000,1.4500000361294951e-05,-1,-2,1.4500000361294951e-05,2.9000000953674316 +4356,70000,7.9857141827233136e-05,-1,-2,7.9857141827233136e-05,5.5900001525878906 +4357,60800,6.1348684539552778e-05,-1,-2,6.1348684539552778e-05,3.7300000190734863 +4358,47000,0.00010319148714188486,-1,-2,0.00010319148714188486,4.8499999046325684 +4359,0,inf,-1,-2,inf,5.5399999618530273 +4360,0,inf,-1,-2,inf,3.5799999237060547 +4361,0,inf,-1,-2,inf,1.2999999523162842 +4362,15000,0.00021066666522528976,-1,-2,0.00021066666522528976,3.1600000858306885 +4363,32500,0.00013938461779616773,-1,-2,0.00013938461779616773,4.5300002098083496 +4364,388000,9.7680413091438822e-06,-1,-2,9.7680413091438822e-06,3.7899999618530273 +4365,0,inf,-1,-2,inf,3.2899999618530273 +4366,37900,8.7862797954585403e-05,-1,-2,8.7862797954585403e-05,3.3299999237060547 +4367,14800,0.00013175676576793194,-1,-2,0.00013175676576793194,1.9500000476837158 +4368,0,inf,-1,-2,inf,3.3599998950958252 +4369,14400,0.00019930554844904691,-1,-2,0.00019930554844904691,2.869999885559082 +4370,27400,0.00010802919859997928,-1,-2,0.00010802919859997928,2.9600000381469727 +4371,56000,7.4107141699641943e-05,-1,-2,7.4107141699641943e-05,4.1500000953674316 +4372,46600,7.1888411184772849e-05,-1,-2,7.1888411184772849e-05,3.3499999046325684 +4373,81980,2.6469871954759583e-05,-1,-2,2.6469871954759583e-05,2.1700000762939453 +4374,52100,8.2533595559652895e-05,-1,-2,8.2533595559652895e-05,4.3000001907348633 +4375,0,inf,-1,-2,inf,3.5 +4376,6580,0.00042553190723992884,-1,-2,0.00042553190723992884,2.7999999523162842 +4377,43950,4.2320818465668708e-05,-1,-2,4.2320818465668708e-05,1.8600000143051147 +4378,80600,1.7369726265314966e-05,-1,-2,1.7369726265314966e-05,1.3999999761581421 +4379,8100,0.00051851850003004074,-1,-2,0.00051851850003004074,4.1999998092651367 +4380,40000,0.00012725000851787627,-1,-2,0.00012725000851787627,5.0900001525878906 +4381,0,inf,-1,-2,inf,3.0699999332427979 +4382,113000,3.1681414839113131e-05,-1,-2,3.1681414839113131e-05,3.5799999237060547 +4383,123000,3.5121953260386363e-05,-1,-2,3.5121953260386363e-05,4.320000171661377 +4384,12000,0.00018000000272877514,-1,-2,0.00018000000272877514,2.1600000858306885 +4385,23100,0.00022987012926023453,-1,-2,0.00022987012926023453,5.309999942779541 +4386,0,inf,-1,-2,inf,2.25 +4387,69200,3.5404624213697389e-05,-1,-2,3.5404624213697389e-05,2.4500000476837158 +4388,435000,1.2942528883286286e-05,-1,-2,1.2942528883286286e-05,5.630000114440918 +4389,80000,5.6000000768108293e-05,-1,-2,5.6000000768108293e-05,4.4800000190734863 +4390,39000,8.5384614067152143e-05,-1,-2,8.5384614067152143e-05,3.3299999237060547 +4391,28800,9.2361115093808621e-05,-1,-2,9.2361115093808621e-05,2.6600000858306885 +4392,14800,0.00033648649696260691,-1,-2,0.00033648649696260691,4.9800000190734863 +4393,65000,5.8000001445179805e-05,-1,-2,5.8000001445179805e-05,3.7699999809265137 +4394,39000,7.7435899584088475e-05,-1,-2,7.7435899584088475e-05,3.0199999809265137 +4395,44000,7.1363640017807484e-05,-1,-2,7.1363640017807484e-05,3.1400001049041748 +4396,26000,0.00013769230281468481,-1,-2,0.00013769230281468481,3.5799999237060547 +4397,19300,0.000227979282499291,-1,-2,0.000227979282499291,4.4000000953674316 +4398,9600,0.00038958332152105868,-1,-2,0.00038958332152105868,3.7400000095367432 +4399,18000,0.00024722222588025033,-1,-2,0.00024722222588025033,4.4499998092651367 +4400,8600,0.00066511624027043581,-1,-2,0.00066511624027043581,5.7199997901916504 +4401,14000,0.0001857142779044807,-1,-2,0.0001857142779044807,2.5999999046325684 +4402,7400,0.00028513511642813683,-1,-2,0.00028513511642813683,2.1099998950958252 +4403,66300,3.2880845537874848e-05,-1,-2,3.2880845537874848e-05,2.1800000667572021 +4404,7000,0.00055428571067750454,-1,-2,0.00055428571067750454,3.880000114440918 +4405,8500,0.00066823529778048396,-1,-2,0.00066823529778048396,5.679999828338623 +4406,177000,2.3615817553945817e-05,-1,-2,2.3615817553945817e-05,4.179999828338623 +4407,114000,2.4561402824474499e-05,-1,-2,2.4561402824474499e-05,2.7999999523162842 +4408,35300,9.6033996669575572e-05,-1,-2,9.6033996669575572e-05,3.3900001049041748 +4409,9100,0.00037142858491279185,-1,-2,0.00037142858491279185,3.380000114440918 +4410,120050,1.7242815374629572e-05,-1,-2,1.7242815374629572e-05,2.0699999332427979 +4411,41550,0.00011696750880219042,-1,-2,0.00011696750880219042,4.8600001335144043 +4412,35500,0.00013746479817200452,-1,-2,0.00013746479817200452,4.880000114440918 +4413,157000,2.6178344342042692e-05,-1,-2,2.6178344342042692e-05,4.1100001335144043 +4414,17600,0.00014318182365968823,-1,-2,0.00014318182365968823,2.5199999809265137 +4415,590,0.0048644067719578743,-1,-2,0.0048644067719578743,2.869999885559082 +4416,75000,1.3999999282532372e-05,-1,-2,1.3999999282532372e-05,1.0499999523162842 +4417,79000,4.5949367631692439e-05,-1,-2,4.5949367631692439e-05,3.630000114440918 +4418,55000,3.6545454349834472e-05,-1,-2,3.6545454349834472e-05,2.0099999904632568 +4419,27700,0.00010794223635457456,-1,-2,0.00010794223635457456,2.9900000095367432 +4420,13000,0.00018384616123512387,-1,-2,0.00018384616123512387,2.3900001049041748 +4421,0,inf,-1,-2,inf,6.2800002098083496 +4422,8100,0.00038271603989414871,-1,-2,0.00038271603989414871,3.0999999046325684 +4423,84000,3.2619049306958914e-05,-1,-2,3.2619049306958914e-05,2.7400000095367432 +4424,9300,0.00046989246038720012,-1,-2,0.00046989246038720012,4.369999885559082 +4425,244170,9.9930375654366799e-06,-1,-2,9.9930375654366799e-06,2.440000057220459 +4426,145020,3.0340643206727691e-05,-1,-2,3.0340643206727691e-05,4.4000000953674316 +4427,388000,4.9484533519716933e-06,-1,-2,4.9484533519716933e-06,1.9199999570846558 +4428,200,0.021050000563263893,-1,-2,0.021050000563263893,4.2100000381469727 +4429,58300,1.0634648788254708e-05,-1,-2,1.0634648788254708e-05,0.62000000476837158 +4430,13100,0.00043893131078220904,-1,-2,0.00043893131078220904,5.75 +4431,22000,0.00018227273540105671,-1,-2,0.00018227273540105671,4.0100002288818359 +4432,6850,0.00045401457464322448,-1,-2,0.00045401457464322448,3.1099998950958252 +4433,0,inf,-1,-2,inf,1.9600000381469727 +4434,75100,3.7017311115050688e-05,-1,-2,3.7017311115050688e-05,2.7799999713897705 +4435,350000,1.2342857189651113e-05,-1,-2,1.2342857189651113e-05,4.320000171661377 +4436,0,inf,-1,-2,inf,4.4200000762939453 +4437,4200,0.0015023809392005205,-1,-2,0.0015023809392005205,6.309999942779541 +4438,62000,4.4677417463390157e-05,-1,-2,4.4677417463390157e-05,2.7699999809265137 +4439,8300,0.00018795179494190961,-1,-2,0.00018795179494190961,1.559999942779541 +4440,8400,0.00032023809035308659,-1,-2,0.00032023809035308659,2.690000057220459 +4441,0,inf,-1,-2,inf,0.54000002145767212 +4442,652070,5.4135293794388417e-06,-1,-2,5.4135293794388417e-06,3.5299999713897705 +4443,82040,6.2164795053831767e-06,-1,-2,6.2164795053831767e-06,0.50999999046325684 +4444,2400,0.0007708333432674408,-1,-2,0.0007708333432674408,1.8500000238418579 +4445,40100,0.00010274314263369888,-1,-2,0.00010274314263369888,4.119999885559082 +4446,74900,5.7009347074199468e-05,-1,-2,5.7009347074199468e-05,4.2699999809265137 +4447,43700,3.2036612537922338e-05,-1,-2,3.2036612537922338e-05,1.3999999761581421 +4448,115400,1.3431542356556747e-05,-1,-2,1.3431542356556747e-05,1.5499999523162842 +4449,0,inf,-1,-2,inf,5.690000057220459 +4450,16000,0.00018937500135507435,-1,-2,0.00018937500135507435,3.0299999713897705 +4451,0,inf,-1,-2,inf,0.77999997138977051 +4452,35300,9.3767703219782561e-05,-1,-2,9.3767703219782561e-05,3.309999942779541 +4453,12000,0.00034083335776813328,-1,-2,0.00034083335776813328,4.0900001525878906 +4454,25000,0.00016479998885188252,-1,-2,0.00016479998885188252,4.119999885559082 +4455,43000,5.7674420531839132e-05,-1,-2,5.7674420531839132e-05,2.4800000190734863 +4456,2800,0.00052857142873108387,-1,-2,0.00052857142873108387,1.4800000190734863 +4457,77600,2.6804122171597555e-05,-1,-2,2.6804122171597555e-05,2.0799999237060547 +4458,8000,0.00037749999319203198,-1,-2,0.00037749999319203198,3.0199999809265137 +4459,10000,0.00017499999376013875,-1,-2,0.00017499999376013875,1.75 +4460,8460,0.0003581560158636421,-1,-2,0.0003581560158636421,3.0299999713897705 +4461,99200,3.4677421353990212e-05,-1,-2,3.4677421353990212e-05,3.440000057220459 +4462,32500,5.2923078328603879e-05,-1,-2,5.2923078328603879e-05,1.7200000286102295 +4463,174500,2.5329512936878018e-05,-1,-2,2.5329512936878018e-05,4.4200000762939453 +4464,27000,9.7777781775221229e-05,-1,-2,9.7777781775221229e-05,2.6400001049041748 +4465,29000,0.00013965518155600876,-1,-2,0.00013965518155600876,4.0500001907348633 +4466,97000,2.2577320123673417e-05,-1,-2,2.2577320123673417e-05,2.190000057220459 +4467,57100,7.5306481448933482e-05,-1,-2,7.5306481448933482e-05,4.3000001907348633 +4468,125400,4.4338117731967941e-05,-1,-2,4.4338117731967941e-05,5.559999942779541 +4469,0,inf,-1,-2,inf,1.8500000238418579 +4470,57500,3.4956519812112674e-05,-1,-2,3.4956519812112674e-05,2.0099999904632568 +4471,61900,3.9418417145498097e-05,-1,-2,3.9418417145498097e-05,2.440000057220459 +4472,0,inf,-1,-2,inf,3.380000114440918 +4473,0,inf,-1,-2,inf,3.869999885559082 +4474,30000,0.00013066666724625975,-1,-2,0.00013066666724625975,3.9200000762939453 +4475,73400,3.4059947211062536e-05,-1,-2,3.4059947211062536e-05,2.5 +4476,6000,0.00035500002559274435,-1,-2,0.00035500002559274435,2.130000114440918 +4477,4908,0.00013243683497421443,-1,-2,0.00013243683497421443,0.64999997615814209 +4478,25000,0.00018679999629966915,-1,-2,0.00018679999629966915,4.6700000762939453 +4479,8000,0.00036250002449378371,-1,-2,0.00036250002449378371,2.9000000953674316 +4480,9000,0.00030888887704350054,-1,-2,0.00030888887704350054,2.7799999713897705 +4481,143600,2.7158773718838347e-06,-1,-2,2.7158773718838347e-06,0.38999998569488525 +4482,31210,8.3306629676371813e-05,-1,-2,8.3306629676371813e-05,2.5999999046325684 +4483,45600,7.34649074729532e-05,-1,-2,7.34649074729532e-05,3.3499999046325684 +4484,435000,1.1724138175850385e-06,-1,-2,1.1724138175850385e-06,0.50999999046325684 +4485,183900,3.5345294691069284e-06,-1,-2,3.5345294691069284e-06,0.64999997615814209 +4486,30500,0.00011639344302238896,-1,-2,0.00011639344302238896,3.5499999523162842 +4487,118700,3.5551809560274705e-05,-1,-2,3.5551809560274705e-05,4.2199997901916504 +4488,8200,0.00056463415967300534,-1,-2,0.00056463415967300534,4.630000114440918 +4489,15000,4.3333333451300859e-05,-1,-2,4.3333333451300859e-05,0.64999997615814209 +4490,72000,1.9444443751126528e-05,-1,-2,1.9444443751126528e-05,1.3999999761581421 +4491,16000,0.00025562499649822712,-1,-2,0.00025562499649822712,4.0900001525878906 +4492,54500,2.9357797757256776e-05,-1,-2,2.9357797757256776e-05,1.6000000238418579 +4493,46000,7.0000001869630069e-05,-1,-2,7.0000001869630069e-05,3.2200000286102295 +4494,65000,7.1384616603609174e-05,-1,-2,7.1384616603609174e-05,4.6399998664855957 +4495,115200,1.8055554392049089e-05,-1,-2,1.8055554392049089e-05,2.0799999237060547 +4496,15000,0.00037733331555500627,-1,-2,0.00037733331555500627,5.6599998474121094 +4497,7000,0.00079714285675436258,-1,-2,0.00079714285675436258,5.5799999237060547 +4498,55200,1.9565217371564358e-05,-1,-2,1.9565217371564358e-05,1.0800000429153442 +4499,81000,3.2592593925073743e-05,-1,-2,3.2592593925073743e-05,2.6400001049041748 +4500,41400,8.550724305678159e-05,-1,-2,8.550724305678159e-05,3.5399999618530273 +4501,48000,7.7083332143956795e-06,-1,-2,7.7083332143956795e-06,0.37000000476837158 +4502,36300,0.00017272727563977242,-1,-2,0.00017272727563977242,6.2699999809265137 +4503,30000,6.3666666392236948e-05,-1,-2,6.3666666392236948e-05,1.9099999666213989 +4504,158000,5.3797471082361881e-06,-1,-2,5.3797471082361881e-06,0.85000002384185791 +4505,8200,0.00068170734448358417,-1,-2,0.00068170734448358417,5.5900001525878906 +4506,10000,0.00041999996756203473,-1,-2,0.00041999996756203473,4.1999998092651367 +4507,50000,0.00011660000018309802,-1,-2,0.00011660000018309802,5.8299999237060547 +4508,45600,8.2675440353341401e-05,-1,-2,8.2675440353341401e-05,3.7699999809265137 +4509,14000,0.000295000005280599,-1,-2,0.000295000005280599,4.130000114440918 +4510,13100,0.00012137404701206833,-1,-2,0.00012137404701206833,1.5900000333786011 +4511,103300,2.6815101591637358e-05,-1,-2,2.6815101591637358e-05,2.7699999809265137 +4512,126660,1.7053529518307187e-05,-1,-2,1.7053529518307187e-05,2.1600000858306885 +4513,200000,1.8900000213761814e-05,-1,-2,1.8900000213761814e-05,3.7799999713897705 +4514,7900,0.00087848101975396276,-1,-2,0.00087848101975396276,6.940000057220459 +4515,80000,4.8249999963445589e-05,-1,-2,4.8249999963445589e-05,3.8599998950958252 +4516,23000,0.00015565217472612858,-1,-2,0.00015565217472612858,3.5799999237060547 +4517,61000,7.1475413278676569e-05,-1,-2,7.1475413278676569e-05,4.3600001335144043 +4518,20000,8.0999998317565769e-05,-1,-2,8.0999998317565769e-05,1.6200000047683716 +4519,28000,8.7142856500577182e-05,-1,-2,8.7142856500577182e-05,2.440000057220459 +4520,34400,7.7034885180182755e-05,-1,-2,7.7034885180182755e-05,2.6500000953674316 +4521,14800,0.000254054059041664,-1,-2,0.000254054059041664,3.7599999904632568 +4522,450000,8.0444442573934793e-06,-1,-2,8.0444442573934793e-06,3.619999885559082 +4523,153800,2.4317294446518645e-05,-1,-2,2.4317294446518645e-05,3.7400000095367432 +4524,116000,5.7758620641834568e-06,-1,-2,5.7758620641834568e-06,0.67000001668930054 +4525,10600,0.00026509433519095182,-1,-2,0.00026509433519095182,2.809999942779541 +4526,43270,5.1999075367348269e-05,-1,-2,5.1999075367348269e-05,2.25 +4527,30030,5.3946052503306419e-05,-1,-2,5.3946052503306419e-05,1.6200000047683716 +4528,245000,1.6612246326985769e-05,-1,-2,1.6612246326985769e-05,4.070000171661377 +4529,15000,9.8666670965030789e-05,-1,-2,9.8666670965030789e-05,1.4800000190734863 +4530,230,0.015043478459119797,-1,-2,0.015043478459119797,3.4600000381469727 +4531,26000,0.00014769230620004237,-1,-2,0.00014769230620004237,3.8399999141693115 +4532,0,inf,-1,-2,inf,3.7599999904632568 +4533,16330,0.00018187385285273194,-1,-2,0.00018187385285273194,2.9700000286102295 +4534,83000,4.0722894482314587e-05,-1,-2,4.0722894482314587e-05,3.380000114440918 +4535,116000,4.1293104004580528e-05,-1,-2,4.1293104004580528e-05,4.7899999618530273 +4536,147500,2.7457628675620072e-05,-1,-2,2.7457628675620072e-05,4.0500001907348633 +4537,24200,0.00017231405945494771,-1,-2,0.00017231405945494771,4.1700000762939453 +4538,0,inf,-1,-2,inf,2.690000057220459 +4539,0,inf,-1,-2,inf,3.9600000381469727 +4540,70000,5.4000000091036782e-05,-1,-2,5.4000000091036782e-05,3.7799999713897705 +4541,250,0.018079999834299088,-1,-2,0.018079999834299088,4.5199999809265137 +4542,8100,0.0004691357898991555,-1,-2,0.0004691357898991555,3.7999999523162842 +4543,1500,0.0030133333057165146,-1,-2,0.0030133333057165146,4.5199999809265137 +4544,9000,0.00033999999868683517,-1,-2,0.00033999999868683517,3.059999942779541 +4545,14400,0.00018750000162981451,-1,-2,0.00018750000162981451,2.7000000476837158 +4546,139230,3.47626228176523e-05,-1,-2,3.47626228176523e-05,4.8400001525878906 +4547,130000,2.730769119807519e-05,-1,-2,2.730769119807519e-05,3.5499999523162842 +4548,101000,3.8217822293518111e-05,-1,-2,3.8217822293518111e-05,3.8599998950958252 +4549,17300,0.00024624279467388988,-1,-2,0.00024624279467388988,4.2600002288818359 +4550,19200,0.00010625000140862539,-1,-2,0.00010625000140862539,2.0399999618530273 +4551,242500,1.8680413631955162e-05,-1,-2,1.8680413631955162e-05,4.5300002098083496 +4552,15200,0.00017434211622457951,-1,-2,0.00017434211622457951,2.6500000953674316 +4553,41400,6.6908214648719877e-05,-1,-2,6.6908214648719877e-05,2.7699999809265137 +4554,206800,1.7649903384153731e-05,-1,-2,1.7649903384153731e-05,3.6500000953674316 +4555,0,inf,-1,-2,inf,0.9100000262260437 +4556,62200,5.900321775698103e-05,-1,-2,5.900321775698103e-05,3.6700000762939453 +4557,62530,5.0055976316798478e-05,-1,-2,5.0055976316798478e-05,3.130000114440918 +4558,25000,0.0001188000023830682,-1,-2,0.0001188000023830682,2.9700000286102295 +4559,18900,0.00020423279784154147,-1,-2,0.00020423279784154147,3.8599998950958252 +4560,65000,7.2615381213836372e-05,-1,-2,7.2615381213836372e-05,4.7199997901916504 +4561,50000,7.219999679364264e-05,-1,-2,7.219999679364264e-05,3.6099998950958252 +4562,65000,1.7230770026799291e-05,-1,-2,1.7230770026799291e-05,1.1200000047683716 +4563,16000,0.0001806250074878335,-1,-2,0.0001806250074878335,2.8900001049041748 +4564,37900,0.00012295514170546085,-1,-2,0.00012295514170546085,4.6599998474121094 +4565,100000,3.4900000173365697e-05,-1,-2,3.4900000173365697e-05,3.4900000095367432 +4566,0,inf,-1,-2,inf,1.6200000047683716 +4567,4200,0.00080714287469163537,-1,-2,0.00080714287469163537,3.3900001049041748 +4568,5660,0.00029328622622415423,-1,-2,0.00029328622622415423,1.6599999666213989 +4569,73410,5.2445167966652662e-05,-1,-2,5.2445167966652662e-05,3.8499999046325684 +4570,335000,1.026865720632486e-05,-1,-2,1.026865720632486e-05,3.440000057220459 +4571,5000,0.00059399998281151056,-1,-2,0.00059399998281151056,2.9700000286102295 +4572,7000,0.00066142861032858491,-1,-2,0.00066142861032858491,4.630000114440918 +4573,335000,1.7402984667569399e-05,-1,-2,1.7402984667569399e-05,5.8299999237060547 +4574,8860,0.00017832957382779568,-1,-2,0.00017832957382779568,1.5800000429153442 +4575,101000,1.2871286344307009e-05,-1,-2,1.2871286344307009e-05,1.2999999523162842 +4576,52030,5.0547761929919943e-05,-1,-2,5.0547761929919943e-05,2.630000114440918 +4577,58000,3.2241379813058302e-05,-1,-2,3.2241379813058302e-05,1.8700000047683716 +4578,0,inf,-1,-2,inf,3.7699999809265137 +4579,9800,0.00046632654266431928,-1,-2,0.00046632654266431928,4.570000171661377 +4580,12000,0.00031583334202878177,-1,-2,0.00031583334202878177,3.7899999618530273 +4581,0,inf,-1,-2,inf,3.7400000095367432 +4582,73400,1.3215259059506934e-05,-1,-2,1.3215259059506934e-05,0.97000002861022949 +4583,38600,9.1450776380952448e-05,-1,-2,9.1450776380952448e-05,3.5299999713897705 +4584,0,inf,-1,-2,inf,1.9800000190734863 +4585,72000,2.0000001313746907e-05,-1,-2,2.0000001313746907e-05,1.440000057220459 +4586,9100,0.00032747251680120826,-1,-2,0.00032747251680120826,2.9800000190734863 +4587,75000,2.18666664295597e-05,-1,-2,2.18666664295597e-05,1.6399999856948853 +4588,123000,1.6991869415505789e-05,-1,-2,1.6991869415505789e-05,2.0899999141693115 +4589,0,inf,-1,-2,inf,0.38999998569488525 +4590,8000,0.00020249999943189323,-1,-2,0.00020249999943189323,1.6200000047683716 +4591,73400,4.2098090489162132e-05,-1,-2,4.2098090489162132e-05,3.0899999141693115 +4592,27800,0.00013453236897476017,-1,-2,0.00013453236897476017,3.7400000095367432 +4593,43100,6.2645012803841382e-05,-1,-2,6.2645012803841382e-05,2.7000000476837158 +4594,8310,0.00025872443802654743,-1,-2,0.00025872443802654743,2.1500000953674316 +4595,19180,0.00017935349023900926,-1,-2,0.00017935349023900926,3.440000057220459 +4596,48800,0.00014221311721485108,-1,-2,0.00014221311721485108,6.940000057220459 +4597,28000,5.5357140809064731e-05,-1,-2,5.5357140809064731e-05,1.5499999523162842 +4598,15600,0.00027884615701623261,-1,-2,0.00027884615701623261,4.3499999046325684 +4599,0,inf,-1,-2,inf,3.2200000286102295 +4600,0,inf,-1,-2,inf,6.2899999618530273 +4601,10000,0.00043499999446794391,-1,-2,0.00043499999446794391,4.3499999046325684 +4602,77000,2.7272726583760232e-05,-1,-2,2.7272726583760232e-05,2.0999999046325684 +4603,76000,8.4078943473286927e-05,-1,-2,8.4078943473286927e-05,6.3899998664855957 +4604,5050,0.00076831685146316886,-1,-2,0.00076831685146316886,3.880000114440918 +4605,3500,0.0011514286743476987,-1,-2,0.0011514286743476987,4.0300002098083496 +4606,0,inf,-1,-2,inf,2.25 +4607,15000,9.9333330581430346e-05,-1,-2,9.9333330581430346e-05,1.4900000095367432 +4608,37910,6.4626750827301294e-05,-1,-2,6.4626750827301294e-05,2.4500000476837158 +4609,27700,0.0001487364643253386,-1,-2,0.0001487364643253386,4.119999885559082 +4610,18200,0.00010219780233455822,-1,-2,0.00010219780233455822,1.8600000143051147 +4611,22300,7.4439463787712157e-05,-1,-2,7.4439463787712157e-05,1.6599999666213989 +4612,56500,3.8584072171943262e-05,-1,-2,3.8584072171943262e-05,2.1800000667572021 +4613,10180,0.00010412573465146124,-1,-2,0.00010412573465146124,1.059999942779541 +4614,0,inf,-1,-2,inf,4.429999828338623 +4615,25000,0.00010520000796532258,-1,-2,0.00010520000796532258,2.630000114440918 +4616,22000,0.00020954545470885932,-1,-2,0.00020954545470885932,4.6100001335144043 +4617,30600,0.00014673202531412244,-1,-2,0.00014673202531412244,4.4899997711181641 +4618,133000,1.5714285837020725e-05,-1,-2,1.5714285837020725e-05,2.0899999141693115 +4619,37000,0.00012216216418892145,-1,-2,0.00012216216418892145,4.5199999809265137 +4620,125000,3.9599999581696466e-05,-1,-2,3.9599999581696466e-05,4.9499998092651367 +4621,24600,0.00018577236915007234,-1,-2,0.00018577236915007234,4.570000171661377 +4622,17600,0.00016818182484712452,-1,-2,0.00016818182484712452,2.9600000381469727 +4623,0,inf,-1,-2,inf,5.179999828338623 +4624,15900,0.00028679246315732598,-1,-2,0.00028679246315732598,4.559999942779541 +4625,0,inf,-1,-2,inf,1.0800000429153442 +4626,117000,9.5726500148884952e-06,-1,-2,9.5726500148884952e-06,1.1200000047683716 +4627,17200,0.00016802326717879623,-1,-2,0.00016802326717879623,2.8900001049041748 +4628,47900,0.00016409186355303973,-1,-2,0.00016409186355303973,7.8600001335144043 +4629,388000,7.1391750680049881e-06,-1,-2,7.1391750680049881e-06,2.7699999809265137 +4630,106700,3.4020620660157874e-05,-1,-2,3.4020620660157874e-05,3.630000114440918 +4631,43700,7.4370705988258123e-05,-1,-2,7.4370705988258123e-05,3.25 +4632,3600,0.0010722222505137324,-1,-2,0.0010722222505137324,3.8599998950958252 +4633,51000,6.4313724578823894e-05,-1,-2,6.4313724578823894e-05,3.2799999713897705 +4634,21700,0.00013778802531305701,-1,-2,0.00013778802531305701,2.9900000095367432 +4635,0,inf,-1,-2,inf,0.69999998807907104 +4636,12000,0.00022000000171829015,-1,-2,0.00022000000171829015,2.6400001049041748 +4637,55000,8.7090906163211912e-05,-1,-2,8.7090906163211912e-05,4.7899999618530273 +4638,25800,0.00019186045392416418,-1,-2,0.00019186045392416418,4.9499998092651367 +4639,4200,0.0017071429174393415,-1,-2,0.0017071429174393415,7.1700000762939453 +4640,3900,0.0011282050982117653,-1,-2,0.0011282050982117653,4.4000000953674316 +4641,8800,0.0003897727292496711,-1,-2,0.0003897727292496711,3.4300000667572021 +4642,230,0.018913043662905693,-1,-2,0.018913043662905693,4.3499999046325684 +4643,27900,7.5627234764397144e-05,-1,-2,7.5627234764397144e-05,2.1099998950958252 +4644,0,inf,-1,-2,inf,2.9500000476837158 +4645,5700,0.0006228070124052465,-1,-2,0.0006228070124052465,3.5499999523162842 +4646,3900,0.0011256409343332052,-1,-2,0.0011256409343332052,4.3899998664855957 +4647,8100,0.00032592593925073743,-1,-2,0.00032592593925073743,2.6400001049041748 +4648,18000,0.00015333332703448832,-1,-2,0.00015333332703448832,2.7599999904632568 +4649,49000,5.5306121794274077e-05,-1,-2,5.5306121794274077e-05,2.7100000381469727 +4650,75000,1.4133333024801686e-05,-1,-2,1.4133333024801686e-05,1.059999942779541 +4651,13100,0.00020229008805472404,-1,-2,0.00020229008805472404,2.6500000953674316 +4652,45700,3.6105033359490335e-05,-1,-2,3.6105033359490335e-05,1.6499999761581421 +4653,9600,0.00048854167107492685,-1,-2,0.00048854167107492685,4.690000057220459 +4654,80000,2.5375000404892489e-05,-1,-2,2.5375000404892489e-05,2.0299999713897705 +4655,0,inf,-1,-2,inf,1.3999999761581421 +4656,39980,9.1295652964618057e-05,-1,-2,9.1295652964618057e-05,3.6500000953674316 +4657,76150,1.9435325157246552e-05,-1,-2,1.9435325157246552e-05,1.4800000190734863 +4658,6000,0.00059166667051613331,-1,-2,0.00059166667051613331,3.5499999523162842 +4659,0,inf,-1,-2,inf,4.4499998092651367 +4660,6090,0.00043349756742827594,-1,-2,0.00043349756742827594,2.6400001049041748 +4661,63000,4.8730158596299589e-05,-1,-2,4.8730158596299589e-05,3.0699999332427979 +4662,140000,1.2714285730908159e-05,-1,-2,1.2714285730908159e-05,1.7799999713897705 +4663,0,inf,-1,-2,inf,2.25 +4664,63000,6.8888890382368118e-05,-1,-2,6.8888890382368118e-05,4.3400001525878906 +4665,8300,0.00057108432520180941,-1,-2,0.00057108432520180941,4.7399997711181641 +4666,26050,6.1804224969819188e-05,-1,-2,6.1804224969819188e-05,1.6100000143051147 +4667,30920,7.0504531322512776e-05,-1,-2,7.0504531322512776e-05,2.1800000667572021 +4668,32000,0.00010000000474974513,-1,-2,0.00010000000474974513,3.2000000476837158 +4669,47000,3.8510635931743309e-05,-1,-2,3.8510635931743309e-05,1.809999942779541 +4670,11200,0.00026964285643771291,-1,-2,0.00026964285643771291,3.0199999809265137 +4671,6100,0.00056393444538116455,-1,-2,0.00056393444538116455,3.440000057220459 +4672,365300,1.0676157216948923e-05,-1,-2,1.0676157216948923e-05,3.9000000953674316 +4673,15200,0.00037434211117215455,-1,-2,0.00037434211117215455,5.690000057220459 +4674,0,inf,-1,-2,inf,2.75 +4675,13100,8.0916026490740478e-05,-1,-2,8.0916026490740478e-05,1.059999942779541 +4676,18800,5.5319145758403465e-05,-1,-2,5.5319145758403465e-05,1.0399999618530273 +4677,0,inf,-1,-2,inf,2.7699999809265137 +4678,15500,0.00010451612615725026,-1,-2,0.00010451612615725026,1.6200000047683716 +4679,423100,4.7270150389522314e-06,-1,-2,4.7270150389522314e-06,2 +4680,417400,1.3320555808604695e-05,-1,-2,1.3320555808604695e-05,5.559999942779541 +4681,7200,0.00025972223374992609,-1,-2,0.00025972223374992609,1.8700000047683716 +4682,39000,6.1794875364284962e-05,-1,-2,6.1794875364284962e-05,2.4100000858306885 +4683,160000,7.6875003287568688e-06,-1,-2,7.6875003287568688e-06,1.2300000190734863 +4684,0,inf,-1,-2,inf,3.380000114440918 +4685,30,0.0976666659116745,-1,-2,0.0976666659116745,2.9300000667572021 +4686,13000,0.00016384616901632398,-1,-2,0.00016384616901632398,2.130000114440918 +4687,215000,1.1069768333982211e-05,-1,-2,1.1069768333982211e-05,2.380000114440918 +4688,148010,2.1079655198263936e-05,-1,-2,2.1079655198263936e-05,3.119999885559082 +4689,14100,0.0003148936084471643,-1,-2,0.0003148936084471643,4.440000057220459 +4690,0,inf,-1,-2,inf,4.7199997901916504 +4691,65000,3.1230767490342259e-05,-1,-2,3.1230767490342259e-05,2.0299999713897705 +4692,10100,0.00034554456942714751,-1,-2,0.00034554456942714751,3.4900000095367432 +4693,8100,0.00078395061427727342,-1,-2,0.00078395061427727342,6.3499999046325684 +4694,0,inf,-1,-2,inf,1.6200000047683716 +4695,88000,3.2840911444509402e-05,-1,-2,3.2840911444509402e-05,2.8900001049041748 +4696,28000,7.4285708251409233e-05,-1,-2,7.4285708251409233e-05,2.0799999237060547 +4697,59710,3.9021939301164821e-05,-1,-2,3.9021939301164821e-05,2.3299999237060547 +4698,0,inf,-1,-2,inf,0.38999998569488525 +4699,66300,2.3831071302993223e-05,-1,-2,2.3831071302993223e-05,1.5800000429153442 +4700,22870,0.00032181898131966591,-1,-2,0.00032181898131966591,7.3600001335144043 +4701,130000,2.8846154236816801e-05,-1,-2,2.8846154236816801e-05,3.75 +4702,68000,5.8382353017805144e-05,-1,-2,5.8382353017805144e-05,3.9700000286102295 +4703,9600,0.00045625001075677574,-1,-2,0.00045625001075677574,4.380000114440918 +4704,42400,6.8632078182417899e-05,-1,-2,6.8632078182417899e-05,2.9100000858306885 +4705,43000,9.0697678388096392e-05,-1,-2,9.0697678388096392e-05,3.9000000953674316 +4706,8100,0.00050123455002903938,-1,-2,0.00050123455002903938,4.059999942779541 +4707,11400,0.00032894738251343369,-1,-2,0.00032894738251343369,3.75 +4708,27980,0.0001747676869854331,-1,-2,0.0001747676869854331,4.8899998664855957 +4709,8300,0.00031084337388165295,-1,-2,0.00031084337388165295,2.5799999237060547 +4710,8100,0.00026419752975925803,-1,-2,0.00026419752975925803,2.1400001049041748 +4711,0,inf,-1,-2,inf,0.69999998807907104 +4712,8000,0.00075624999590218067,-1,-2,0.00075624999590218067,6.0500001907348633 +4713,7000,0.00070000003324821591,-1,-2,0.00070000003324821591,4.9000000953674316 +4714,0,inf,-1,-2,inf,3.1600000858306885 +4715,0,inf,-1,-2,inf,3.3499999046325684 +4716,8600,0.00043720929534174502,-1,-2,0.00043720929534174502,3.7599999904632568 +4717,8500,0.00030588233494199812,-1,-2,0.00030588233494199812,2.5999999046325684 +4718,13500,4.9629630666458979e-05,-1,-2,4.9629630666458979e-05,0.67000001668930054 +4719,95000,3.8631580537185073e-05,-1,-2,3.8631580537185073e-05,3.6700000762939453 +4720,92500,2.9945946153020486e-05,-1,-2,2.9945946153020486e-05,2.7699999809265137 +4721,74980,4.1611096094129607e-05,-1,-2,4.1611096094129607e-05,3.119999885559082 +4722,42000,0.0001211904818774201,-1,-2,0.0001211904818774201,5.0900001525878906 +4723,9600,0.00034791664802469313,-1,-2,0.00034791664802469313,3.3399999141693115 +4724,0,inf,-1,-2,inf,0.38999998569488525 +4725,75200,4.3882977479370311e-05,-1,-2,4.3882977479370311e-05,3.2999999523162842 +4726,35720,2.4636057787574828e-05,-1,-2,2.4636057787574828e-05,0.87999999523162842 +4727,22930,0.00013693851360585541,-1,-2,0.00013693851360585541,3.1400001049041748 +4728,13400,0.000358955207047984,-1,-2,0.000358955207047984,4.809999942779541 +4729,15600,0.00032371794804930687,-1,-2,0.00032371794804930687,5.0500001907348633 +4730,13960,0.00026790829724632204,-1,-2,0.00026790829724632204,3.7400000095367432 +4731,9400,0.00036595744313672185,-1,-2,0.00036595744313672185,3.440000057220459 +4732,47200,4.6398305130423978e-05,-1,-2,4.6398305130423978e-05,2.190000057220459 +4733,46000,1.6956520994426683e-05,-1,-2,1.6956520994426683e-05,0.77999997138977051 +4734,8200,0.00032317073782905936,-1,-2,0.00032317073782905936,2.6500000953674316 +4735,28000,0.00012785714352503419,-1,-2,0.00012785714352503419,3.5799999237060547 +4736,127000,2.6141731723328121e-05,-1,-2,2.6141731723328121e-05,3.3199999332427979 +4737,100000,2.1600000764010474e-05,-1,-2,2.1600000764010474e-05,2.1600000858306885 +4738,733000,9.7544343589106575e-06,-1,-2,9.7544343589106575e-06,7.1500000953674316 +4739,47900,0.00010647181625245139,-1,-2,0.00010647181625245139,5.0999999046325684 +4740,162100,4.8118445192812942e-06,-1,-2,4.8118445192812942e-06,0.77999997138977051 +4741,6500,0.0006276923231780529,-1,-2,0.0006276923231780529,4.0799999237060547 +4742,0,inf,-1,-2,inf,2.4100000858306885 +4743,39304,6.7423163272906095e-05,-1,-2,6.7423163272906095e-05,2.6500000953674316 +4744,90000,4.2222221964038908e-05,-1,-2,4.2222221964038908e-05,3.7999999523162842 +4745,8800,0.00024886365281417966,-1,-2,0.00024886365281417966,2.190000057220459 +4746,18000,0.00027444443549029529,-1,-2,0.00027444443549029529,4.940000057220459 +4747,0,inf,-1,-2,inf,4.2399997711181641 +4748,20900,0.00014497607480734587,-1,-2,0.00014497607480734587,3.0299999713897705 +4749,14000,0.00038428572588600218,-1,-2,0.00038428572588600218,5.380000114440918 +4750,0,inf,-1,-2,inf,4.6999998092651367 +4751,17000,0.00012705882545560598,-1,-2,0.00012705882545560598,2.1600000858306885 +4752,0,inf,-1,-2,inf,2.6600000858306885 +4753,84000,3.9642854972044006e-05,-1,-2,3.9642854972044006e-05,3.3299999237060547 +4754,137000,2.0145986127317883e-05,-1,-2,2.0145986127317883e-05,2.7599999904632568 +4755,7900,0.00054810126312077045,-1,-2,0.00054810126312077045,4.3299999237060547 +4756,80600,2.1215881133684888e-05,-1,-2,2.1215881133684888e-05,1.7100000381469727 +4757,54500,4.8440368118463084e-05,-1,-2,4.8440368118463084e-05,2.6400001049041748 +4758,8200,0.00049268291331827641,-1,-2,0.00049268291331827641,4.0399999618530273 +4759,0,inf,-1,-2,inf,3.4300000667572021 +4760,0,inf,-1,-2,inf,3.7400000095367432 +4761,37750,0.00012397349928505719,-1,-2,0.00012397349928505719,4.679999828338623 +4762,14000,0.00021428571199066937,-1,-2,0.00021428571199066937,3 +4763,153800,2.5227569494745694e-05,-1,-2,2.5227569494745694e-05,3.880000114440918 +4764,8200,0.00024512194795534015,-1,-2,0.00024512194795534015,2.0099999904632568 +4765,7500,0.00023733332636766136,-1,-2,0.00023733332636766136,1.7799999713897705 +4766,100000,5.860000237589702e-05,-1,-2,5.860000237589702e-05,5.8600001335144043 +4767,12000,0.00026833332958631217,-1,-2,0.00026833332958631217,3.2200000286102295 +4768,75000,3.506666689645499e-05,-1,-2,3.506666689645499e-05,2.630000114440918 +4769,80000,3.6500001442618668e-05,-1,-2,3.6500001442618668e-05,2.9200000762939453 +4770,18000,0.00024111111997626722,-1,-2,0.00024111111997626722,4.3400001525878906 +4771,0,inf,-1,-2,inf,1.8899999856948853 +4772,19200,0.00021302084496710449,-1,-2,0.00021302084496710449,4.0900001525878906 +4773,14000,0.00023428571876138449,-1,-2,0.00023428571876138449,3.2799999713897705 +4774,41200,2.6213592718704604e-05,-1,-2,2.6213592718704604e-05,1.0800000429153442 +4775,17280,8.1018515629693866e-05,-1,-2,8.1018515629693866e-05,1.3999999761581421 +4776,0,inf,-1,-2,inf,4.3899998664855957 +4777,81000,2.2839505618321709e-05,-1,-2,2.2839505618321709e-05,1.8500000238418579 +4778,0,inf,-1,-2,inf,2.630000114440918 +4779,112000,4.7946428821887821e-05,-1,-2,4.7946428821887821e-05,5.369999885559082 +4780,106700,5.5201497161760926e-05,-1,-2,5.5201497161760926e-05,5.8899998664855957 +4781,50000,8.9599998318590224e-05,-1,-2,8.9599998318590224e-05,4.4800000190734863 +4782,23000,0.00024217391910497099,-1,-2,0.00024217391910497099,5.570000171661377 +4783,200,0.014899999834597111,-1,-2,0.014899999834597111,2.9800000190734863 +4784,39000,0.000128717947518453,-1,-2,0.000128717947518453,5.0199999809265137 +4785,0,inf,-1,-2,inf,1.6599999666213989 +4786,0,inf,-1,-2,inf,4.5999999046325684 +4787,35500,4.9577465688344091e-05,-1,-2,4.9577465688344091e-05,1.7599999904632568 +4788,0,inf,-1,-2,inf,1.6599999666213989 +4789,20000,0.00029300001915544271,-1,-2,0.00029300001915544271,5.8600001335144043 +4790,24300,0.00018395061488263309,-1,-2,0.00018395061488263309,4.4699997901916504 +4791,41960,0.0001222592982230708,-1,-2,0.0001222592982230708,5.130000114440918 +4792,4908,0.00084148329915478826,-1,-2,0.00084148329915478826,4.130000114440918 +4793,0,inf,-1,-2,inf,0.77999997138977051 +4794,9000,0.00034888889058493078,-1,-2,0.00034888889058493078,3.1400001049041748 +4795,80300,3.7110836274223402e-05,-1,-2,3.7110836274223402e-05,2.9800000190734863 +4796,29710,0.00016122517990879714,-1,-2,0.00016122517990879714,4.7899999618530273 +4797,16000,0.00012937499559484422,-1,-2,0.00012937499559484422,2.0699999332427979 +4798,7170,0.00030264994711615145,-1,-2,0.00030264994711615145,2.1700000762939453 +4799,17500,0.00029142855782993138,-1,-2,0.00029142855782993138,5.0999999046325684 +4800,46400,0.00010905172530328855,-1,-2,0.00010905172530328855,5.059999942779541 +4801,8100,0.00056790123926475644,-1,-2,0.00056790123926475644,4.5999999046325684 +4802,6000,0.00065833335975185037,-1,-2,0.00065833335975185037,3.9500000476837158 +4803,8000,0.00048249997780658305,-1,-2,0.00048249997780658305,3.8599998950958252 +4804,12160,0.00033799343509599566,-1,-2,0.00033799343509599566,4.1100001335144043 +4805,0,inf,-1,-2,inf,4.9800000190734863 +4806,22100,0.0001828054228099063,-1,-2,0.0001828054228099063,4.0399999618530273 +4807,24000,0.0003070833336096257,-1,-2,0.0003070833336096257,7.369999885559082 +4808,15200,0.00034934209543280303,-1,-2,0.00034934209543280303,5.309999942779541 +4809,115000,2.8608696084120311e-05,-1,-2,2.8608696084120311e-05,3.2899999618530273 +4810,179000,2.1564244889304973e-05,-1,-2,2.1564244889304973e-05,3.8599998950958252 +4811,126000,2.373015922785271e-05,-1,-2,2.373015922785271e-05,2.9900000095367432 +4812,10200,0.00049411761574447155,-1,-2,0.00049411761574447155,5.0399999618530273 +4813,242500,1.1835050827357918e-05,-1,-2,1.1835050827357918e-05,2.869999885559082 +4814,26000,0.00016076922474894673,-1,-2,0.00016076922474894673,4.179999828338623 +4815,31360,0.0001361607137368992,-1,-2,0.0001361607137368992,4.2699999809265137 +4816,6000,0.00080333335790783167,-1,-2,0.00080333335790783167,4.820000171661377 +4817,123000,3.5934961488237604e-05,-1,-2,3.5934961488237604e-05,4.4200000762939453 +4818,60000,6.3333332036563661e-06,-1,-2,6.3333332036563661e-06,0.37999999523162842 +4819,83530,6.3330538978334516e-05,-1,-2,6.3330538978334516e-05,5.2899999618530273 +4820,61900,5.7673667470226064e-05,-1,-2,5.7673667470226064e-05,3.5699999332427979 +4821,222000,2.2657659428659827e-05,-1,-2,2.2657659428659827e-05,5.0300002098083496 +4822,32950,0.00022943854855839163,-1,-2,0.00022943854855839163,7.559999942779541 +4823,13960,0.00030229226103983819,-1,-2,0.00030229226103983819,4.2199997901916504 +4824,24900,0.00014578313857782632,-1,-2,0.00014578313857782632,3.630000114440918 +4825,11000,0.00018272727902512997,-1,-2,0.00018272727902512997,2.0099999904632568 +4826,96000,2.3749998945277184e-05,-1,-2,2.3749998945277184e-05,2.2799999713897705 +4827,8200,0.00058292684843763709,-1,-2,0.00058292684843763709,4.7800002098083496 +4828,161500,2.8854488846263848e-05,-1,-2,2.8854488846263848e-05,4.6599998474121094 +4829,74900,3.9118825952755287e-05,-1,-2,3.9118825952755287e-05,2.9300000667572021 +4830,216700,1.4582372386939824e-05,-1,-2,1.4582372386939824e-05,3.1600000858306885 +4831,42000,4.0238097426481545e-05,-1,-2,4.0238097426481545e-05,1.690000057220459 +4832,114300,2.528434015403036e-05,-1,-2,2.528434015403036e-05,2.8900001049041748 +4833,16800,0.00028035714058205485,-1,-2,0.00028035714058205485,4.7100000381469727 +4834,20000,0.00022499999613501132,-1,-2,0.00022499999613501132,4.5 +4835,115200,3.2118055059981998e-06,-1,-2,3.2118055059981998e-06,0.37000000476837158 +4836,10300,0.00012038835120620206,-1,-2,0.00012038835120620206,1.2400000095367432 +4837,7100,0.00070704222889617085,-1,-2,0.00070704222889617085,5.0199999809265137 +4838,52000,4.0384613384958357e-05,-1,-2,4.0384613384958357e-05,2.0999999046325684 +4839,25000,0.00017400000069756061,-1,-2,0.00017400000069756061,4.3499999046325684 +4840,4300,0.0003023255558218807,-1,-2,0.0003023255558218807,1.2999999523162842 +4841,5700,0.00038245614268817008,-1,-2,0.00038245614268817008,2.1800000667572021 +4842,0,inf,-1,-2,inf,2.630000114440918 +4843,0,inf,-1,-2,inf,1.8700000047683716 +4844,46330,4.3600259232334793e-05,-1,-2,4.3600259232334793e-05,2.0199999809265137 +4845,59800,6.2040133343543857e-05,-1,-2,6.2040133343543857e-05,3.7100000381469727 +4846,0,inf,-1,-2,inf,3.119999885559082 +4847,30000,8.699999307282269e-05,-1,-2,8.699999307282269e-05,2.6099998950958252 +4848,14800,0.00018716216436587274,-1,-2,0.00018716216436587274,2.7699999809265137 +4849,0,inf,-1,-2,inf,4.7100000381469727 +4850,106000,4.0377359255217016e-05,-1,-2,4.0377359255217016e-05,4.2800002098083496 +4851,47000,9.8510638053994626e-05,-1,-2,9.8510638053994626e-05,4.630000114440918 +4852,27800,0.00017302157357335091,-1,-2,0.00017302157357335091,4.809999942779541 +4853,3400,0.00089705880964174867,-1,-2,0.00089705880964174867,3.0499999523162842 +4854,0,inf,-1,-2,inf,3.4200000762939453 +4855,42000,5.7380955695407465e-05,-1,-2,5.7380955695407465e-05,2.4100000858306885 +4856,8300,0.00078795180888846517,-1,-2,0.00078795180888846517,6.5399999618530273 +4857,33220,0.0001273329253308475,-1,-2,0.0001273329253308475,4.2300000190734863 +4858,62300,6.1476726841647178e-05,-1,-2,6.1476726841647178e-05,3.8299999237060547 +4859,201500,3.1712159398011863e-05,-1,-2,3.1712159398011863e-05,6.3899998664855957 +4860,30000,8.4333332779351622e-05,-1,-2,8.4333332779351622e-05,2.5299999713897705 +4861,0,inf,-1,-2,inf,3.2899999618530273 +4862,8460,0.00067257683258503675,-1,-2,0.00067257683258503675,5.690000057220459 +4863,650000,8.7230773715418763e-06,-1,-2,8.7230773715418763e-06,5.6700000762939453 +4864,74980,8.0288074968848377e-05,-1,-2,8.0288074968848377e-05,6.0199999809265137 +4865,8300,0.00033373493351973593,-1,-2,0.00033373493351973593,2.7699999809265137 +4866,68000,4.029411866213195e-05,-1,-2,4.029411866213195e-05,2.7400000095367432 +4867,33000,7.9090903454925865e-05,-1,-2,7.9090903454925865e-05,2.6099998950958252 +4868,60000,1.6500000128871761e-05,-1,-2,1.6500000128871761e-05,0.99000000953674316 +4869,0,inf,-1,-2,inf,3.7799999713897705 +4870,56000,1.8214284864370711e-05,-1,-2,1.8214284864370711e-05,1.0199999809265137 +4871,18900,0.00027989418595097959,-1,-2,0.00027989418595097959,5.2899999618530273 +4872,25000,0.00018079999426845461,-1,-2,0.00018079999426845461,4.5199999809265137 +4873,63070,4.4078009523218498e-05,-1,-2,4.4078009523218498e-05,2.7799999713897705 +4874,7000,0.0003257142670918256,-1,-2,0.0003257142670918256,2.2799999713897705 +4875,60000,7.7999997301958501e-05,-1,-2,7.7999997301958501e-05,4.679999828338623 +4876,16000,0.00015249999705702066,-1,-2,0.00015249999705702066,2.440000057220459 +4877,136600,1.4787700820306782e-05,-1,-2,1.4787700820306782e-05,2.0199999809265137 +4878,50000,8.0799996794667095e-05,-1,-2,8.0799996794667095e-05,4.0399999618530273 +4879,8000,0.00040000001899898052,-1,-2,0.00040000001899898052,3.2000000476837158 +4880,8100,0.00038765431963838637,-1,-2,0.00038765431963838637,3.1400001049041748 +4881,9000,0.00074333336669951677,-1,-2,0.00074333336669951677,6.690000057220459 +4882,16000,0.00029562501003965735,-1,-2,0.00029562501003965735,4.7300000190734863 +4883,18000,0.00010388888767920434,-1,-2,0.00010388888767920434,1.8700000047683716 +4884,12000,0.00040583332884125412,-1,-2,0.00040583332884125412,4.869999885559082 +4885,61740,6.3006154960021377e-05,-1,-2,6.3006154960021377e-05,3.8900001049041748 +4886,137000,4.1386861994396895e-05,-1,-2,4.1386861994396895e-05,5.6700000762939453 +4887,0,inf,-1,-2,inf,3.7599999904632568 +4888,13900,0.00017985611339099705,-1,-2,0.00017985611339099705,2.5 +4889,54050,8.8621643953956664e-05,-1,-2,8.8621643953956664e-05,4.7899999618530273 +4890,101400,2.6528599846642464e-05,-1,-2,2.6528599846642464e-05,2.690000057220459 +4891,46790,6.133788701845333e-05,-1,-2,6.133788701845333e-05,2.869999885559082 +4892,118800,3.8299665902741253e-05,-1,-2,3.8299665902741253e-05,4.5500001907348633 +4893,14000,0.00034428571234457195,-1,-2,0.00034428571234457195,4.820000171661377 +4894,37000,9.4864866696298122e-05,-1,-2,9.4864866696298122e-05,3.5099999904632568 +4895,44000,4.5909091568319127e-05,-1,-2,4.5909091568319127e-05,2.0199999809265137 +4896,26300,0.0001178707170765847,-1,-2,0.0001178707170765847,3.0999999046325684 +4897,31500,0.00017555555677972734,-1,-2,0.00017555555677972734,5.5300002098083496 +4898,9600,0.00055312499171122909,-1,-2,0.00055312499171122909,5.309999942779541 +4899,28900,0.00016816609422676265,-1,-2,0.00016816609422676265,4.8600001335144043 +4900,137000,4.1094892367254943e-05,-1,-2,4.1094892367254943e-05,5.630000114440918 +4901,6000,0.00013499999477062374,-1,-2,0.00013499999477062374,0.81000000238418579 +4902,16000,3.5000000934815034e-05,-1,-2,3.5000000934815034e-05,0.56000000238418579 +4903,15400,0.0001766233763191849,-1,-2,0.0001766233763191849,2.7200000286102295 +4904,64300,3.654743341030553e-05,-1,-2,3.654743341030553e-05,2.3499999046325684 +4905,62000,7.8225806646514684e-05,-1,-2,7.8225806646514684e-05,4.8499999046325684 +4906,8300,0.00032650603679940104,-1,-2,0.00032650603679940104,2.7100000381469727 +4907,80000,1.6250000044237822e-05,-1,-2,1.6250000044237822e-05,1.2999999523162842 +4908,13000,9.9999997473787516e-05,-1,-2,9.9999997473787516e-05,1.2999999523162842 +4909,14500,0.00022551724396180362,-1,-2,0.00022551724396180362,3.2699999809265137 +4910,56500,6.9380534114316106e-05,-1,-2,6.9380534114316106e-05,3.9200000762939453 +4911,0,inf,-1,-2,inf,3.9700000286102295 +4912,4000,0.00054500001715496182,-1,-2,0.00054500001715496182,2.1800000667572021 +4913,7000,0.00070714281173422933,-1,-2,0.00070714281173422933,4.9499998092651367 +4914,0,inf,-1,-2,inf,1.9099999666213989 +4915,100000,1.9600000086938962e-05,-1,-2,1.9600000086938962e-05,1.9600000381469727 +4916,101500,2.5615761842345819e-05,-1,-2,2.5615761842345819e-05,2.5999999046325684 +4917,148010,2.8511585696833208e-05,-1,-2,2.8511585696833208e-05,4.2199997901916504 +4918,59800,7.8260869486257434e-05,-1,-2,7.8260869486257434e-05,4.679999828338623 +4919,19000,5.5263153626583517e-05,-1,-2,5.5263153626583517e-05,1.0499999523162842 +4920,57508,2.9734994313912466e-05,-1,-2,2.9734994313912466e-05,1.7100000381469727 +4921,42000,0.0001271428627660498,-1,-2,0.0001271428627660498,5.3400001525878906 +4922,11000,0.00036363635445013642,-1,-2,0.00036363635445013642,4 +4923,101500,7.9802957770880312e-06,-1,-2,7.9802957770880312e-06,0.81000000238418579 +4924,38000,9.6315794507972896e-05,-1,-2,9.6315794507972896e-05,3.6600000858306885 +4925,73500,3.6054421798326075e-05,-1,-2,3.6054421798326075e-05,2.6500000953674316 +4926,144400,3.2063711842056364e-05,-1,-2,3.2063711842056364e-05,4.630000114440918 +4927,37200,8.1989244790747762e-05,-1,-2,8.1989244790747762e-05,3.0499999523162842 +4928,23100,0.00012900432921014726,-1,-2,0.00012900432921014726,2.9800000190734863 +4929,0,inf,-1,-2,inf,1.3300000429153442 +4930,51000,6.117646989878267e-05,-1,-2,6.117646989878267e-05,3.119999885559082 +4931,80400,6.2810948293190449e-05,-1,-2,6.2810948293190449e-05,5.0500001907348633 +4932,61500,7.5772353739012033e-05,-1,-2,7.5772353739012033e-05,4.6599998474121094 +4933,12100,0.0002148760249838233,-1,-2,0.0002148760249838233,2.5999999046325684 +4934,0,inf,-1,-2,inf,2.2400000095367432 +4935,8400,0.00033095237449742854,-1,-2,0.00033095237449742854,2.7799999713897705 +4936,18000,0.00037611110019497573,-1,-2,0.00037611110019497573,6.7699999809265137 +4937,63000,9.2539681645575911e-05,-1,-2,9.2539681645575911e-05,5.8299999237060547 +4938,0,inf,-1,-2,inf,4.630000114440918 +4939,6000,0.00040166667895391583,-1,-2,0.00040166667895391583,2.4100000858306885 +4940,0,inf,-1,-2,inf,4.179999828338623 +4941,8200,0.00033780487137846649,-1,-2,0.00033780487137846649,2.7699999809265137 +4942,31900,8.1504702393431216e-05,-1,-2,8.1504702393431216e-05,2.5999999046325684 +4943,161300,1.5065096704347525e-05,-1,-2,1.5065096704347525e-05,2.4300000667572021 +4944,0,inf,-1,-2,inf,4.5300002098083496 +4945,40000,7.9999997979030013e-05,-1,-2,7.9999997979030013e-05,3.2000000476837158 +4946,133000,3.4060150937875733e-05,-1,-2,3.4060150937875733e-05,4.5300002098083496 +4947,160800,1.9651741240522824e-05,-1,-2,1.9651741240522824e-05,3.1600000858306885 +4948,13800,0.00023260869784280658,-1,-2,0.00023260869784280658,3.2100000381469727 +4949,109100,2.7589367164182477e-05,-1,-2,2.7589367164182477e-05,3.0099999904632568 +4950,130000,4.3307692976668477e-05,-1,-2,4.3307692976668477e-05,5.630000114440918 +4951,47100,8.0042460467666388e-05,-1,-2,8.0042460467666388e-05,3.7699999809265137 +4952,50000,7.6999996963422745e-05,-1,-2,7.6999996963422745e-05,3.8499999046325684 +4953,24660,0.000163422548212111,-1,-2,0.000163422548212111,4.0300002098083496 +4954,109000,2.880734064092394e-05,-1,-2,2.880734064092394e-05,3.1400001049041748 +4955,62000,9.9999997473787516e-06,-1,-2,9.9999997473787516e-06,0.62000000476837158 +4956,18000,0.00016555555339436978,-1,-2,0.00016555555339436978,2.9800000190734863 +4957,423100,6.8069016379013192e-06,-1,-2,6.8069016379013192e-06,2.880000114440918 +4958,80000,9.4499999249819666e-05,-1,-2,9.4499999249819666e-05,7.559999942779541 +4959,72000,7.0833331847097725e-05,-1,-2,7.0833331847097725e-05,5.0999999046325684 +4960,22070,0.00024059809220489115,-1,-2,0.00024059809220489115,5.309999942779541 +4961,4900,0.00085306121036410332,-1,-2,0.00085306121036410332,4.179999828338623 +4962,55000,5.8909092331305146e-05,-1,-2,5.8909092331305146e-05,3.2400000095367432 +4963,17400,0.00026954023633152246,-1,-2,0.00026954023633152246,4.690000057220459 +4964,9400,0.00063404254615306854,-1,-2,0.00063404254615306854,5.9600000381469727 +4965,0,inf,-1,-2,inf,3.0499999523162842 +4966,29500,1.1186441042809747e-05,-1,-2,1.1186441042809747e-05,0.33000001311302185 +4967,174500,3.1977077014744282e-05,-1,-2,3.1977077014744282e-05,5.5799999237060547 +4968,43000,8.4651168435811996e-05,-1,-2,8.4651168435811996e-05,3.6400001049041748 +4969,32500,5.2000003051944077e-05,-1,-2,5.2000003051944077e-05,1.690000057220459 +4970,0,inf,-1,-2,inf,4.2600002288818359 +4971,9600,0.00055937498109415174,-1,-2,0.00055937498109415174,5.369999885559082 +4972,65000,5.1076920499326661e-05,-1,-2,5.1076920499326661e-05,3.3199999332427979 +4973,8100,0.00047777776489965618,-1,-2,0.00047777776489965618,3.869999885559082 +4974,13960,0.00022277935931924731,-1,-2,0.00022277935931924731,3.1099998950958252 +4975,141200,9.490085176366847e-06,-1,-2,9.490085176366847e-06,1.3400000333786011 +4976,18100,8.1767953815869987e-05,-1,-2,8.1767953815869987e-05,1.4800000190734863 +4977,86400,4.8032408813014627e-05,-1,-2,4.8032408813014627e-05,4.1500000953674316 +4978,0,inf,-1,-2,inf,4.2199997901916504 +4979,38600,5.388600766309537e-05,-1,-2,5.388600766309537e-05,2.0799999237060547 +4980,9300,0.00078279571607708931,-1,-2,0.00078279571607708931,7.2800002098083496 +4981,0,inf,-1,-2,inf,4.9000000953674316 +4982,62530,4.7657125833211467e-05,-1,-2,4.7657125833211467e-05,2.9800000190734863 +4983,2400,0.00081250001676380634,-1,-2,0.00081250001676380634,1.9500000476837158 +4984,0,inf,-1,-2,inf,1.8700000047683716 +4985,62000,3.9838709199102595e-05,-1,-2,3.9838709199102595e-05,2.4700000286102295 +4986,230,0.027347825467586517,-1,-2,0.027347825467586517,6.2899999618530273 +4987,0,inf,-1,-2,inf,2.8499999046325684 +4988,43800,8.6301370174624026e-05,-1,-2,8.6301370174624026e-05,3.7799999713897705 +4989,14300,0.00055524474009871483,-1,-2,0.00055524474009871483,7.940000057220459 +4990,6000,0.0002899999963119626,-1,-2,0.0002899999963119626,1.7400000095367432 +4991,12630,0.00031433097319677472,-1,-2,0.00031433097319677472,3.9700000286102295 +4992,41500,0.00012240963405929506,-1,-2,0.00012240963405929506,5.0799999237060547 +4993,30500,0.00013934426533523947,-1,-2,0.00013934426533523947,4.25 +4994,26100,0.00016551725275348872,-1,-2,0.00016551725275348872,4.320000171661377 +4995,15000,0.00025866666692309082,-1,-2,0.00025866666692309082,3.880000114440918 +4996,13100,0.00057709921384230256,-1,-2,0.00057709921384230256,7.559999942779541 +4997,0,inf,-1,-2,inf,0.68000000715255737 +4998,103000,1.5728155631222762e-05,-1,-2,1.5728155631222762e-05,1.6200000047683716 +4999,14800,2.5000001187436283e-05,-1,-2,2.5000001187436283e-05,0.37000000476837158 diff --git a/sharrow/viz.py b/sharrow/viz.py new file mode 100644 index 0000000..867a81f --- /dev/null +++ b/sharrow/viz.py @@ -0,0 +1,163 @@ +import io +from itertools import zip_longest + +try: + from IPython.display import SVG +except ImportError: + SVG = None + +try: + import pygraphviz as viz +except ImportError: + viz = None + + +def make_graph(datatree, fontname="Arial", fontsize=12, ignore_joined_dims=True): + if viz is None: + raise ModuleNotFoundError("pygraphviz is not installed") + + small = f"{fontsize * .7:.1f}" + g = viz.AGraph(rankdir="LR", strict=False, fontname=fontname, fontsize=fontsize) + + connected_nodes = set() + for e in datatree._graph.edges: + rel = datatree._get_relationship(e) + connected_nodes.add(rel.parent_data) + connected_nodes.add(rel.child_data) + + g_nodes = {} + if len(datatree._graph.nodes): + if datatree.root_node_name: + if ignore_joined_dims: + dims = [ + i + for i in datatree.subspaces[datatree.root_node_name].dims + if not i.startswith("joined_") + ] + else: + dims = list(datatree.subspaces[datatree.root_node_name].dims) + g_nodes[datatree.root_node_name] = {"dims": dims, "vars": set()} + for k in datatree._graph.nodes: + if k == datatree.root_node_name or k not in connected_nodes: + continue + if ignore_joined_dims: + dims = [ + i for i in datatree.subspaces[k].dims if not i.startswith("joined_") + ] + else: + dims = list(datatree.subspaces[k].dims) + g_nodes[k] = {"dims": dims, "vars": set()} + for e in datatree._graph.edges: + rel = datatree._get_relationship(e) + g_nodes[rel.parent_data]["vars"].add(rel.parent_name) + + def node_label_simple(k, v): + dim_names = [f"{i}" for i in v["dims"]] + dim_defs = "|".join(dim_names) + var_names = [f"{i}" for i in v["vars"]] + var_defs = "|".join(var_names) + out = f"{k}|{{{{Dimensions|{dim_defs}}}||{{Variables|{var_defs}}}}}" + return out + + def node_label(k, v): + cells = [] + if len(v["dims"]) > 0 and len(v["vars"]) > 0: + cells.append( + f""" + + DIMENSIONS + VARIABLES + + """ + ) + for _d, _v in zip_longest(v["dims"], v["vars"], fillvalue=""): + if _d == "": + cells.append( + f""" + + + {_v} + + """ + ) + elif _v == "": + cells.append( + f""" + + {_d} + + + """ + ) + else: + cells.append( + f""" + + {_d} + {_v} + + """ + ) + elif len(v["dims"]) > 0 and len(v["vars"]) == 0: + cells.append( + f""" + + DIMENSIONS + + """ + ) + for _d in v["dims"]: + cells.append( + f""" + + {_d} + + """ + ) + + out = f"""< + + {''.join(cells)} +
{k}
>""" + return out + + if len(datatree._graph.nodes): + for k, v in g_nodes.items(): + g.add_node( + k, + label=node_label(k, v), + shape="plaintext", + fontname=fontname, + fontsize=fontsize, + ) + + for e in datatree._graph.edges: + rel = datatree._get_relationship(e) + g.add_edge( + rel.parent_data, + rel.child_data, + key=repr(rel), + tailport=f"var{rel.parent_name}", + headport=f"dim{rel.child_name}", + dir="forward", + arrowhead="odiamond" if rel.indexing == "label" else "normal", + ) + + return g + + +def display_svg(graph): + """ + Render a pygraphviz AGraph as SVG. + + Parameters + ---------- + graph : pygraphviz.agraph.AGraph + + Returns + ------- + IPython.core.display.SVG + """ + pyg_imgdata = io.BytesIO() + graph.draw(pyg_imgdata, format="svg", prog="dot") + return SVG(pyg_imgdata.getvalue()) From e3a3cc46e45e4507d4bf5a168b87fe08da04b2ac Mon Sep 17 00:00:00 2001 From: Jeffrey Newman Date: Wed, 11 Jan 2023 16:59:52 -0600 Subject: [PATCH 2/7] Recompile when existence of df.get() input changes (#33) * repair and test subspace fallbacks * allow error on graphviz --- docs/walkthrough/one-dim.ipynb | 6 +- sharrow/aster.py | 10 +- sharrow/flows.py | 157 ++++++++++++++++++++++++++++ sharrow/tests/test_relationships.py | 90 ++++++++++++++-- 4 files changed, 251 insertions(+), 12 deletions(-) diff --git a/docs/walkthrough/one-dim.ipynb b/docs/walkthrough/one-dim.ipynb index 96ec3f3..0090468 100644 --- a/docs/walkthrough/one-dim.ipynb +++ b/docs/walkthrough/one-dim.ipynb @@ -939,7 +939,11 @@ "cell_type": "code", "execution_count": null, "id": "fb9f17cc", - "metadata": {}, + "metadata": { + "tags": [ + "raises-exception" + ] + }, "outputs": [], "source": [ "nest_tree" diff --git a/sharrow/aster.py b/sharrow/aster.py index 4fb8f24..ded9c06 100755 --- a/sharrow/aster.py +++ b/sharrow/aster.py @@ -398,7 +398,9 @@ def _replacement( if self.spacevars is not None: if attr not in self.spacevars: - if topname == pref_topname and not self.swallow_errors: + if self.get_default or ( + topname == pref_topname and not self.swallow_errors + ): raise KeyError(f"{topname}..{attr}") # we originally raised a KeyError here regardless, but what if we just # give back the original node, and see if other spaces, @@ -649,8 +651,10 @@ def visit_Subscript(self, node): def visit_Attribute(self, node): if isinstance(node.value, ast.Name): + # for XXX.YYY, XXX is a space name and YYY is a literal value: skims.DIST if node.value.id == self.spacename: return self._replacement(node.attr, node.ctx, node) + # for ____.YYY, handles unadorned values in the top level if node.value.id == self.rawalias and node.attr in self.spacevars: result = ast.Subscript( value=ast.Name(id=self.rawname, ctx=ast.Load()), @@ -659,6 +663,7 @@ def visit_Attribute(self, node): ) self.log_event(f"visit_Attribute(Raw {node.attr})", node, result) return result + # for YYY.ZZZ, where YYY is a variable in the root and ZZZ is anything if self.spacename == "" and node.value.id in self.spacevars: result = ast.Attribute( value=self.visit(node.value), @@ -669,6 +674,7 @@ def visit_Attribute(self, node): return result return node else: + # pass through result = ast.Attribute( value=self.visit(node.value), attr=node.attr, @@ -912,7 +918,7 @@ def visit_Call(self, node): keywords=[], ) - # implement x.get("y",z) + # implement x.get("y",z) where x is the spacename if ( isinstance(node.func, ast.Attribute) and node.func.attr == "get" diff --git a/sharrow/flows.py b/sharrow/flows.py index 5ba3439..382eae0 100644 --- a/sharrow/flows.py +++ b/sharrow/flows.py @@ -46,6 +46,7 @@ class CacheMissWarning(UserWarning): "hard_sigmoid", "transpose_leading", "clip", + "get", } @@ -140,6 +141,56 @@ def filter_name_tokens(expr, matchable_names=None): return name_tokens, arg_tokens +class ExtractOptionalGetTokens(ast.NodeTransformer): + def __init__(self, from_names): + self.optional_get_tokens = set() + self.required_get_tokens = set() + self.from_names = from_names + + def visit_Call(self, node): + if isinstance(node.func, ast.Attribute): + if node.func.attr == "get": + if isinstance(node.func.value, ast.Name): + if node.func.value.id in self.from_names: + if len(node.args) == 1: + if isinstance(node.args[0], ast.Constant): + if len(node.keywords) == 0: + self.required_get_tokens.add( + (node.func.value.id, node.args[0].value) + ) + elif ( + len(node.keywords) == 1 + and node.keywords[0].arg == "default" + ): + self.optional_get_tokens.add( + (node.func.value.id, node.args[0].value) + ) + else: + raise ValueError( + f"{node.func.value.id}.get with unexpected keyword arguments" + ) + if len(node.args) == 2: + if isinstance(node.args[0], ast.Constant): + self.optional_get_tokens.add( + (node.func.value.id, node.args[0].value) + ) + if len(node.args) > 2: + raise ValueError( + f"{node.func.value.id}.get with more than 2 positional arguments" + ) + return node + + def check(self, node): + if isinstance(node, str): + node = ast.parse(node) + if isinstance(node, ast.AST): + self.visit(node) + else: + for i in node: + self.check(i) + return self.optional_get_tokens + + def coerce_to_range_index(idx): if isinstance(idx, pd.RangeIndex): return idx @@ -916,6 +967,37 @@ def __initialize_1( if aux_var in all_raw_names: self._used_aux_vars.append(aux_var) + subspace_names = set() + for (k, _) in self.tree.subspaces_iter(): + subspace_names.add(k) + for k in self.tree.subspace_fallbacks: + subspace_names.add(k) + optional_get_tokens = ExtractOptionalGetTokens(from_names=subspace_names).check( + defs.values() + ) + self._optional_get_tokens = [] + if optional_get_tokens: + for (_spacename, _varname) in optional_get_tokens: + found = False + if ( + _spacename in self.tree.subspaces + and _varname in self.tree.subspaces[_spacename] + ): + self._optional_get_tokens.append(f"__{_spacename}__{_varname}:True") + found = True + elif _spacename in self.tree.subspace_fallbacks: + for _subspacename in self.tree.subspace_fallbacks[_spacename]: + if _varname in self.tree.subspaces[_subspacename]: + self._optional_get_tokens.append( + f"__{_subspacename}__{_varname}:__{_spacename}__{_varname}" + ) + found = True + break + if not found: + self._optional_get_tokens.append( + f"__{_spacename}__{_varname}:False" + ) + self._hashing_level = hashing_level if self._hashing_level > 1: func_code, all_name_tokens = self.init_sub_funcs( @@ -956,6 +1038,8 @@ def _flow_hash_push(x): _flow_hash_push(f"aux_var:{k}") for k in sorted(self._used_extra_funcs): _flow_hash_push(f"func:{k}") + for k in sorted(self._optional_get_tokens): + _flow_hash_push(f"OPTIONAL:{k}") _flow_hash_push("---DataTree---") for k in self.arg_names: _flow_hash_push(f"arg:{k}") @@ -1164,6 +1248,32 @@ def init_sub_funcs( other_way = True # at least one variable was found in a get break + # check if we can resolve this "get" on any other subspace + for other_spacename in self.tree.subspace_fallbacks.get( + topkey, [] + ): + dim_slots, digital_encodings, blenders = meta_data[ + other_spacename + ] + try: + expr = expression_for_numba( + expr, + spacename, + dim_slots, + dim_slots, + digital_encodings=digital_encodings, + prefer_name=other_spacename, + extra_vars=self.tree.extra_vars, + blenders=blenders, + bool_wrapping=self.bool_wrapping, + get_default=True, + ) + except KeyError as err: # noqa: F841 + pass + else: + other_way = True + # at least one variable was found in a fallback + break if not other_way: raise if prior_expr == expr: @@ -1174,6 +1284,49 @@ def init_sub_funcs( # nothing else needs to change prior_expr = expr + # now process for subspace fallbacks + for gd in [False, True]: + # first run all these with get_default off, nothing drops to defaults + # if we might find it later. Then do a second pass with get_default on. + for ( + alias_spacename, + actual_spacenames, + ) in self.tree.subspace_fallbacks.items(): + for actual_spacename in actual_spacenames: + dim_slots, digital_encodings, blenders = meta_data[ + actual_spacename + ] + try: + expr = expression_for_numba( + expr, + alias_spacename, + dim_slots, + dim_slots, + digital_encodings=digital_encodings, + prefer_name=actual_spacename, + extra_vars=self.tree.extra_vars, + blenders=blenders, + bool_wrapping=self.bool_wrapping, + get_default=gd, + ) + except KeyError: + # there was an error, but lets make sure we process the + # whole expression to rewrite all the things we can before + # moving on to the fallback processing. + expr = expression_for_numba( + expr, + alias_spacename, + dim_slots, + dim_slots, + digital_encodings=digital_encodings, + prefer_name=actual_spacename, + extra_vars=self.tree.extra_vars, + blenders=blenders, + bool_wrapping=self.bool_wrapping, + swallow_errors=True, + get_default=gd, + ) + # now find instances where an identifier is previously created in this flow. expr = expression_for_numba( expr, @@ -2457,6 +2610,10 @@ def logit_draws( mask=mask, ) + @property + def defs(self): + return {k: v[0] for (k, v) in self._raw_functions.items()} + @property def function_names(self): return list(self._raw_functions.keys()) diff --git a/sharrow/tests/test_relationships.py b/sharrow/tests/test_relationships.py index f2add2b..29c064d 100644 --- a/sharrow/tests/test_relationships.py +++ b/sharrow/tests/test_relationships.py @@ -74,6 +74,52 @@ def test_shared_data(dataframe_regression, households, skims): dataframe_regression.check(result2, basename="test_shared_data_2") +def test_subspace_fallbacks(dataframe_regression, households, skims): + + tree = DataTree( + base=households, + skims=skims, + relationships=( + "base.otaz_idx->skims.otaz", + "base.dtaz_idx->skims.dtaz", + "base.timeperiod5->skims.time_period", + ), + ) + tree.subspace_fallbacks["df"] = ["base", "skims"] + + flow1 = tree.setup_flow( + { + "income": "df['income']", + "sov_time_by_income": "df['SOV_TIME']/df['income']", + "sov_cost_by_income": "df['HOV3_TIME']", + } + ) + result1 = flow1._load(tree, as_dataframe=True) + dataframe_regression.check(result1, basename="test_shared_data") + + flow2 = tree.setup_flow( + { + "income": "income", + "sov_time_by_income": "SOV_TIME/income", + "sov_cost_by_income": "HOV3_TIME", + } + ) + result2 = flow2._load(tree, as_dataframe=True) + dataframe_regression.check(result2, basename="test_shared_data") + + # names that are not valid Python identifiers + flow3 = tree.setup_flow( + { + "income > 10k": "df.income > 10_000", + "income [up to 10k]": "df.income <= 10_000", + "sov_time / income": "df.SOV_TIME/df.income", + "log1p(sov_cost_by_income)": "log1p(df.HOV3_TIME)", + } + ) + result3 = flow3._load(tree, as_dataframe=True) + dataframe_regression.check(result3, basename="test_shared_data_2") + + def test_shared_data_reversible(dataframe_regression, households, skims): tree = DataTree( @@ -778,9 +824,9 @@ def test_get(dataframe_regression, households, skims): ), ) - ss = tree.setup_flow( + flow1 = tree.setup_flow( { - "income": "base.get('income', 0)", + "income": "base.get('income', 0) + base.get('missing_one', 0)", "sov_time_by_income": "skims.SOV_TIME/base.get('income', 0)", "missing_data": "base.get('missing_data', -1)", "missing_skim": "skims.get('missing_core', -2)", @@ -788,12 +834,40 @@ def test_get(dataframe_regression, households, skims): "sov_cost_by_income_2": "skims.get('HOV3_TIME', 999)", }, ) - result = ss._load(tree, as_dataframe=True) + result = flow1._load(tree, as_dataframe=True) dataframe_regression.check(result) - s2 = tree.setup_flow( + tree_plus = DataTree( + base=households.assign(missing_one=1.0), + skims=skims, + relationships=( + "base.otaz_idx->skims.otaz", + "base.dtaz_idx->skims.dtaz", + "base.timeperiod5->skims.time_period", + ), + ) + flow2 = tree_plus.setup_flow(flow1.defs) + result = flow2._load(tree_plus, as_dataframe=True) + dataframe_regression.check(result.eval("income = income-1")) + assert flow2.flow_hash != flow1.flow_hash + + tree.subspace_fallbacks["df"] = ["base"] + flow3 = tree.setup_flow( + { + "income": "base.get('income', 0)", + "sov_time_by_income": "skims.SOV_TIME/df.get('income', 0)", + "missing_data": "df.get('missing_data', -1)", + "missing_skim": "skims.get('missing_core', -2)", + "sov_time_by_income_2": "skims.get('SOV_TIME')/df.income", + "sov_cost_by_income_2": "skims.get('HOV3_TIME', 999)", + }, + ) + result = flow3._load(tree, as_dataframe=True) + dataframe_regression.check(result) + + flow4 = tree.setup_flow( { - "income": "base.get('income', default=0)", + "income": "base.get('income', default=0) + df.get('missing_one', 0)", "sov_time_by_income": "skims.SOV_TIME/base.get('income', default=0)", "missing_data": "base.get('missing_data', default=-1)", "missing_skim": "skims.get('missing_core', default=-2)", @@ -801,10 +875,8 @@ def test_get(dataframe_regression, households, skims): "sov_cost_by_income_2": "skims.get('HOV3_TIME', default=999)", }, ) - result = s2._load(tree, as_dataframe=True) - - assert s2.flow_hash != ss.flow_hash - + result = flow4._load(tree, as_dataframe=True) + assert flow4.flow_hash != flow1.flow_hash dataframe_regression.check(result) From 5c6aecb1ee8900de31288b47311d8b1e21d66bd1 Mon Sep 17 00:00:00 2001 From: Jeffrey Newman Date: Thu, 12 Jan 2023 21:57:25 -0600 Subject: [PATCH 3/7] Bugfix for df.get (#34) * repair and test subspace fallbacks * allow error on graphviz * find "get" when inside another function * fix root_dims --- sharrow/flows.py | 4 ++-- sharrow/relationships.py | 4 +++- sharrow/tests/test_relationships.py | 17 +++++++++++++++++ 3 files changed, 22 insertions(+), 3 deletions(-) diff --git a/sharrow/flows.py b/sharrow/flows.py index 382eae0..dbadacb 100644 --- a/sharrow/flows.py +++ b/sharrow/flows.py @@ -141,7 +141,7 @@ def filter_name_tokens(expr, matchable_names=None): return name_tokens, arg_tokens -class ExtractOptionalGetTokens(ast.NodeTransformer): +class ExtractOptionalGetTokens(ast.NodeVisitor): def __init__(self, from_names): self.optional_get_tokens = set() self.required_get_tokens = set() @@ -178,7 +178,7 @@ def visit_Call(self, node): raise ValueError( f"{node.func.value.id}.get with more than 2 positional arguments" ) - return node + self.generic_visit(node) def check(self, node): if isinstance(node, str): diff --git a/sharrow/relationships.py b/sharrow/relationships.py index 50d49aa..15e87c6 100644 --- a/sharrow/relationships.py +++ b/sharrow/relationships.py @@ -366,7 +366,9 @@ def shape(self): def root_dims(self): from .flows import presorted - return tuple(presorted(self.root_dataset, self.dim_order, self.dim_exclude)) + return tuple( + presorted(self.root_dataset.dims, self.dim_order, self.dim_exclude) + ) def __shallow_copy_extras(self): return dict( diff --git a/sharrow/tests/test_relationships.py b/sharrow/tests/test_relationships.py index 29c064d..415fcbc 100644 --- a/sharrow/tests/test_relationships.py +++ b/sharrow/tests/test_relationships.py @@ -879,6 +879,23 @@ def test_get(dataframe_regression, households, skims): assert flow4.flow_hash != flow1.flow_hash dataframe_regression.check(result) + # test get when inside another function + flow5 = tree.setup_flow( + { + "income": "np.power(base.get('income', default=0) + df.get('missing_one', 0), 1)", + "sov_time_by_income": "skims.SOV_TIME/np.power(base.get('income', default=0), 1)", + "missing_data": "np.where(np.isnan(df.get('missing_data', default=1)), 0, df.get('missing_data', default=-1))", + "missing_skim": "(np.where(np.isnan(df.get('num_escortees', np.nan)), -2 , df.get('num_escortees', np.nan)))", + "sov_time_by_income_2": "skims.get('SOV_TIME', default=0)/base.income", + "sov_cost_by_income_2": "skims.get('HOV3_TIME', default=999)", + }, + ) + result = flow5._load(tree, as_dataframe=True) + assert "__skims__HOV3_TIME:True" in flow5._optional_get_tokens + assert "__df__missing_data:False" in flow5._optional_get_tokens + assert "__df__num_escortees:False" in flow5._optional_get_tokens + dataframe_regression.check(result) + def test_get_native(): data = example_data.get_data() From 11cc7f149feb848cfce9a63f8f49fcab57041171 Mon Sep 17 00:00:00 2001 From: Jeffrey Newman Date: Sat, 15 Apr 2023 14:33:50 -0500 Subject: [PATCH 4/7] pandas.CategoricalDtype <-> digital_encoding (#35) * DataStore (#1) * repair and test subspace fallbacks * allow error on graphviz * find "get" when inside another function * fix root_dims * datastore class * digital_encoding -> cat * ruff * fix name * some docstrings * pyupgrade * tar_zst * one remove-cell tag * fix cell tags * pd categorical in docs * improve memory on Dataset.iat --- .github/workflows/run-tests.yml | 8 +- .pre-commit-config.yaml | 11 +- docs/_script/hide_test_cells.py | 8 +- docs/walkthrough/encoding.ipynb | 207 +++++++++++- docs/walkthrough/two-dim.ipynb | 15 +- envs/development.yml | 2 +- envs/testing.yml | 2 +- pyproject.toml | 9 + sharrow/__init__.py | 22 ++ sharrow/aster.py | 67 ++-- sharrow/categorical.py | 40 +++ sharrow/dataset.py | 324 +++++++++++++++---- sharrow/datastore.py | 482 ++++++++++++++++++++++++++++ sharrow/digital_encoding.py | 43 ++- sharrow/filewrite.py | 2 +- sharrow/flows.py | 212 ++++++++++-- sharrow/nested_logit.py | 2 +- sharrow/relationships.py | 269 +++++++++++----- sharrow/selectors.py | 35 +- sharrow/shared_memory.py | 16 +- sharrow/table.py | 17 +- sharrow/tests/conftest.py | 53 +++ sharrow/tests/test_categorical.py | 99 ++++++ sharrow/tests/test_datasets.py | 30 ++ sharrow/tests/test_datastore.py | 131 ++++++++ sharrow/tests/test_relationships.py | 15 +- sharrow/utils/__init__.py | 0 sharrow/utils/tar_zst.py | 104 ++++++ 28 files changed, 1940 insertions(+), 285 deletions(-) create mode 100644 sharrow/categorical.py create mode 100644 sharrow/datastore.py create mode 100644 sharrow/tests/conftest.py create mode 100644 sharrow/tests/test_categorical.py create mode 100644 sharrow/tests/test_datastore.py create mode 100644 sharrow/utils/__init__.py create mode 100644 sharrow/utils/tar_zst.py diff --git a/.github/workflows/run-tests.yml b/.github/workflows/run-tests.yml index 7ec36fc..79a20ba 100644 --- a/.github/workflows/run-tests.yml +++ b/.github/workflows/run-tests.yml @@ -46,12 +46,12 @@ jobs: run: | conda info -a conda list - - name: Lint with flake8 + - name: Lint with Ruff run: | # stop the build if there are Python syntax errors or undefined names - flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + ruff check . --select=E9,F63,F7,F82 --statistics + # exit-zero treats all errors as warnings. + ruff check . --exit-zero --statistics - name: Test with pytest run: | python -m pytest diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 333916f..835834c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -13,6 +13,12 @@ repos: hooks: - id: nbstripout +- repo: https://github.com/charliermarsh/ruff-pre-commit + rev: v0.0.257 + hooks: + - id: ruff + args: [--fix, --exit-non-zero-on-fix] + - repo: https://github.com/pycqa/isort rev: 5.10.1 hooks: @@ -23,8 +29,3 @@ repos: rev: 22.10.0 hooks: - id: black - -- repo: https://github.com/PyCQA/flake8 - rev: 5.0.4 - hooks: - - id: flake8 diff --git a/docs/_script/hide_test_cells.py b/docs/_script/hide_test_cells.py index 0a4b5c6..a8e6bf3 100644 --- a/docs/_script/hide_test_cells.py +++ b/docs/_script/hide_test_cells.py @@ -11,10 +11,10 @@ # Text to look for in adding tags text_search_dict = { - "# TEST": "remove_cell", # Remove the whole cell - "# HIDDEN": "remove_cell", # Remove the whole cell - "# NO CODE": "remove_input", # Remove only the input - "# HIDE CODE": "hide_input", # Hide the input w/ a button to show + "# TEST": "remove-cell", # Remove the whole cell + "# HIDDEN": "remove-cell", # Remove the whole cell + "# NO CODE": "remove-input", # Remove only the input + "# HIDE CODE": "hide-input", # Hide the input w/ a button to show } # Search through each notebook and look for th text, add a tag if necessary diff --git a/docs/walkthrough/encoding.ipynb b/docs/walkthrough/encoding.ipynb index f8f3e2d..7f07159 100644 --- a/docs/walkthrough/encoding.ipynb +++ b/docs/walkthrough/encoding.ipynb @@ -16,7 +16,7 @@ "id": "f17c8818", "metadata": { "tags": [ - "remove_cell" + "remove-cell" ] }, "outputs": [], @@ -30,7 +30,9 @@ "cell_type": "code", "execution_count": null, "id": "d4e7246c", - "metadata": {}, + "metadata": { + "tags": [] + }, "outputs": [], "source": [ "import numpy as np\n", @@ -217,7 +219,7 @@ "id": "2ad591bb", "metadata": { "tags": [ - "remove_cell" + "remove-cell" ] }, "outputs": [], @@ -296,7 +298,7 @@ "id": "bd549b5e", "metadata": { "tags": [ - "remove_cell" + "remove-cell" ] }, "outputs": [], @@ -377,7 +379,7 @@ "id": "7d74e53e", "metadata": { "tags": [ - "remove_cell" + "remove-cell" ] }, "outputs": [], @@ -477,7 +479,7 @@ "id": "a016d30f", "metadata": { "tags": [ - "remove_cell" + "remove-cell" ] }, "outputs": [], @@ -525,7 +527,7 @@ "id": "28afb335", "metadata": { "tags": [ - "remove_cell" + "remove-cell" ] }, "outputs": [], @@ -690,6 +692,195 @@ " _name='WLK_LOC_WLK_FAR'\n", ").to_series() == [0,152,474]).all()" ] + }, + { + "cell_type": "markdown", + "id": "cb219dc3-dd66-44cd-a7c5-2a1da4bc1467", + "metadata": { + "tags": [] + }, + "source": [ + "# Pandas Categorical Dtype\n", + "\n", + "Dictionary encoding is very similar to the approach used for the pandas Categorical dtype, and\n", + "can be used to achieve some of the efficiencies of categorical data, even though xarray lacks\n", + "a formal native categorical data representation. Sharrow's `construct` function for creating\n", + "Dataset objects will automatically use dictionary encoding for \"category\" data. \n", + "\n", + "To demonstrate, we'll load some household data and create a categorical data column." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "3b765919-69a4-4fb0-b805-9d3b5fed7897", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "hh = sh.example_data.get_households()\n", + "hh[\"income_grp\"] = pd.cut(hh.income, bins=[-np.inf,30000,60000,np.inf], labels=['Low', \"Mid\", \"High\"])\n", + "hh = hh[[\"income\",\"income_grp\"]]\n", + "hh.head()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "312faa0b-13cf-4649-9835-7a53b5e81a0b", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "hh.info()" + ] + }, + { + "cell_type": "markdown", + "id": "c51a88d2-02b1-4502-9f4b-271fbb126699", + "metadata": {}, + "source": [ + "We'll then create a Dataset using construct." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "cd1c2fd5-59c6-48cb-bd6e-d2f9dde2aa36", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "hh_dataset = sh.dataset.construct(hh[[\"income\",\"income_grp\"]])\n", + "hh_dataset" + ] + }, + { + "cell_type": "markdown", + "id": "033b3629-a16b-47a4-bb18-10af9c7c4f07", + "metadata": {}, + "source": [ + "Note that the \"income\" variable remains an integer as expected, but the \"income_grp\" variable, \n", + "which had been a \"category\" dtype in pandas, is now stored as an `int8`, giving the \n", + "category _index_ of each element (it would be an `int16` or larger if needed, but that's\n", + "not necessary with only 3 categories). The information about the labels for the categories is \n", + "retained not in the data itself but in the `digital_encoding`:" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "369442af-1c69-41eb-b530-ea398d6eac7a", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "hh_dataset[\"income_grp\"].digital_encoding" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "58db6505-1c90-475e-8d91-0e2e89ec0f0e", + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "# TESTING\n", + "assert hh_dataset[\"income_grp\"].dtype == \"int8\"\n", + "assert hh_dataset[\"income_grp\"].digital_encoding.keys() == {'dictionary', 'ordered'}\n", + "assert all(hh_dataset[\"income_grp\"].digital_encoding['dictionary'] == np.array(['Low', 'Mid', 'High'], dtype='=5.7.1 - nbmake diff --git a/envs/testing.yml b/envs/testing.yml index deb0879..76d1928 100644 --- a/envs/testing.yml +++ b/envs/testing.yml @@ -14,7 +14,7 @@ dependencies: - numexpr - sparse - filelock - - flake8 + - ruff # required for testing - pytest - pytest-cov diff --git a/pyproject.toml b/pyproject.toml index c4bee96..dea5508 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -17,6 +17,15 @@ float_to_top = true default_section = "THIRDPARTY" known_first_party = "sharrow" +[tool.ruff] +# Enable flake8-bugbear (`B`) and pyupgrade ('UP') rules. +select = ["E", "F", "B", "UP"] +fix = true +ignore-init-module-imports = true +line-length = 120 +ignore = ["B905"] +target-version = "py39" + [tool.pytest.ini_options] minversion = "6.0" addopts = "-v --nbmake --disable-warnings" diff --git a/sharrow/__init__.py b/sharrow/__init__.py index df6c3b8..03d66a4 100644 --- a/sharrow/__init__.py +++ b/sharrow/__init__.py @@ -3,7 +3,29 @@ from . import dataset, example_data, selectors, shared_memory, sparse from ._infer_version import __version__, __version_tuple__ from .dataset import Dataset +from .datastore import DataStore from .digital_encoding import array_decode, array_encode from .flows import CacheMissWarning, Flow from .relationships import DataTree, Relationship from .table import Table, concat_tables + +__all__ = [ + "__version__", + "__version_tuple__", + "DataArray", + "Dataset", + "DataStore", + "DataTree", + "Relationship", + "Table", + "CacheMissWarning", + "Flow", + "example_data", + "array_decode", + "array_encode", + "concat_tables", + "dataset", + "selectors", + "shared_memory", + "sparse", +] diff --git a/sharrow/aster.py b/sharrow/aster.py index ded9c06..c85f0f9 100755 --- a/sharrow/aster.py +++ b/sharrow/aster.py @@ -1,7 +1,6 @@ import ast import io import logging -import sys import tokenize try: @@ -9,7 +8,9 @@ except ImportError: from astunparse import unparse as _unparse - unparse = lambda *args: _unparse(*args).strip("\n") + def unparse(*args): + return _unparse(*args).strip("\n") + logger = logging.getLogger("sharrow.aster") @@ -23,22 +24,21 @@ def unparse_(*args): raise -if sys.version_info >= (3, 8): - ast_Constant_Type = ast.Constant - ast_String_value = lambda x: x.value if isinstance(x, ast.Str) else x - ast_TupleIndex_Type = ast.Tuple - ast_Index_Value = lambda x: x - ast_Constant = ast.Constant -else: - ast_Constant_Type = (ast.Index, ast.Constant, ast.Str, ast.Num) - ast_String_value = ( - lambda x: x.s - if isinstance(x, ast.Str) - else (ast_String_value(x.value) if isinstance(x, ast.Index) else x) - ) - ast_TupleIndex_Type = (ast.Index, ast.Tuple) - ast_Index_Value = lambda x: x.value if isinstance(x, ast.Index) else x - ast_Constant = lambda x: ast.Constant(x, kind=None) +ast_Constant_Type = ast.Constant + + +def ast_String_value(x): + return x.value if isinstance(x, ast.Str) else x + + +ast_TupleIndex_Type = ast.Tuple + + +def ast_Index_Value(x): + return x + + +ast_Constant = ast.Constant def _isNone(c): @@ -69,7 +69,6 @@ def extract_names(command): def extract_names_2(command): - if not isinstance(command, str): return set(), dict(), dict() @@ -364,7 +363,8 @@ def log_event(self, tag, node1=None, node2=None): except: # noqa: E722 unparsed = f"{type(node1)} not unparseable" logger.debug( - f"RewriteForNumba({self.spacename}|{self.rawalias}).{tag} [{type(node1).__name__}]= {unparsed}", + f"RewriteForNumba({self.spacename}|{self.rawalias}).{tag} " + f"[{type(node1).__name__}]= {unparsed}", ) else: try: @@ -376,7 +376,9 @@ def log_event(self, tag, node1=None, node2=None): except: # noqa: E722 unparsed2 = f"{type(node2).__name__} not unparseable" logger.debug( - f"RewriteForNumba({self.spacename}|{self.rawalias}).{tag} [{type(node1).__name__},{type(node2).__name__}]= {unparsed1} => {unparsed2}", + f"RewriteForNumba({self.spacename}|{self.rawalias}).{tag} " + f"[{type(node1).__name__},{type(node2).__name__}]= " + f"{unparsed1} => {unparsed2}", ) def generic_visit(self, node): @@ -402,8 +404,8 @@ def _replacement( topname == pref_topname and not self.swallow_errors ): raise KeyError(f"{topname}..{attr}") - # we originally raised a KeyError here regardless, but what if we just - # give back the original node, and see if other spaces, + # we originally raised a KeyError here regardless, but what if + # we just give back the original node, and see if other spaces, # possibly fallback spaces, might work? If nothing works then # it will still eventually error out when compiling? # The swallow errors option allows us to continue processing @@ -448,16 +450,9 @@ def _maybe_transpose_first_two_args(_slice): if isinstance(n, int): elts.append(ast.Name(id=f"_arg{n:02}", ctx=ast.Load())) elif isinstance(n, dict): - if sys.version_info >= (3, 8): - elts.append( - ast.Constant(n=n[missing_dim_value], ctx=ast.Load()) - ) - else: - elts.append( - ast.Constant( - n[missing_dim_value], kind=None, ctx=ast.Load() - ) - ) + elts.append( + ast.Constant(n=n[missing_dim_value], ctx=ast.Load()) + ) else: elts.append(n) logger.debug(f"ELT {unparse_(elts[-1])}") @@ -489,7 +484,6 @@ def _maybe_transpose_first_two_args(_slice): digital_encoding = self.digital_encodings.get(attr, None) if digital_encoding is not None: - dictionary = digital_encoding.get("dictionary", None) offset_source = digital_encoding.get("offset_source", None) if dictionary is not None: @@ -606,7 +600,8 @@ def visit_Subscript(self, node): result, ) return result - # for XXX[YYY,ZZZ], XXX is a space name and YYY is a literal value and ZZZ is a literal value: skims['SOV_TIME','MD'] + # for XXX[YYY,ZZZ], XXX is a space name and YYY is a literal value and + # ZZZ is a literal value: skims['SOV_TIME','MD'] if ( node.value.id == self.spacename and isinstance(ast_Index_Value(node.slice), ast.Tuple) @@ -726,7 +721,6 @@ def visit_BinOp(self, node): if self.bool_wrapping and isinstance( node.op, (ast.BitAnd, ast.BitOr, ast.BitXor) ): - result = ast.BinOp( left=bool_wrap(left), op=node.op, @@ -743,7 +737,6 @@ def visit_BinOp(self, node): return result def visit_Call(self, node): - result = None # implement ActivitySim's "reverse" skims if ( diff --git a/sharrow/categorical.py b/sharrow/categorical.py new file mode 100644 index 0000000..30e5832 --- /dev/null +++ b/sharrow/categorical.py @@ -0,0 +1,40 @@ +from __future__ import annotations + +import numpy as np +import xarray as xr + + +class ArrayIsNotCategoricalError(TypeError): + """The array is not an encoded categorical array.""" + + +@xr.register_dataarray_accessor("cat") +class _Categorical: + """ + Accessor for pseudo-categorical arrays. + """ + + __slots__ = ("dataarray",) + + def __init__(self, dataarray: xr.DataArray): + self.dataarray = dataarray + + @property + def categories(self): + try: + return self.dataarray.attrs["digital_encoding"]["dictionary"] + except KeyError: + raise ArrayIsNotCategoricalError() from None + + @property + def ordered(self): + return self.dataarray.attrs["digital_encoding"].get("ordered", True) + + def category_array(self) -> np.ndarray: + arr = np.asarray(self.categories) + if arr.dtype.kind == "O": + arr = arr.astype(str) + return arr + + def is_categorical(self) -> bool: + return "dictionary" in self.dataarray.attrs.get("digital_encoding", {}) diff --git a/sharrow/dataset.py b/sharrow/dataset.py index 68be2be..68d02e9 100755 --- a/sharrow/dataset.py +++ b/sharrow/dataset.py @@ -1,9 +1,12 @@ +from __future__ import annotations + import ast import base64 import hashlib import logging import re -from typing import Any, Hashable, Mapping, Sequence +from collections.abc import Hashable, Mapping, Sequence +from typing import Any import numpy as np import pandas as pd @@ -13,6 +16,7 @@ from .accessors import register_dataset_method from .aster import extract_all_name_tokens +from .categorical import _Categorical # noqa from .table import Table logger = logging.getLogger("sharrow") @@ -92,21 +96,21 @@ def construct(source): if isinstance(source, pd.DataFrame): source = dataset_from_dataframe_fast(source) # xarray default can be slow elif isinstance(source, (Table, pa.Table)): - source = xr.Dataset.from_table(source) - elif isinstance(source, (pa.Table)): - source = xr.Dataset.from_table(source) + source = from_table(source) elif isinstance(source, xr.Dataset): pass # don't do the superclass things elif isinstance(source, Sequence) and all(isinstance(i, str) for i in source): - source = xr.Dataset.from_table(pa.table({i: [] for i in source})) + source = from_table(pa.table({i: [] for i in source})) else: source = xr.Dataset(source) return source def dataset_from_dataframe_fast( - dataframe: pd.DataFrame, sparse: bool = False -) -> "Dataset": + dataframe: pd.DataFrame, + sparse: bool = False, + preserve_cat: bool = True, +) -> Dataset: """Convert a pandas.DataFrame into an xarray.Dataset Each column will be converted into an independent variable in the @@ -175,11 +179,26 @@ def dataset_from_dataframe_fast( index_name = idx.name if idx.name is not None else "index" # Cast to a NumPy array first, in case the Series is a pandas Extension # array (which doesn't have a valid NumPy dtype) - arrays = { - name: ([index_name], np.asarray(dataframe[name].values)) - for name in dataframe.columns - if name != index_name - } + arrays = {} + for name in dataframe.columns: + if name != index_name: + if dataframe[name].dtype == "category" and preserve_cat: + cat = dataframe[name].cat + categories = np.asarray(cat.categories) + if categories.dtype.kind == "O": + categories = categories.astype(str) + arrays[name] = ( + [index_name], + np.asarray(cat.codes), + { + "digital_encoding": { + "dictionary": categories, + "ordered": cat.ordered, + } + }, + ) + else: + arrays[name] = ([index_name], np.asarray(dataframe[name].values)) return Dataset(arrays, coords={index_name: (index_name, dataframe.index.values)}) @@ -197,7 +216,8 @@ def from_table( Table from which to use data and indices. index_name : str, default 'index' This name will be given to the default dimension index, if - none is given. Ignored if `index` is given explicitly. + none is given. Ignored if `index` is given explicitly and + it already has a name. index : Index-like, optional Use this index instead of a default RangeIndex. @@ -218,10 +238,21 @@ def from_table( raise ValueError( "cannot attach a non-unique MultiIndex and convert into xarray" ) - arrays = [ - (tbl.column_names[n], np.asarray(tbl.column(n))) - for n in range(len(tbl.column_names)) - ] + arrays = [] + metadata = {} + for n in range(len(tbl.column_names)): + c = tbl.column(n) + if isinstance(c.type, pa.DictionaryType): + cc = c.combine_chunks() + arrays.append((tbl.column_names[n], np.asarray(cc.indices))) + metadata[tbl.column_names[n]] = { + "digital_encoding": { + "dictionary": cc.dictionary, + "ordered": cc.type.ordered, + } + } + else: + arrays.append((tbl.column_names[n], np.asarray(c))) result = xr.Dataset() if isinstance(index, pd.MultiIndex): dims = tuple( @@ -231,11 +262,17 @@ def from_table( for dim, lev in zip(dims, index.levels): result[dim] = (dim, lev) else: - index_name = index.name if index.name is not None else "index" + try: + if index.name is not None: + index_name = index.name + except AttributeError: + pass dims = (index_name,) result[index_name] = (dims, index) result._set_numpy_data_from_dataframe(index, arrays, dims) + for k, v in metadata.items(): + result[k].attrs.update(v) return result @@ -627,27 +664,11 @@ def from_zarr_with_attr(*args, **kwargs): for k in obj: attrs = {} for aname, avalue in obj[k].attrs.items(): - if ( - isinstance(avalue, str) - and avalue.startswith(" {") - and avalue.endswith("} ") - ): - avalue = ast.literal_eval(avalue[1:-1]) - if isinstance(avalue, str) and avalue == " < None > ": - avalue = None - attrs[aname] = avalue + attrs[aname] = _from_evalable_string(avalue) obj[k] = obj[k].assign_attrs(attrs) attrs = {} for aname, avalue in obj.attrs.items(): - if ( - isinstance(avalue, str) - and avalue.startswith(" {") - and avalue.endswith("} ") - ): - avalue = ast.literal_eval(avalue[1:-1]) - if isinstance(avalue, str) and avalue == " < None > ": - avalue = None - attrs[aname] = avalue + attrs[aname] = _from_evalable_string(avalue) obj = obj.assign_attrs(attrs) return obj @@ -673,7 +694,7 @@ class _SingleDim: __slots__ = ("dataset", "dim_name") - def __init__(self, dataset: "Dataset"): + def __init__(self, dataset: Dataset): self.dataset = dataset if len(self.dataset.dims) != 1: raise ValueError("single_dim implies a single dimension dataset") @@ -691,10 +712,122 @@ def index(self): def size(self): return self.dataset.dims[self.dim_name] - def to_pyarrow(self): - return pa.Table.from_pydict( - {k: pa.array(v.to_numpy()) for k, v in self.dataset.variables.items()} + def _to_pydict(self): + columns = [k for k in self.dataset.variables if k != self.dim_name] + data = [] + for k in columns: + a = self.dataset._variables[k] + if ( + "digital_encoding" in a.attrs + and "dictionary" in a.attrs["digital_encoding"] + ): + de = a.attrs["digital_encoding"] + data.append( + pd.Categorical.from_codes( + a.values, + de["dictionary"], + de.get("ordered"), + ) + ) + else: + data.append(a.values) + return dict(zip(columns, data)) + + def to_pyarrow(self) -> pa.Table: + columns = [k for k in self.dataset.variables if k != self.dim_name] + data = [] + for k in columns: + a = self.dataset._variables[k] + if ( + "digital_encoding" in a.attrs + and "dictionary" in a.attrs["digital_encoding"] + ): + de = a.attrs["digital_encoding"] + data.append( + pa.DictionaryArray.from_arrays( + a.values, + de["dictionary"], + ordered=de.get("ordered", False), + ) + ) + else: + data.append(pa.array(a.values)) + content = dict(zip(columns, data)) + content[self.dim_name] = self.index + return pa.Table.from_pydict(content) + + def to_parquet(self, filename): + import pyarrow.parquet as pq + + t = self.to_pyarrow() + pq.write_table(t, filename) + + def to_pandas(self) -> pd.DataFrame: + """ + Convert this dataset into a pandas DataFrame. + + The resulting DataFrame is always a copy of the data in the dataset. + + Returns + ------- + pandas.DataFrame + """ + return pd.DataFrame(self._to_pydict(), index=self.index, copy=True) + + def eval( + self, + expr: str, + parser: str = "pandas", + engine: str | None = None, + local_dict=None, + global_dict=None, + ): + """ + Evaluate a Python expression as a string using various backends. + + Parameters + ---------- + expr : str + The expression to evaluate. This string cannot contain any Python + `statements + `__, + only Python `expressions + `__. + parser : {'pandas', 'python'}, default 'pandas' + The parser to use to construct the syntax tree from the expression. The + default of ``'pandas'`` parses code slightly different than standard + Python. Alternatively, you can parse an expression using the + ``'python'`` parser to retain strict Python semantics. See the + :ref:`enhancing performance ` documentation for + more details. + engine : {'python', 'numexpr'}, default 'numexpr' + The engine used to evaluate the expression. Supported engines are + - None : tries to use ``numexpr``, falls back to ``python`` + - ``'numexpr'`` : This default engine evaluates pandas objects using + numexpr for large speed ups in complex expressions with large frames. + - ``'python'`` : Performs operations as if you had ``eval``'d in top + level python. This engine is generally not that useful. + local_dict : dict or None, optional + A dictionary of local variables, taken from locals() by default. + global_dict : dict or None, optional + A dictionary of global variables, taken from globals() by default. + + Returns + ------- + DataArray or numeric scalar + """ + result = pd.eval( + expr, + parser=parser, + engine=engine, + local_dict=local_dict, + global_dict=global_dict, + resolvers=[self.dataset], ) + if result.size == self.size: + return DataArray(np.asarray(result), coords=self.dataset.coords) + else: + return result @xr.register_dataarray_accessor("single_dim") @@ -705,7 +838,7 @@ class _SingleDimArray: __slots__ = ("dataarray", "dim_name") - def __init__(self, dataarray: "DataArray"): + def __init__(self, dataarray: DataArray): self.dataarray = dataarray if len(self.dataarray.dims) != 1: raise ValueError("single_dim implies a single dimension dataset") @@ -725,6 +858,39 @@ def rename(self, name: str) -> DataArray: return self.dataarray return self.dataarray.rename({self.dim_name: name}) + def to_pandas(self) -> pd.Series: + """ + Convert this array into a pandas Series. + + If this array is categorical (i.e. with a simple dictionary-based + digital encoding) then the result will be a Series with categorical dtype. + + The DataArray's `name` attribute is preserved in the result. + """ + if self.dataarray.cat.is_categorical(): + return pd.Series( + pd.Categorical.from_codes( + self.dataarray, + self.dataarray.cat.categories, + self.dataarray.cat.ordered, + ), + index=self.index, + name=self.dataarray.name, + ) + else: + result = self.dataarray.to_pandas() + if self.dataarray.name: + result = result.rename(self.dataarray.name) + return result + + def to_pyarrow(self): + if self.dataarray.cat.is_categorical(): + return pa.DictionaryArray.from_arrays( + self.dataarray.data, self.dataarray.cat.categories + ) + else: + return pa.array(self.dataarray.data) + @xr.register_dataset_accessor("iloc") class _iLocIndexer: @@ -742,10 +908,10 @@ class _iLocIndexer: __slots__ = ("dataset",) - def __init__(self, dataset: "Dataset"): + def __init__(self, dataset: Dataset): self.dataset = dataset - def __getitem__(self, key: Mapping[Hashable, Any]) -> "Dataset": + def __getitem__(self, key: Mapping[Hashable, Any]) -> Dataset: if not is_dict_like(key): if len(self.dataset.dims) == 1: dim_name = self.dataset.dims.__iter__().__next__() @@ -858,6 +1024,58 @@ def to_zarr_zip(self, *args, **kwargs): return super().to_zarr(*args, **kwargs) +def _to_ast_literal(x): + if isinstance(x, dict): + return ( + "{" + + ", ".join( + f"{_to_ast_literal(k)}: {_to_ast_literal(v)}" for k, v in x.items() + ) + + "}" + ) + elif isinstance(x, list): + return "[" + ", ".join(_to_ast_literal(i) for i in x) + "]" + elif isinstance(x, tuple): + return "(" + ", ".join(_to_ast_literal(i) for i in x) + ")" + elif isinstance(x, pd.Index): + return _to_ast_literal(x.to_list()) + elif isinstance(x, np.ndarray): + return _to_ast_literal(list(x)) + else: + return repr(x) + + +def _to_evalable_string(x): + if x is None: + return " < None > " + elif x is True: + return " < True > " + elif x is False: + return " < False > " + else: + return f" {_to_ast_literal(x)} " + + +def _from_evalable_string(x): + if isinstance(x, str): + # if x.startswith(" {") and x.endswith("} "): + # return ast.literal_eval(x[1:-1]) + if x == " < None > ": + return None + if x == " < True > ": + return True + if x == " < False > ": + return False + if x.startswith(" ") and x.endswith(" "): + try: + return ast.literal_eval(x.strip(" ")) + except Exception: + print(x) + raise + else: + return x + + @register_dataset_method def to_zarr_with_attr(self, *args, **kwargs): """ @@ -938,19 +1156,17 @@ def to_zarr_with_attr(self, *args, **kwargs): for k in self: attrs = {} for aname, avalue in self[k].attrs.items(): - if isinstance(avalue, dict): - avalue = f" {avalue!r} " - if avalue is None: - avalue = " < None > " - attrs[aname] = avalue + attrs[aname] = _to_evalable_string(avalue) obj[k] = self[k].assign_attrs(attrs) + if hasattr(self, "coords"): + for k in self.coords: + attrs = {} + for aname, avalue in self.coords[k].attrs.items(): + attrs[aname] = _to_evalable_string(avalue) + obj.coords[k] = self.coords[k].assign_attrs(attrs) attrs = {} for aname, avalue in self.attrs.items(): - if isinstance(avalue, dict): - avalue = f" {avalue!r} " - if avalue is None: - avalue = " < None > " - attrs[aname] = avalue + attrs[aname] = _to_evalable_string(avalue) obj = obj.assign_attrs(attrs) return obj.to_zarr(*args, **kwargs) @@ -1088,7 +1304,7 @@ def from_named_objects(*args): try: name = a.name except AttributeError: - raise ValueError(f"argument {n} has no name") + raise ValueError(f"argument {n} has no name") from None if name is None: raise ValueError(f"the name for argument {n} is None") objs[name] = a diff --git a/sharrow/datastore.py b/sharrow/datastore.py new file mode 100644 index 0000000..4be79df --- /dev/null +++ b/sharrow/datastore.py @@ -0,0 +1,482 @@ +from __future__ import annotations + +import datetime +import os +import shutil +from collections.abc import Collection +from pathlib import Path + +import pandas as pd +import xarray as xr +import yaml + +from .dataset import construct, from_zarr_with_attr +from .relationships import DataTree, Relationship + + +def timestamp(): + return datetime.datetime.now(datetime.timezone.utc).astimezone().isoformat() + + +class ReadOnlyError(ValueError): + """This object is read-only.""" + + +def _read_parquet(filename, index_col=None) -> xr.Dataset: + import pyarrow.parquet as pq + + from sharrow.dataset import from_table + + content = pq.read_table(filename) + if index_col is not None: + index = content.column(index_col) + content = content.drop([index_col]) + else: + index = None + x = from_table(content, index=index, index_name=index_col or "index") + return x + + +class DataStore: + metadata_filename: str = "metadata.yaml" + checkpoint_subdir: str = "checkpoints" + LATEST = "_" + _BY_OFFSET = "digitizedOffset" + + def __init__(self, directory: Path | None, mode="a", storage_format: str = "zarr"): + self._directory = Path(directory) if directory else directory + self._mode = mode + self._checkpoints = {} + self._checkpoint_order = [] + self._tree = DataTree(root_node_name=False) + self._keep_digitized = False + assert storage_format in {"zarr", "parquet", "hdf5"} + self._storage_format = storage_format + try: + self.read_metadata() + except FileNotFoundError: + pass + + @property + def directory(self) -> Path: + if self._directory is None: + raise NotADirectoryError("no directory set") + return self._directory + + def __setitem__(self, key: str, value: xr.Dataset | pd.DataFrame): + assert isinstance(key, str) + if self._mode == "r": + raise ReadOnlyError + if isinstance(value, xr.Dataset): + self._set_dataset(key, value) + elif isinstance(value, pd.DataFrame): + self._set_dataset(key, construct(value)) + else: + raise TypeError(f"cannot put {type(value)}") + + def __getitem__(self, key: str): + assert isinstance(key, str) + return self.get_dataset(key) + + def clone(self, mode="a"): + """ + Create a clone of this DataStore. + + The clone has the same active datasets as the original (and the data + shares the same memory) but it does not retain the checkpoint metadata + and is not connected to the same checkpoint store. + + Returns + ------- + DataStore + """ + duplicate = self.__class__(None, mode=mode) + duplicate._tree = self._tree + return duplicate + + def _set_dataset( + self, + name: str, + data: xr.Dataset, + last_checkpoint: str = None, + ) -> None: + if self._mode == "r": + raise ReadOnlyError + data_vars = {} + coords = {} + for k, v in data.coords.items(): + coords[k] = v.assign_attrs(last_checkpoint=last_checkpoint) + for k, v in data.items(): + if k in coords: + continue + data_vars[k] = v.assign_attrs(last_checkpoint=last_checkpoint) + data = xr.Dataset(data_vars=data_vars, coords=coords, attrs=data.attrs) + self._tree.add_dataset(name, data) + + def _update_dataset( + self, + name: str, + data: xr.Dataset, + last_checkpoint=None, + ) -> xr.Dataset: + if self._mode == "r": + raise ReadOnlyError + if not isinstance(data, xr.Dataset): + raise TypeError(type(data)) + partial_update = self._tree.get_subspace(name, default_empty=True) + for k, v in data.items(): + if k in data.coords: + continue + assert v.name == k + partial_update = self._update_dataarray( + name, v, last_checkpoint, partial_update=partial_update + ) + for k, v in data.coords.items(): + assert v.name == k + partial_update = self._update_dataarray( + name, v, last_checkpoint, as_coord=True, partial_update=partial_update + ) + return partial_update + + def _update_dataarray( + self, + name: str, + data: xr.DataArray, + last_checkpoint=None, + as_coord=False, + partial_update=None, + ) -> xr.Dataset: + if self._mode == "r": + raise ReadOnlyError + if partial_update is None: + base_data = self._tree.get_subspace(name, default_empty=True) + else: + base_data = partial_update + if isinstance(data, xr.DataArray): + if as_coord: + updated_dataset = base_data.assign_coords( + {data.name: data.assign_attrs(last_checkpoint=last_checkpoint)} + ) + else: + updated_dataset = base_data.assign( + {data.name: data.assign_attrs(last_checkpoint=last_checkpoint)} + ) + self._tree = self._tree.replace_datasets( + {name: updated_dataset}, redigitize=self._keep_digitized + ) + return updated_dataset + else: + raise TypeError(type(data)) + + def update( + self, + name: str, + obj: xr.Dataset | xr.DataArray, + last_checkpoint: str = None, + ) -> None: + """ + Make a partial update of an existing named dataset. + + Parameters + ---------- + name : str + obj : Dataset or DataArray + last_checkpoint : str or None + Set the "last_checkpoint" attribute on all updated variables to this + value. Users should typically leave this as "None", which flags the + checkpointing algorithm to write this data to disk the next time a + checkpoint is written. + """ + if isinstance(obj, xr.Dataset): + self._update_dataset(name, obj, last_checkpoint=last_checkpoint) + elif isinstance(obj, xr.DataArray): + self._update_dataarray(name, obj, last_checkpoint=last_checkpoint) + else: + raise TypeError(type(obj)) + + def set_data( + self, + name: str, + data: xr.Dataset | pd.DataFrame, + relationships: str | Relationship | Collection[str | Relationship] = None, + ) -> None: + """ + Set the content of a named dataset. + + This completely overwrites any existing data with the same name. + + Parameters + ---------- + name : str + data : Dataset or DataFrame + relationships : str or Relationship or list thereof + """ + self.__setitem__(name, data) + if relationships is not None: + if isinstance(relationships, (str, Relationship)): + relationships = [relationships] + for r in relationships: + self._tree.add_relationship(r) + + def get_dataset(self, name: str, columns: Collection[str] = None) -> xr.Dataset: + """ + Retrieve some or all of a named dataset. + + Parameters + ---------- + name : str + columns : Collection[str], optional + Get only these variables of the dataset. + """ + if columns is None: + return self._tree.get_subspace(name) + else: + return xr.Dataset({c: self._tree[f"{name}.{c}"] for c in columns}) + + def get_dataframe(self, name: str, columns: Collection[str] = None) -> pd.DataFrame: + """ + Retrieve some or all of a named dataset, as a pandas DataFrame. + + This completely overwrites any existing data with the same name. + + Parameters + ---------- + name : str + columns : Collection[str], optional + Get only these variables of the dataset. + """ + dataset = self.get_dataset(name, columns) + return dataset.single_dim.to_pandas() + + def _to_be_checkpointed(self) -> dict[str, xr.Dataset]: + result = {} + for table_name, table_data in self._tree.subspaces_iter(): + # any data elements that were created without a + # last_checkpoint attr get one now + for _k, v in table_data.variables.items(): + if "last_checkpoint" not in v.attrs: + v.attrs["last_checkpoint"] = None + # collect everything not checkpointed + uncheckpointed = table_data.filter_by_attrs(last_checkpoint=None) + if uncheckpointed: + result[table_name] = uncheckpointed + return result + + def _zarr_subdir(self, table_name, checkpoint_name): + return self.directory.joinpath(table_name, checkpoint_name).with_suffix(".zarr") + + def _parquet_name(self, table_name, checkpoint_name): + return self.directory.joinpath(table_name, checkpoint_name).with_suffix( + ".parquet" + ) + + def make_checkpoint(self, checkpoint_name: str, overwrite: bool = True): + """ + Write data to disk. + + Only new data (since the last time a checkpoint was made) is actually + written out. + + Parameters + ---------- + checkpoint_name : str + overwrite : bool, default True + """ + if self._mode == "r": + raise ReadOnlyError + to_be_checkpointed = self._to_be_checkpointed() + new_checkpoint = { + "timestamp": timestamp(), + "tables": {}, + "relationships": [], + } + # remove checkpoint name from ordered list if it already exists + while checkpoint_name in self._checkpoint_order: + self._checkpoint_order.remove(checkpoint_name) + # add checkpoint name at end ordered list + self._checkpoint_order.append(checkpoint_name) + for table_name, table_data in to_be_checkpointed.items(): + if self._storage_format == "parquet" and len(table_data.dims) == 1: + target = self._parquet_name(table_name, checkpoint_name) + if overwrite and target.is_file(): + os.unlink(target) + target.parent.mkdir(parents=True, exist_ok=True) + table_data.single_dim.to_parquet(str(target)) + elif self._storage_format == "zarr" or ( + self._storage_format == "parquet" and len(table_data.dims) > 1 + ): + # zarr is used if ndim > 1 + target = self._zarr_subdir(table_name, checkpoint_name) + if overwrite and target.is_dir(): + shutil.rmtree(target) + target.mkdir(parents=True, exist_ok=True) + table_data.to_zarr_with_attr(target) + elif self._storage_format == "hdf5": + raise NotImplementedError + else: + raise ValueError( + f"cannot write with storage format {self._storage_format!r}" + ) + self.update(table_name, table_data, last_checkpoint=checkpoint_name) + for table_name, table_data in self._tree.subspaces_iter(): + inventory = {"data_vars": {}, "coords": {}} + for varname, vardata in table_data.items(): + inventory["data_vars"][varname] = { + "last_checkpoint": vardata.attrs.get("last_checkpoint", "MISSING"), + "dtype": str(vardata.dtype), + } + for varname, vardata in table_data.coords.items(): + _cp = checkpoint_name + # coords in every checkpoint with any content + if table_name not in to_be_checkpointed: + _cp = vardata.attrs.get("last_checkpoint", "MISSING") + inventory["coords"][varname] = { + "last_checkpoint": _cp, + "dtype": str(vardata.dtype), + } + new_checkpoint["tables"][table_name] = inventory + for r in self._tree.list_relationships(): + new_checkpoint["relationships"].append(r.to_dict()) + self._checkpoints[checkpoint_name] = new_checkpoint + self._write_checkpoint(checkpoint_name, new_checkpoint) + self._write_metadata() + + def _write_checkpoint(self, name, checkpoint): + if self._mode == "r": + raise ReadOnlyError + checkpoint_metadata_target = self.directory.joinpath( + self.checkpoint_subdir, f"{name}.yaml" + ) + if checkpoint_metadata_target.exists(): + n = 1 + while checkpoint_metadata_target.with_suffix(f".{n}.yaml").exists(): + n += 1 + os.rename( + checkpoint_metadata_target, + checkpoint_metadata_target.with_suffix(f".{n}.yaml"), + ) + checkpoint_metadata_target.parent.mkdir(parents=True, exist_ok=True) + with open(checkpoint_metadata_target, "w") as f: + yaml.safe_dump(checkpoint, f) + + def _write_metadata(self): + if self._mode == "r": + raise ReadOnlyError + metadata_target = self.directory.joinpath(self.metadata_filename) + if metadata_target.exists(): + n = 1 + while metadata_target.with_suffix(f".{n}.yaml").exists(): + n += 1 + os.rename(metadata_target, metadata_target.with_suffix(f".{n}.yaml")) + with open(metadata_target, "w") as f: + metadata = dict( + datastore_format_version=1, + checkpoint_order=self._checkpoint_order, + ) + yaml.safe_dump(metadata, f) + + def read_metadata(self, checkpoints=None): + """ + Read storage metadata + + Parameters + ---------- + checkpoints : str | list[str], optional + Read only these checkpoints. If not provided, only the latest + checkpoint metadata is read. Set to "*" to read all. + """ + with open(self.directory.joinpath(self.metadata_filename)) as f: + metadata = yaml.safe_load(f) + datastore_format_version = metadata.get("datastore_format_version", "missing") + if datastore_format_version == 1: + self._checkpoint_order = metadata["checkpoint_order"] + else: + raise NotImplementedError(f"{datastore_format_version=}") + if checkpoints is None or checkpoints == self.LATEST: + checkpoints = [self._checkpoint_order[-1]] + elif isinstance(checkpoints, str): + if checkpoints == "*": + checkpoints = list(self._checkpoint_order) + else: + checkpoints = [checkpoints] + for c in checkpoints: + with open( + self.directory.joinpath(self.checkpoint_subdir, f"{c}.yaml") + ) as f: + self._checkpoints[c] = yaml.safe_load(f) + + def restore_checkpoint(self, checkpoint_name: str): + if checkpoint_name not in self._checkpoints: + try: + self.read_metadata(checkpoint_name) + except FileNotFoundError: + raise KeyError(checkpoint_name) from None + checkpoint = self._checkpoints[checkpoint_name] + self._tree = DataTree(root_node_name=False) + for table_name, table_def in checkpoint["tables"].items(): + if table_name == "timestamp": + continue + t = xr.Dataset() + opened_targets = {} + coords = table_def.get("coords", {}) + if len(coords) == 1: + index_name = list(coords)[0] + else: + index_name = None + for coord_name, coord_def in coords.items(): + target = self._zarr_subdir(table_name, coord_def["last_checkpoint"]) + if target.exists(): + if target not in opened_targets: + opened_targets[target] = from_zarr_with_attr(target) + else: + # zarr not found, try parquet + target2 = self._parquet_name( + table_name, coord_def["last_checkpoint"] + ) + if target2.exists(): + if target not in opened_targets: + opened_targets[target] = _read_parquet(target2, index_name) + else: + raise FileNotFoundError(target) + t = t.assign_coords({coord_name: opened_targets[target][coord_name]}) + data_vars = table_def.get("data_vars", {}) + for var_name, var_def in data_vars.items(): + if var_def["last_checkpoint"] == "MISSING": + raise ValueError(f"missing checkpoint for {table_name}.{var_name}") + target = self._zarr_subdir(table_name, var_def["last_checkpoint"]) + if target.exists(): + if target not in opened_targets: + opened_targets[target] = from_zarr_with_attr(target) + else: + # zarr not found, try parquet + target2 = self._parquet_name(table_name, var_def["last_checkpoint"]) + if target2.exists(): + if target not in opened_targets: + opened_targets[target] = _read_parquet(target2, index_name) + else: + raise FileNotFoundError(target) + t = t.assign({var_name: opened_targets[target][var_name]}) + self._tree.add_dataset(table_name, t) + for r in checkpoint["relationships"]: + self._tree.add_relationship(Relationship(**r)) + + def add_relationship(self, relationship: str | Relationship): + self._tree.add_relationship(relationship) + + def digitize_relationships(self, redigitize=True): + """ + Convert all label-based relationships into position-based. + + Parameters + ---------- + redigitize : bool, default True + Re-compute position-based relationships from labels, even + if the relationship had previously been digitized. + """ + self._keep_digitized = True + self._tree.digitize_relationships(inplace=True, redigitize=redigitize) + + @property + def relationships_are_digitized(self) -> bool: + """bool : Whether all relationships are digital (by position).""" + return self._tree.relationships_are_digitized diff --git a/sharrow/digital_encoding.py b/sharrow/digital_encoding.py index 7dee25f..e260022 100644 --- a/sharrow/digital_encoding.py +++ b/sharrow/digital_encoding.py @@ -163,24 +163,35 @@ def find_bins(values, final_width=255): def digitize_by_dictionary(arr, bitwidth=8): result = arr.copy() bins = find_bins(arr, final_width=1 << bitwidth) - bin_edges = (bins[1:] - bins[:-1]) / 2 + bins[:-1] try: - arr_data = arr.data - except AttributeError: - pass + bin_edges = (bins[1:] - bins[:-1]) / 2 + bins[:-1] + except TypeError: + # bins are not numeric + bin_map = {x:n for n,x in enumerate(bins)} + u, inv = np.unique(arr.data, return_inverse=True) + result.data = np.array([bin_map.get(x) for x in u])[inv].reshape(arr.shape) + result.attrs["digital_encoding"] = { + "dictionary": bins, + } + return result else: - if isinstance(arr_data, da.Array): - result.data = da.digitize(arr_data, bin_edges).astype(f"uint{bitwidth}") - result.attrs["digital_encoding"] = { - "dictionary": bins, - } - return result - # fall back to numpy digitize - result.data = np.digitize(arr, bin_edges).astype(f"uint{bitwidth}") - result.attrs["digital_encoding"] = { - "dictionary": bins, - } - return result + try: + arr_data = arr.data + except AttributeError: + pass + else: + if isinstance(arr_data, da.Array): + result.data = da.digitize(arr_data, bin_edges).astype(f"uint{bitwidth}") + result.attrs["digital_encoding"] = { + "dictionary": bins, + } + return result + # fall back to numpy digitize + result.data = np.digitize(arr, bin_edges).astype(f"uint{bitwidth}") + result.attrs["digital_encoding"] = { + "dictionary": bins, + } + return result @xr.register_dataset_accessor("digital_encoding") diff --git a/sharrow/filewrite.py b/sharrow/filewrite.py index 872911c..6d9a55f 100644 --- a/sharrow/filewrite.py +++ b/sharrow/filewrite.py @@ -21,7 +21,7 @@ def blacken(code): except Exception as err: import warnings - warnings.warn(f"error in blacken: {err!r}") + warnings.warn(f"error in blacken: {err!r}", stacklevel=2) return code diff --git a/sharrow/flows.py b/sharrow/flows.py index dbadacb..33005a6 100644 --- a/sharrow/flows.py +++ b/sharrow/flows.py @@ -186,8 +186,13 @@ def check(self, node): if isinstance(node, ast.AST): self.visit(node) else: - for i in node: - self.check(i) + try: + node_iter = iter(node) + except TypeError: + pass + else: + for i in node_iter: + self.check(i) return self.optional_get_tokens @@ -203,7 +208,13 @@ def coerce_to_range_index(idx): FUNCTION_TEMPLATE = """ # {init_expr} -@nb.jit(cache=False, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +@nb.jit( + cache=False, + error_model='{error_model}', + boundscheck={boundscheck}, + nopython={nopython}, + fastmath={fastmath}, + nogil={nopython}) def {fname}( {argtokens} _outputs, @@ -215,7 +226,14 @@ def {fname}( IRUNNER_1D_TEMPLATE = """ -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +@nb.jit( + cache=True, + parallel=True, + error_model='{error_model}', + boundscheck={boundscheck}, + nopython={nopython}, + fastmath={fastmath}, + nogil={nopython}) def irunner( argshape, {joined_namespace_names} @@ -236,7 +254,14 @@ def irunner( """ IRUNNER_2D_TEMPLATE = """ -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +@nb.jit( + cache=True, + parallel=True, + error_model='{error_model}', + boundscheck={boundscheck}, + nopython={nopython}, + fastmath={fastmath}, + nogil={nopython}) def irunner( argshape, {joined_namespace_names} @@ -258,7 +283,14 @@ def irunner( """ IDOTTER_1D_TEMPLATE = """ -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +@nb.jit( + cache=True, + parallel=True, + error_model='{error_model}', + boundscheck={boundscheck}, + nopython={nopython}, + fastmath={fastmath}, + nogil={nopython}) def idotter( argshape, {joined_namespace_names} @@ -283,7 +315,14 @@ def idotter( """ IDOTTER_2D_TEMPLATE = """ -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +@nb.jit( + cache=True, + parallel=True, + error_model='{error_model}', + boundscheck={boundscheck}, + nopython={nopython}, + fastmath={fastmath}, + nogil={nopython}) def idotter( argshape, {joined_namespace_names} @@ -310,7 +349,13 @@ def idotter( """ ILINER_1D_TEMPLATE = """ -@nb.jit(cache=False, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +@nb.jit( + cache=False, + error_model='{error_model}', + boundscheck={boundscheck}, + nopython={nopython}, + fastmath={fastmath}, + nogil={nopython}) def linemaker( intermediate, j0, {joined_namespace_names} @@ -320,7 +365,13 @@ def linemaker( """ ILINER_2D_TEMPLATE = """ -@nb.jit(cache=False, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +@nb.jit( + cache=False, + error_model='{error_model}', + boundscheck={boundscheck}, + nopython={nopython}, + fastmath={fastmath}, + nogil={nopython}) def linemaker( intermediate, j0, j1, {joined_namespace_names} @@ -331,7 +382,13 @@ def linemaker( MNL_GENERIC_TEMPLATE = """ -@nb.jit(cache=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +@nb.jit( + cache=True, + error_model='{error_model}', + boundscheck={boundscheck}, + nopython={nopython}, + fastmath={fastmath}, + nogil={nopython}) def _sample_choices_maker( prob_array, random_array, @@ -381,7 +438,13 @@ def _sample_choices_maker( -@nb.jit(cache=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +@nb.jit( + cache=True, + error_model='{error_model}', + boundscheck={boundscheck}, + nopython={nopython}, + fastmath={fastmath}, + nogil={nopython}) def _sample_choices_maker_counted( prob_array, random_array, @@ -446,7 +509,14 @@ def _sample_choices_maker_counted( logit_ndims = 1 -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +@nb.jit( + cache=True, + parallel=True, + error_model='{error_model}', + boundscheck={boundscheck}, + nopython={nopython}, + fastmath={fastmath}, + nogil={nopython}) def mnl_transform_plus1d( argshape, {joined_namespace_names} @@ -496,7 +566,13 @@ def mnl_transform_plus1d( """ ) -# @nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}) +# @nb.jit( +# cache=True, +# parallel=True, +# error_model='{error_model}', +# boundscheck={boundscheck}, +# nopython={nopython}, +# fastmath={fastmath}) # def mnl_transform_plus1d( # argshape, # {joined_namespace_names} @@ -533,7 +609,9 @@ def mnl_transform_plus1d( # if logsums: # _logsums[j0,k0] = np.log(local_sum) + shifter # if pick_counted: -# _sample_choices_maker_counted(partial, random_draws[j0,k0], result[j0,k0], result_p[j0,k0], pick_count[j0,k0]) +# _sample_choices_maker_counted( +# partial, random_draws[j0,k0], result[j0,k0], result_p[j0,k0], pick_count[j0,k0] +# ) # else: # _sample_choices_maker(partial, random_draws[j0,k0], result[j0,k0], result_p[j0,k0]) # return result, result_p, pick_count, _logsums @@ -545,7 +623,14 @@ def mnl_transform_plus1d( logit_ndims = 2 -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +@nb.jit( + cache=True, + parallel=True, + error_model='{error_model}', + boundscheck={boundscheck}, + nopython={nopython}, + fastmath={fastmath}, + nogil={nopython}) def mnl_transform( argshape, {joined_namespace_names} @@ -609,7 +694,14 @@ def mnl_transform( return result, result_p, pick_count, _logsums -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +@nb.jit( + cache=True, + parallel=True, + error_model='{error_model}', + boundscheck={boundscheck}, + nopython={nopython}, + fastmath={fastmath}, + nogil={nopython}) def mnl_transform_plus1d( argshape, {joined_namespace_names} @@ -664,7 +756,9 @@ def mnl_transform_plus1d( continue partial /= local_sum if pick_counted: - _sample_choices_maker_counted(partial, random_draws[j0,j1], result[j0,j1], result_p[j0,j1], pick_count[j0,j1]) + _sample_choices_maker_counted( + partial, random_draws[j0,j1], result[j0,j1], result_p[j0,j1], pick_count[j0,j1] + ) else: _sample_choices_maker(partial, random_draws[j0,j1], result[j0,j1], result_p[j0,j1]) return result, result_p, pick_count, _logsums @@ -676,7 +770,14 @@ def mnl_transform_plus1d( from sharrow.nested_logit import _utility_to_probability -@nb.jit(cache=True, parallel=True, error_model='{error_model}', boundscheck={boundscheck}, nopython={nopython}, fastmath={fastmath}, nogil={nopython}) +@nb.jit( + cache=True, + parallel=True, + error_model='{error_model}', + boundscheck={boundscheck}, + nopython={nopython}, + fastmath={fastmath}, + nogil={nopython}) def nl_transform( argshape, {joined_namespace_names} @@ -746,7 +847,9 @@ def nl_transform( _logsums[j0] = utility[-1] if logsums != 1: if pick_counted: - _sample_choices_maker_counted(probability[:n_alts], random_draws[j0], result[j0], result_p[j0], pick_count[j0]) + _sample_choices_maker_counted( + probability[:n_alts], random_draws[j0], result[j0], result_p[j0], pick_count[j0] + ) else: _sample_choices_maker(probability[:n_alts], random_draws[j0], result[j0], result_p[j0]) return result, result_p, pick_count, _logsums @@ -853,6 +956,7 @@ def __new__( dim_order=None, dim_exclude=None, bool_wrapping=False, + with_root_node_name=None, ): assert isinstance(tree, DataTree) tree.digitize_relationships(inplace=True) @@ -895,9 +999,11 @@ def __new__( parallel=parallel, extra_hash_data=extra_hash_data, write_hash_audit=write_hash_audit, + with_root_node_name=with_root_node_name, ) if flow_library is not None: flow_library[self.flow_hash] = self + self.with_root_node_name = with_root_node_name return self def __initialize_1( @@ -937,7 +1043,7 @@ def __initialize_1( all_raw_names = set() all_name_tokens = set() - for k, expr in defs.items(): + for _k, expr in defs.items(): plain_names, attribute_pairs, subscript_pairs = extract_names_2(expr) all_raw_names |= plain_names if self.tree.root_node_name: @@ -1068,15 +1174,19 @@ def _flow_hash_push(x): digital_encoding = self.tree.subspaces[parts[1]][ "__".join(parts[2:]) ].attrs["digital_encoding"] - except (AttributeError, KeyError): + except (AttributeError, KeyError) as err: pass + print(f"$$$$/ndigital_encoding=ERR\n{err}\n\n\n$$$") + else: + print(f"$$$$/n{digital_encoding=}\n\n\n$$$") if digital_encoding: for de_k in sorted(digital_encoding.keys()): de_v = digital_encoding[de_k] if de_k == "dictionary": self.encoding_dictionaries[k] = de_v _flow_hash_push((k, "digital_encoding", de_k, de_v)) + for k in extra_hash_data: _flow_hash_push(k) @@ -1170,7 +1280,7 @@ def init_sub_funcs( other_way = False # if other_way is triggered, there may be residual other terms # that were not addressed, so this loop should be applied again. - for spacename, spacearrays in self.tree.subspaces.items(): + for spacename in self.tree.subspaces.keys(): dim_slots, digital_encodings, blenders = meta_data[spacename] try: expr = expression_for_numba( @@ -1401,6 +1511,7 @@ def __initialize_2( parallel=True, extra_hash_data=(), write_hash_audit=True, + with_root_node_name=None, ): """ @@ -1464,7 +1575,7 @@ def __initialize_2( # if an existing __init__ file matches the hash, just use it init_file = os.path.join(self.cache_dir, self.name, "__init__.py") if os.path.isfile(init_file): - with open(init_file, "rt") as f: + with open(init_file) as f: content = f.read() s = re.search("""flow_hash = ['"](.*)['"]""", content) else: @@ -1609,9 +1720,12 @@ def __initialize_2( if self.tree.relationships_are_digitized: + if with_root_node_name is None: + with_root_node_name = self.tree.root_node_name + root_dims = list( presorted( - self.tree.root_dataset.dims, + self.tree._graph.nodes[with_root_node_name]["dataset"].dims, self.dim_order, self.dim_exclude, ) @@ -1763,7 +1877,9 @@ def load_raw(self, rg, args, runner=None, dtype=None, dot=None): assembled_args = [args.get(k) for k in self.arg_name_positions.keys()] for aa in assembled_args: if aa.dtype.kind != "i": - warnings.warn("position arguments are not all integers") + warnings.warn( + "position arguments are not all integers", stacklevel=2 + ) try: if runner is None: if dot is None: @@ -1930,7 +2046,13 @@ def _iload_raw( kwargs.update(nesting) if mask is not None: kwargs["mask"] = mask - tree_root_dims = rg.root_dataset.dims + + if self.with_root_node_name is None: + tree_root_dims = rg.root_dataset.dims + else: + tree_root_dims = rg._graph.nodes[self.with_root_node_name][ + "dataset" + ].dims argshape = [ tree_root_dims[i] for i in presorted(tree_root_dims, self.dim_order, self.dim_exclude) @@ -2056,7 +2178,9 @@ def check_cache_misses(self, *funcs, fresh=True, log_details=True): f"cache miss in {self.flow_hash}{warning_text}\n" f"Compile Time: {timers}" ) - warnings.warn(f"{self.flow_hash}", CacheMissWarning) + warnings.warn( + f"{self.flow_hash}", CacheMissWarning, stacklevel=1 + ) self.compiled_recently = True self._known_cache_misses[runner_name][k] = v return self.compiled_recently @@ -2140,9 +2264,18 @@ def _load( if logit_draws is None and logsums == 1: logit_draws = np.zeros(source.shape + (0,), dtype=dtype) - use_dims = list( - presorted(source.root_dataset.dims, self.dim_order, self.dim_exclude) - ) + if self.with_root_node_name is None: + use_dims = list( + presorted(source.root_dataset.dims, self.dim_order, self.dim_exclude) + ) + else: + use_dims = list( + presorted( + source._graph.nodes[self.with_root_node_name]["dataset"].dims, + self.dim_order, + self.dim_exclude, + ) + ) if logit_draws is not None: if dot is None: @@ -2313,9 +2446,20 @@ def _load( result = squeeze(result, result_squeeze) result_p = squeeze(result_p, result_squeeze) pick_count = squeeze(pick_count, result_squeeze) - result_coords = { - k: v for k, v in source.root_dataset.coords.items() if k in result_dims - } + if self.with_root_node_name is None: + result_coords = { + k: v + for k, v in source.root_dataset.coords.items() + if k in result_dims + } + else: + result_coords = { + k: v + for k, v in source._graph.nodes[self.with_root_node_name][ + "dataset" + ].coords.items() + if k in result_dims + } if result is not None: result = xr.DataArray( result, @@ -2658,7 +2802,7 @@ def show_code(self, linenos="inline"): from pygments.lexers.python import PythonLexer codefile = os.path.join(self.cache_dir, self.name, "__init__.py") - with open(codefile, "rt") as f_code: + with open(codefile) as f_code: code = f_code.read() pretty = highlight(code, PythonLexer(), HtmlFormatter(linenos=linenos)) css = HtmlFormatter().get_style_defs(".highlight") diff --git a/sharrow/nested_logit.py b/sharrow/nested_logit.py index 452df23..ee9a569 100644 --- a/sharrow/nested_logit.py +++ b/sharrow/nested_logit.py @@ -1,4 +1,4 @@ -from typing import Mapping +from collections.abc import Mapping import numba as nb import numpy as np diff --git a/sharrow/relationships.py b/sharrow/relationships.py index 15e87c6..134b8eb 100644 --- a/sharrow/relationships.py +++ b/sharrow/relationships.py @@ -24,7 +24,8 @@ except ImportError: from astunparse import unparse as _unparse - unparse = lambda *args: _unparse(*args).strip("\n") + def unparse(*args): + return _unparse(*args).strip("\n") logger = logging.getLogger("sharrow") @@ -47,6 +48,8 @@ "clip", } +NOTSET = "<--NOTSET-->" + def _require_string(x): if not isinstance(x, str): @@ -197,10 +200,30 @@ def __init__( def __eq__(self, other): if isinstance(other, self.__class__): - return repr(self) == repr(other) + if self.analog: + left = ( + f" " + f"{self.child_data}[{self.child_name!r}]>" + ) + else: + left = repr(self) + if other.analog: + right = ( + f" " + f"{other.child_data}[{other.child_name!r}]>" + ) + else: + right = repr(other) + return left == right def __repr__(self): - return f" {self.child_data}[{self.child_name!r}]>" + return ( + f" " + f"{self.child_data}[{self.child_name!r}]>" + ) def attrs(self): return dict( @@ -209,6 +232,16 @@ def attrs(self): indexing=self.indexing, ) + def to_dict(self): + return dict( + parent_data=self.parent_data, + parent_name=self.parent_name, + child_data=self.child_data, + child_name=self.child_name, + indexing=self.indexing, + analog=self.analog, + ) + @classmethod def from_string(cls, s): """ @@ -257,7 +290,7 @@ class DataTree: Parameters ---------- graph : networkx.MultiDiGraph - root_node_name : str + root_node_name : str or False The name of the node at the root of the tree. extra_funcs : Tuple[Callable] Additional functions that can be called by Flow objects created @@ -441,15 +474,34 @@ def root_node_name(self): @root_node_name.setter def root_node_name(self, name): - if name is None: - self._root_node_name = None + if name is None or name is False: + self._root_node_name = name return if not isinstance(name, str): - raise TypeError(f"root_node_name must be str not {type(name)}") + raise TypeError( + f"root_node_name must be one of [str, None, False] not {type(name)}" + ) if name not in self._graph.nodes: raise KeyError(name) self._root_node_name = name + @property + def root_node_name_str(self): + """str: The root node for this data tree, which is only ever a parent. + + This method raises a ValueError if root node cannot be determined. + """ + if self._root_node_name is None: + for nodename in self._graph.nodes: + if self._graph.in_degree(nodename) == 0: + self._root_node_name = nodename + break + if self._root_node_name is None: + raise ValueError("root node cannot be determined") + if self._root_node_name is False: + raise ValueError("root node is False") + return self._root_node_name + def add_relationship(self, *args, **kwargs): """ Add a relationship to this DataTree. @@ -469,28 +521,7 @@ def add_relationship(self, *args, **kwargs): if len(args) == 1 and isinstance(args[0], Relationship): r = args[0] elif len(args) == 1 and isinstance(args[0], str): - s = args[0] - if "->" in s: - parent, child = s.split("->", 1) - i = "position" - elif "@" in s: - parent, child = s.split("@", 1) - i = "label" - else: - raise ValueError(f"cannot interpret relationship {s!r}") - p1, p2 = parent.split(".", 1) - c1, c2 = child.split(".", 1) - p1 = p1.strip() - p2 = p2.strip() - c1 = c1.strip() - c2 = c2.strip() - r = Relationship( - parent_data=p1, - parent_name=p2, - child_data=c1, - child_name=c2, - indexing=i, - ) + r = Relationship.from_string(args[0]) else: r = Relationship(*args, **kwargs) @@ -511,6 +542,13 @@ def get_relationship(self, parent, child): attrs = self._graph.edges[parent, child] return Relationship(parent_data=parent, child_data=child, **attrs) + def list_relationships(self) -> list[Relationship]: + """list : List all relationships defined in this tree.""" + result = [] + for e in self._graph.edges: + result.append(self._get_relationship(e)) + return result + def add_dataset(self, name, dataset, relationships=(), as_root=False): """ Add a new Dataset node to this DataTree. @@ -564,11 +602,11 @@ def add_items(self, items): @property def root_node(self): - return self._graph.nodes[self.root_node_name] + return self._graph.nodes[self.root_node_name_str] @property def root_dataset(self): - return self._graph.nodes[self.root_node_name]["dataset"] + return self._graph.nodes[self.root_node_name_str]["dataset"] @root_dataset.setter def root_dataset(self, x): @@ -576,7 +614,7 @@ def root_dataset(self, x): if not isinstance(x, Dataset): x = construct(x) - if self.root_node_name in self.replacement_filters: + if self.root_node_name_str in self.replacement_filters: x = self.replacement_filters[self.root_node_name](x) self._graph.nodes[self.root_node_name]["dataset"] = x @@ -630,16 +668,28 @@ def get(self, item, default=None, broadcast=True, coords=True): raise else: result = xr.DataArray(default) - root_dataset = self.root_dataset - if result.dims != self.root_dims and broadcast: - result, _ = xr.broadcast(result, root_dataset) - if coords: - add_coords = {} - for i in result.dims: - if i not in result.coords and i in root_dataset.coords: - add_coords[i] = root_dataset.coords[i] - if add_coords: - result = result.assign_coords(add_coords) + if self.root_node_name: + root_dataset = self.root_dataset + if result.dims != self.root_dims and broadcast: + result, _ = xr.broadcast(result, root_dataset) + if coords: + add_coords = {} + for i in result.dims: + if i not in result.coords and i in root_dataset.coords: + add_coords[i] = root_dataset.coords[i] + if add_coords: + result = result.assign_coords(add_coords) + elif self.root_node_name is False: + if "." in item: + item_in, item = item.split(".", 1) + base_dataset = self._graph.nodes[item_in]["dataset"] + if coords: + add_coords = {} + for i in result.dims: + if i not in result.coords and i in base_dataset.coords: + add_coords[i] = base_dataset.coords[i] + if add_coords: + result = result.assign_coords(add_coords) return result def finditem(self, item, maybe_in=None): @@ -665,11 +715,17 @@ def _getitem( if "." in item: item_in, item = item.split(".", 1) + queue = [self.root_node_name] + if self.root_node_name is False: + # when root_node_name is False, we don't want to broadcast + # back to the root, but instead only to the given `item_in` + queue = [item_in] + item_in = None else: item_in = None - - queue = [self.root_node_name] + queue = [self.root_node_name_str] examined = set() + start_from = queue[0] while len(queue): current_node = queue.pop(0) if current_node in examined: @@ -686,7 +742,7 @@ def _getitem( if (by_name or by_dims) and (item_in is None or item_in == current_node): if just_node_name: return current_node - if current_node == self.root_node_name: + if current_node == start_from: if by_dims: return xr.DataArray( pd.RangeIndex(dataset.dims[item]), dims=item @@ -711,19 +767,19 @@ def _getitem( dims_in_result = set(result.dims) top_dim_names = {} for path in nx.algorithms.simple_paths.all_simple_edge_paths( - self._graph, self.root_node_name, current_node + self._graph, start_from, current_node ): if dim_names_from_top: e = path[0] top_dim_name = self._graph.edges[e].get("parent_name") - root_dataset = self.root_dataset + start_dataset = self._graph.nodes[start_from]["dataset"] # deconvert digitized dim names back to native dims if ( - top_dim_name not in root_dataset.dims - and top_dim_name in root_dataset.variables + top_dim_name not in start_dataset.dims + and top_dim_name in start_dataset.variables ): - if root_dataset.variables[top_dim_name].ndim == 1: - top_dim_name = root_dataset.variables[ + if start_dataset.variables[top_dim_name].ndim == 1: + top_dim_name = start_dataset.variables[ top_dim_name ].dims[0] else: @@ -828,6 +884,8 @@ def get_expr(self, expression, engine="sharrow", allow_native=True): result = DataArray( pd.eval(expression, resolvers=[self], engine="numexpr"), ) + else: + raise ValueError(f"unknown engine {engine}") from None return result @property @@ -846,12 +904,48 @@ def subspaces_iter(self): if s is not None: yield (k, s) + def contains_subspace(self, key) -> bool: + """ + Is this named Dataset in this tree's subspaces + + Parameters + ---------- + key : str + + Returns + ------- + bool + """ + return key in self._graph.nodes + + def get_subspace(self, key, default_empty=False) -> xr.Dataset: + """ + Access named Dataset from this tree's subspaces + + Parameters + ---------- + key : str + default_empty : bool, default False + Return an empty Dataset if the key is not found. + + Returns + ------- + xr.Dataset + """ + result = self._graph.nodes[key].get("dataset", None) + if result is None: + if default_empty: + result = xr.Dataset() + else: + raise KeyError(key) + return result + def namespace_names(self): namespace = set() for spacename, spacearrays in self.subspaces_iter(): - for k, arr in spacearrays.coords.items(): + for k, _arr in spacearrays.coords.items(): namespace.add(f"__{spacename or 'base'}__{k}") - for k, arr in spacearrays.items(): + for k, _arr in spacearrays.items(): if k.startswith("_s_"): namespace.add(f"__{spacename or 'base'}__{k}__indptr") namespace.add(f"__{spacename or 'base'}__{k}__indices") @@ -866,7 +960,7 @@ def dims(self): Mapping from dimension names to lengths across all dataset nodes. """ dims = {} - for k, v in self.subspaces_iter(): + for _k, v in self.subspaces_iter(): for name, length in v.dims.items(): if name in dims: if dims[name] != length: @@ -930,7 +1024,7 @@ def drop_dims(self, dims, inplace=False, ignore_missing_dims=True): # remove subspaces that rely on dropped dim boot_queue = set() booted = set() - for (up, dn, n), e in obj._graph.edges.items(): + for (up, dn, _n), e in obj._graph.edges.items(): if up == obj.root_node_name: _analog = e.get("analog", "") if _analog in dims: @@ -945,7 +1039,7 @@ def drop_dims(self, dims, inplace=False, ignore_missing_dims=True): while boot_queue: b = boot_queue.pop() booted.add(b) - for (up, dn, n), e in obj._graph.edges.items(): + for (up, dn, _n) in obj._graph.edges.keys(): if up == b: boot_queue.add(dn) @@ -987,7 +1081,8 @@ def get_indexes( if result_shape != result_k.shape: if check_shapes: raise ValueError( - f"inconsistent index shapes {result_k.shape} v {result_shape} (probably an error on {k} or {sorted(dims)[0]})" + f"inconsistent index shapes {result_k.shape} v {result_shape} " + f"(probably an error on {k} or {sorted(dims)[0]})" ) result[k] = result_k @@ -1074,6 +1169,7 @@ def setup_flow( write_hash_audit=True, hashing_level=1, dim_exclude=None, + with_root_node_name=None, ): """ Set up a new Flow for analysis using the structure of this DataTree. @@ -1158,6 +1254,7 @@ def setup_flow( write_hash_audit=write_hash_audit, dim_order=self.dim_order, dim_exclude=dim_exclude, + with_root_node_name=with_root_node_name, ) def _spill(self, all_name_tokens=()): @@ -1237,13 +1334,18 @@ def digitize_relationships(self, inplace=False, redigitize=True): # vectorize version mapper = {i: j for (j, i) in enumerate(_dataarray_to_numpy(downstream))} + + def mapper_get(x, mapper=mapper): + return mapper.get(x, 0) + if upstream.size: - offsets = xr.apply_ufunc(np.vectorize(mapper.get), upstream) + offsets = xr.apply_ufunc(np.vectorize(mapper_get), upstream) else: offsets = xr.DataArray([], dims=["index"]) if offsets.dtype.kind != "i": warnings.warn( f"detected missing values in digitizing {r.parent_data}.{r.parent_name}", + stacklevel=2, ) # candidate name for write back @@ -1353,29 +1455,40 @@ def _arg_tokenizer( try: upside = ", ".join(unparse(t) for t in upside_ast) except: # noqa: E722 - for t in upside_ast: - str_t = str(t) - if len(str_t) < 2000: - print(f"t:{str_t}") - else: - print(f"t:{str_t[:200]}...") - raise - - # check for redirection target - if retarget is not None: - tokens.append( - f"__{spacename}___digitized_{retarget}_of_{this_dim_name}[__{parent_data}__{parent_name}[{upside}]]" - ) - else: - tokens.append(f"__{parent_data}__{parent_name}[{upside}]") + if self.root_node_name is False: + upside = None + else: + print(f"{parent_data=}") + print(f"{parent_name=}") + print(f"{spacearrayname=}") + print(f"{exclude_dims=}") + print(f"{blends=}") + for t in upside_ast: + str_t = str(t) + if len(str_t) < 2000: + print(f"t:{str_t}") + else: + print(f"t:{str_t[:200]}...") + raise + if upside is not None: + # check for redirection target + if retarget is not None: + tokens.append( + f"__{spacename}___digitized_{retarget}_of_{this_dim_name}[__{parent_data}__{parent_name}[{upside}]]" + ) + else: + tokens.append(f"__{parent_data}__{parent_name}[{upside}]") found_token = True break if not found_token: if dimname in self.subspaces[spacename].indexes: - ix = self.subspaces[spacename].indexes[dimname] - ix = {i: n for n, i in enumerate(ix)} - tokens.append(ix) - n_missing_tokens += 1 + if self.root_node_name is False: + tokens.append(False) + else: + ix = self.subspaces[spacename].indexes[dimname] + ix = {i: n for n, i in enumerate(ix)} + tokens.append(ix) + n_missing_tokens += 1 elif dimname.endswith("_indices") or dimname.endswith("_indptr"): tokens.append(None) # this dimension corresponds to a blender @@ -1396,7 +1509,7 @@ def coords(self): return self.root_dataset.coords def get_index(self, dim): - for spacename, subspace in self.subspaces.items(): + for _spacename, subspace in self.subspaces.items(): if dim in subspace.coords: return subspace.indexes[dim] diff --git a/sharrow/selectors.py b/sharrow/selectors.py index 5fb6bef..927cfaa 100644 --- a/sharrow/selectors.py +++ b/sharrow/selectors.py @@ -127,9 +127,16 @@ def _filter( ds = self._obj if _load: ds = ds.load() + if _func == "isel": + # remove coordinates, we don't need them for isel + ds_ = ds.drop_vars(ds.coords) + else: + ds_ = ds + if _names: + result = ( - getattr(ds, _func)(**loaders) + getattr(ds_, _func)(**loaders) .digital_encoding.strip(_names) .drop_vars(_baggage) ) @@ -149,7 +156,7 @@ def _filter( result = result[_name] return result else: - result = getattr(ds, _func)(**loaders) + result = getattr(ds_, _func)(**loaders) names = list(result.keys()) for n in names: if self._obj.redirection.is_blended(n): @@ -202,17 +209,34 @@ def __call__( ): modified_idxs = {} raw_idxs = {} + + keep_raw_idxs = False + is_it_blended = [] + if isinstance(_name, str): + is_it_blended = [_name] + elif _names is not None: + is_it_blended = _names + for n in is_it_blended: + try: + if self._obj.redirection.is_blended(n): + keep_raw_idxs = True + except AttributeError: + keep_raw_idxs = True + for k, v in idxs.items(): target = self._obj.redirection.target(k) if target is None: - raw_idxs[k] = modified_idxs[k] = v + modified_idxs[k] = v + if keep_raw_idxs: + raw_idxs[k] = v else: v_ = np.asarray(v) modified_idxs[target] = self._obj[f"_digitized_{target}_of_{k}"][ v_ ].to_numpy() - raw_idxs[target] = v_ # self._obj[k][v_].to_numpy() - return self._filter( + if keep_raw_idxs: + raw_idxs[target] = v_ # self._obj[k][v_].to_numpy() + out = self._filter( _name=_name, _names=_names, _load=_load, @@ -221,6 +245,7 @@ def __call__( _raw_idxs=raw_idxs, **modified_idxs, ) + return out @xr.register_dataset_accessor("at") diff --git a/sharrow/shared_memory.py b/sharrow/shared_memory.py index 8b493eb..d2d114e 100644 --- a/sharrow/shared_memory.py +++ b/sharrow/shared_memory.py @@ -99,7 +99,7 @@ def create_shared_memory_array(key, size): size=size, ) except FileExistsError: - raise FileExistsError(f"sharrow_shared_memory_array:{key}") + raise FileExistsError(f"sharrow_shared_memory_array:{key}") from None __GLOBAL_MEMORY_ARRAYS[key] = result return result @@ -138,7 +138,7 @@ def open_shared_memory_array(key, mode="r+"): create=False, ) except FileNotFoundError: - raise FileNotFoundError(f"sharrow_shared_memory_array:{key}") + raise FileNotFoundError(f"sharrow_shared_memory_array:{key}") from None else: logger.info( f"shared memory array from ephemeral memory, {si_units(result.size)}" @@ -175,7 +175,7 @@ def create_shared_list(content, key): name=h, ) except FileExistsError: - raise FileExistsError(f"sharrow_shared_memory_list:{key}") + raise FileExistsError(f"sharrow_shared_memory_list:{key}") from None __GLOBAL_MEMORY_LISTS[key] = result return result @@ -190,7 +190,7 @@ def read_shared_list(key): try: sl = ShareableList(name=_hexhash(f"sharrow__list__{key}")) except FileNotFoundError: - raise FileNotFoundError(f"sharrow_shared_memory_list:{key}") + raise FileNotFoundError(f"sharrow_shared_memory_list:{key}") from None else: return sl @@ -202,7 +202,7 @@ def get_shared_list_nbytes(key): try: shm = SharedMemory(name=h, create=False) except FileNotFoundError: - raise FileNotFoundError(f"sharrow_shared_memory_list:{key}") + raise FileNotFoundError(f"sharrow_shared_memory_list:{key}") from None else: return shm.size @@ -397,7 +397,7 @@ def shared_memory_key(self): try: return self._shared_memory_key_ except AttributeError: - raise ValueError("this dataset is not in shared memory") + raise ValueError("this dataset is not in shared memory") from None @classmethod def from_shared_memory(cls, key, own_data=False, mode="r+"): @@ -431,7 +431,7 @@ def from_shared_memory(cls, key, own_data=False, mode="r+"): # for memmap, list is loaded from pickle, not shared ram pass - if own_data and not (own_data is True): + if own_data and own_data is not True: mem = own_data own_data = True else: @@ -513,7 +513,7 @@ def shared_memory_size(self): try: return sum(i.size for i in self._shared_memory_objs_) except AttributeError: - raise ValueError("this dataset is not in shared memory") + raise ValueError("this dataset is not in shared memory") from None @property def is_shared_memory(self): diff --git a/sharrow/table.py b/sharrow/table.py index b964080..adde6ba 100644 --- a/sharrow/table.py +++ b/sharrow/table.py @@ -257,9 +257,9 @@ def from_quilt(cls, path, blockname=None): stopper = blockname else: qlog = os.path.join(path, "quilt.log") - with open(qlog, "rt") as logreader: + with open(qlog) as logreader: existing_info = yaml.safe_load(logreader) - for stopper, block in enumerate(existing_info): + for _stopper, block in enumerate(existing_info): if block.get("name", None) == blockname: break else: @@ -267,8 +267,13 @@ def from_quilt(cls, path, blockname=None): else: stopper = 1e99 n = 0 - rowfile = lambda n: os.path.join(path, f"block.{n:03d}.rows") - colfile = lambda n: os.path.join(path, f"block.{n:03d}.cols") + + def rowfile(n): + return os.path.join(path, f"block.{n:03d}.rows") + + def colfile(n): + return os.path.join(path, f"block.{n:03d}.cols") + builder = None look = True while look and n <= stopper: @@ -291,7 +296,7 @@ def from_quilt(cls, path, blockname=None): n += 1 if builder is not None: metadata = builder.schema.metadata - metadata[b"quilt_number"] = f"{n}".encode("utf8") + metadata[b"quilt_number"] = f"{n}".encode() return builder.replace_schema_metadata(metadata) return None @@ -305,7 +310,7 @@ def to_quilt(self, path, blockname=None): ex_cols = [] max_block = -1 else: - with open(qlog, "rt") as logreader: + with open(qlog) as logreader: existing_info = yaml.safe_load(logreader) ex_rows = sum(block.get("rows", 0) for block in existing_info) ex_cols = sum((block.get("cols", []) for block in existing_info), []) diff --git a/sharrow/tests/conftest.py b/sharrow/tests/conftest.py new file mode 100644 index 0000000..7c54017 --- /dev/null +++ b/sharrow/tests/conftest.py @@ -0,0 +1,53 @@ +import pytest +import xarray as xr +import pandas as pd +from sharrow.dataset import construct + + +@pytest.fixture +def person_dataset() -> xr.Dataset: + """ + Sample persons dataset with dummy data. + """ + df = pd.DataFrame( + { + "Income": [45, 88, 56, 15, 71], + "Name": ["Andre", "Bruce", "Carol", "David", "Eugene"], + "Age": [14, 25, 55, 8, 21], + "WorkMode": ["Car", "Bus", "Car", "Car", "Walk"], + "household_id": [11, 11, 22, 22, 33], + }, + index=pd.Index([441, 445, 552, 556, 934], name="person_id"), + ) + df["WorkMode"] = df["WorkMode"].astype("category") + return construct(df) + + +@pytest.fixture +def household_dataset() -> xr.Dataset: + """ + Sample household dataset with dummy data. + """ + df = pd.DataFrame( + { + "n_cars": [1, 2, 1], + }, + index=pd.Index([11, 22, 33], name="household_id"), + ) + return construct(df) + + +@pytest.fixture +def tours_dataset() -> xr.Dataset: + """ + Sample tours dataset with dummy data. + """ + df = pd.DataFrame( + { + "TourMode": ["Car", "Bus", "Car", "Car", "Walk"], + "person_id": [441, 445, 552, 556, 934], + }, + index=pd.Index([4411, 4451, 5521, 5561, 9341], name="tour_id"), + ) + df["TourMode"] = df["TourMode"].astype("category") + return construct(df) diff --git a/sharrow/tests/test_categorical.py b/sharrow/tests/test_categorical.py new file mode 100644 index 0000000..64edb8e --- /dev/null +++ b/sharrow/tests/test_categorical.py @@ -0,0 +1,99 @@ +from __future__ import annotations + +import numpy as np +import xarray as xr + +import sharrow + + +def test_simple_cat(tours_dataset: xr.Dataset): + + tree = sharrow.DataTree(tours=tours_dataset) + + assert all(tours_dataset.TourMode.cat.categories == ["Bus", "Car", "Walk"]) + + expr = "tours.TourMode == 'Bus'" + f = tree.setup_flow({expr: expr}) + a = f.load_dataarray(dtype=np.int8) + a = a.isel(expressions=0) + assert all(a == np.asarray([0, 1, 0, 0, 0])) + + tour_mode_bus = tree.get_expr(expr) + assert all(tour_mode_bus == np.asarray([0, 1, 0, 0, 0])) + + +def test_2_level_tree_cat( + tours_dataset: xr.Dataset, + person_dataset: xr.Dataset, +): + + tree = sharrow.DataTree(tours=tours_dataset) + tree.add_dataset("persons", person_dataset, "tours.person_id @ persons.person_id") + + assert all(tours_dataset.TourMode.cat.categories == ["Bus", "Car", "Walk"]) + + expr = "tours.TourMode == 'Bus'" + f = tree.setup_flow({expr: expr}) + a = f.load_dataarray(dtype=np.int8) + a = a.isel(expressions=0) + assert all(a == np.asarray([0, 1, 0, 0, 0])) + + tour_mode_bus = tree.get_expr(expr) + assert all(tour_mode_bus == np.asarray([0, 1, 0, 0, 0])) + + work_mode_bus = tree.get_expr("WorkMode == 'Walk'") + assert all(work_mode_bus == np.asarray([0, 0, 0, 0, 1])) + + work_mode_bus1 = tree.get_expr("persons.WorkMode == 'Walk'") + assert all(work_mode_bus1 == np.asarray([0, 0, 0, 0, 1])) + + +def test_3_level_tree_cat( + tours_dataset: xr.Dataset, + person_dataset: xr.Dataset, + household_dataset: xr.Dataset, +): + + tree = sharrow.DataTree(tours=tours_dataset) + tree.add_dataset("persons", person_dataset, "tours.person_id @ persons.person_id") + tree.add_dataset( + "households", person_dataset, "persons.household_id @ households.household_id" + ) + + assert all(tours_dataset.TourMode.cat.categories == ["Bus", "Car", "Walk"]) + + expr = "tours.TourMode == 'Bus'" + f = tree.setup_flow({expr: expr}) + a = f.load_dataarray(dtype=np.int8) + a = a.isel(expressions=0) + assert all(a == np.asarray([0, 1, 0, 0, 0])) + + tour_mode_bus = tree.get_expr(expr) + assert all(tour_mode_bus == np.asarray([0, 1, 0, 0, 0])) + + work_mode_bus = tree.get_expr("WorkMode == 'Walk'") + assert all(work_mode_bus == np.asarray([0, 0, 0, 0, 1])) + + work_mode_bus1 = tree.get_expr("persons.WorkMode == 'Walk'") + assert all(work_mode_bus1 == np.asarray([0, 0, 0, 0, 1])) + + +def test_rootless_tree_cat( + tours_dataset: xr.Dataset, + person_dataset: xr.Dataset, + household_dataset: xr.Dataset, +): + + tree = sharrow.DataTree(tours=tours_dataset, root_node_name=False) + tree.add_dataset("persons", person_dataset, "tours.person_id @ persons.person_id") + tree.add_dataset( + "households", person_dataset, "persons.household_id @ households.household_id" + ) + + assert all(tours_dataset.TourMode.cat.categories == ["Bus", "Car", "Walk"]) + + expr = "tours.TourMode == 'Bus'" + f = tree.setup_flow({expr: expr}, with_root_node_name="tours") + a = f.load_dataarray(dtype=np.int8) + a = a.isel(expressions=0) + assert all(a == np.asarray([0, 1, 0, 0, 0])) diff --git a/sharrow/tests/test_datasets.py b/sharrow/tests/test_datasets.py index f2b8b09..d2da374 100644 --- a/sharrow/tests/test_datasets.py +++ b/sharrow/tests/test_datasets.py @@ -3,6 +3,7 @@ import numpy as np import openmatrix +import pandas as pd from pytest import approx import sharrow as sh @@ -35,3 +36,32 @@ def test_dataset_construct_with_zoneids(): with openmatrix.open_file(t.joinpath("dummy5.omx"), mode="r") as back: ds1 = sh.dataset.from_omx(back, indexes="one-based") assert ds1.coords["otaz"].values == approx(np.asarray([1, 2, 3, 4, 5])) + + +def test_dataset_categoricals(): + hhs = sh.example_data.get_households() + + def income_cat(i): + if i < 12500: + return "LOW" + elif i < 45000: + return "MID" + else: + return "HIGH" + + hhs["income_grp"] = hhs.income.apply(income_cat).astype( + pd.CategoricalDtype(["LOW", "MID", "HIGH"], ordered=True) + ) + assert hhs["income_grp"].dtype == "category" + + hd = sh.dataset.construct(hhs) + assert hd["income_grp"].dtype == np.int8 + + # affirm we can recover categorical and non-categorical data from datarrays + pd.testing.assert_series_equal( + hhs["income_grp"], hd.income_grp.single_dim.to_pandas() + ) + pd.testing.assert_series_equal(hhs["income"], hd.income.single_dim.to_pandas()) + + recovered_df = hd.single_dim.to_pandas() + pd.testing.assert_frame_equal(hhs, recovered_df) diff --git a/sharrow/tests/test_datastore.py b/sharrow/tests/test_datastore.py new file mode 100644 index 0000000..6d0c974 --- /dev/null +++ b/sharrow/tests/test_datastore.py @@ -0,0 +1,131 @@ +from __future__ import annotations + +import shutil +from pathlib import Path + +import pytest +import xarray as xr + +from sharrow.datastore import DataStore, ReadOnlyError + + +def test_datasstore_checkpointing(tmp_path: Path, person_dataset): + tm = DataStore(directory=tmp_path) + tm["persons"] = person_dataset + tm.make_checkpoint("init_persons") + + person_dataset["DoubleAge"] = person_dataset["Age"] * 2 + tm.update("persons", person_dataset["DoubleAge"]) + tm.make_checkpoint("annot_persons") + + tm2 = DataStore(directory=tmp_path) + tm2.restore_checkpoint("annot_persons") + xr.testing.assert_equal(tm2.get_dataset("persons"), person_dataset) + + tm2.restore_checkpoint("init_persons") + assert "DoubleAge" not in tm2.get_dataset("persons") + + tm_ro = DataStore(directory=tmp_path, mode="r") + with pytest.raises(ReadOnlyError): + tm_ro.make_checkpoint("will-fail") + + +def test_datasstore_checkpointing_parquet(tmp_path: Path, person_dataset): + tm = DataStore(directory=tmp_path, storage_format="parquet") + tm["persons"] = person_dataset + tm.make_checkpoint("init_persons") + + person_dataset["DoubleAge"] = person_dataset["Age"] * 2 + tm.update("persons", person_dataset["DoubleAge"]) + tm.make_checkpoint("annot_persons") + + tm2 = DataStore(directory=tmp_path) + tm2.restore_checkpoint("annot_persons") + xr.testing.assert_equal(tm2.get_dataset("persons"), person_dataset) + + tm2.restore_checkpoint("init_persons") + assert "DoubleAge" not in tm2.get_dataset("persons") + + tm_ro = DataStore(directory=tmp_path, mode="r") + with pytest.raises(ReadOnlyError): + tm_ro.make_checkpoint("will-fail") + + +def test_datasstore_relationships( + tmp_path: Path, person_dataset, household_dataset, tours_dataset +): + pth = tmp_path.joinpath("relations") + + if pth.exists(): + shutil.rmtree(pth) + + pth.mkdir(parents=True, exist_ok=True) + tm = DataStore(directory=pth) + + tm["persons"] = person_dataset + tm.make_checkpoint("init_persons") + + tm["households"] = household_dataset + tm.add_relationship("persons.household_id @ households.household_id") + tm.make_checkpoint("init_households") + + tm["tours"] = tours_dataset + tm.add_relationship("tours.person_id @ persons.person_id") + tm.make_checkpoint("init_tours") + + tm.digitize_relationships() + assert tm.relationships_are_digitized + + tm.make_checkpoint("digitized") + + tm2 = DataStore(directory=pth, mode="r") + tm2.read_metadata("*") + tm2.restore_checkpoint("init_households") + + assert sorted(tm2.get_dataset("persons")) == [ + "Age", + "Income", + "Name", + "WorkMode", + "household_id", + ] + + assert sorted(tm2.get_dataset("households")) == [ + "n_cars", + ] + + tm2.restore_checkpoint("digitized") + assert sorted(tm2.get_dataset("persons")) == [ + "Age", + "Income", + "Name", + "WorkMode", + "digitizedOffsethousehold_id_households_household_id", + "household_id", + ] + + double_age = tm2.get_dataset("persons")["Age"] * 2 + with pytest.raises(ReadOnlyError): + tm2.update("persons", double_age.rename("doubleAge")) + + with pytest.raises(ReadOnlyError): + tm2.make_checkpoint("age-x2") + + tm.update("persons", double_age.rename("doubleAge")) + assert sorted(tm.get_dataset("persons")) == [ + "Age", + "Income", + "Name", + "WorkMode", + "digitizedOffsethousehold_id_households_household_id", + "doubleAge", + "household_id", + ] + + tm.make_checkpoint("age-x2") + tm2.read_metadata() + tm2.restore_checkpoint("age-x2") + + person_restored = tm2.get_dataframe("persons") + print(person_restored.WorkMode.dtype) + assert person_restored.WorkMode.dtype == "category" diff --git a/sharrow/tests/test_relationships.py b/sharrow/tests/test_relationships.py index 415fcbc..7a76dfb 100644 --- a/sharrow/tests/test_relationships.py +++ b/sharrow/tests/test_relationships.py @@ -30,7 +30,6 @@ def skims(): def test_shared_data(dataframe_regression, households, skims): - tree = DataTree( base=households, skims=skims, @@ -75,7 +74,6 @@ def test_shared_data(dataframe_regression, households, skims): def test_subspace_fallbacks(dataframe_regression, households, skims): - tree = DataTree( base=households, skims=skims, @@ -121,7 +119,6 @@ def test_subspace_fallbacks(dataframe_regression, households, skims): def test_shared_data_reversible(dataframe_regression, households, skims): - tree = DataTree( base=households, odt_skims=skims, @@ -287,7 +284,6 @@ def test_with_2d_base(dataframe_regression): def test_mixed_dtypes(dataframe_regression, households, skims): - tree = DataTree( base=households, skims=skims, @@ -372,7 +368,6 @@ def _get_target(q, token): sys.version_info < (3, 8), reason="shared memory requires python3.8 or higher" ) def test_shared_memory(skims): - token = "skims" + secrets.token_hex(5) skims_2 = skims.shm.to_shared_memory(token) @@ -410,7 +405,6 @@ def test_relationship_init(): def test_replacement_filters(dataframe_regression, households, skims): - tree = DataTree( base=households, skims=skims, @@ -448,7 +442,6 @@ def rename_jncome(x): def test_name_in_wrong_subspace(dataframe_regression, households, skims): - tree = DataTree( base=households, skims=skims, @@ -517,7 +510,6 @@ def test_name_in_wrong_subspace(dataframe_regression, households, skims): def test_shared_data_encoded(dataframe_regression, households, skims): - households = sharrow.dataset.construct(households).digital_encoding.set( "income", bitwidth=32, @@ -608,7 +600,6 @@ def test_joint_dict_encoded(dataframe_regression, skims): def test_isin_and_between(dataframe_regression): - data = example_data.get_data() persons = data["persons"] @@ -691,7 +682,6 @@ def test_isin_and_between(dataframe_regression): def test_nested_where(dataframe_regression): - data = example_data.get_data() base = persons = data["persons"] @@ -813,7 +803,6 @@ def test_isna(): def test_get(dataframe_regression, households, skims): - tree = DataTree( base=households, skims=skims, @@ -884,8 +873,8 @@ def test_get(dataframe_regression, households, skims): { "income": "np.power(base.get('income', default=0) + df.get('missing_one', 0), 1)", "sov_time_by_income": "skims.SOV_TIME/np.power(base.get('income', default=0), 1)", - "missing_data": "np.where(np.isnan(df.get('missing_data', default=1)), 0, df.get('missing_data', default=-1))", - "missing_skim": "(np.where(np.isnan(df.get('num_escortees', np.nan)), -2 , df.get('num_escortees', np.nan)))", + "missing_data": "np.where(np.isnan(df.get('missing_data', default=1)), 0, df.get('missing_data', default=-1))", # noqa: E501 + "missing_skim": "(np.where(np.isnan(df.get('num_escortees', np.nan)), -2 , df.get('num_escortees', np.nan)))", # noqa: E501 "sov_time_by_income_2": "skims.get('SOV_TIME', default=0)/base.income", "sov_cost_by_income_2": "skims.get('HOV3_TIME', default=999)", }, diff --git a/sharrow/utils/__init__.py b/sharrow/utils/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/sharrow/utils/tar_zst.py b/sharrow/utils/tar_zst.py new file mode 100644 index 0000000..a5e78ad --- /dev/null +++ b/sharrow/utils/tar_zst.py @@ -0,0 +1,104 @@ +# based on https://gist.github.com/scivision/ad241e9cf0474e267240e196d7545eca + +import os +import sys +import tarfile +import tempfile +from pathlib import Path + +try: + import zstandard # pip install zstandard +except ModuleNotFoundError: + zstandard = None + + +def extract_zst(archive: Path, out_path: Path): + """ + extract .zst file + works on Windows, Linux, MacOS, etc. + + Parameters + ---------- + archive: pathlib.Path or str + .zst file to extract + out_path: pathlib.Path or str + directory to extract files and directories to + """ + + if zstandard is None: + raise ImportError("pip install zstandard") + + archive = Path(archive).expanduser() + out_path = Path(out_path).expanduser().resolve() + # need .resolve() in case intermediate relative dir doesn't exist + + dctx = zstandard.ZstdDecompressor() + + with tempfile.TemporaryFile(suffix=".tar") as ofh: + with archive.open("rb") as ifh: + dctx.copy_stream(ifh, ofh) + ofh.seek(0) + with tarfile.open(fileobj=ofh) as z: + z.extractall(out_path) + + +def compress_zst(in_path: Path, archive: Path): + """ + Compress a directory into a .tar.zst file. + + Certain hidden files are excluded, including .git directories and + macOS's .DS_Store files. + + Parameters + ---------- + in_path: pathlib.Path or str + directory to compress + archive: pathlib.Path or str + .tar.zst file to compress into + """ + if zstandard is None: + raise ImportError("pip install zstandard") + dctx = zstandard.ZstdCompressor(level=9, threads=-1, write_checksum=True) + with tempfile.TemporaryFile(suffix=".tar") as ofh: + with tarfile.open(fileobj=ofh, mode="w") as z: + for dirpath, dirnames, filenames in os.walk(in_path): + if os.path.basename(dirpath) == ".git": + continue + for n in range(len(dirnames) - 1, -1, -1): + if dirnames[n] == ".git" or dirnames[n].startswith("---"): + dirnames.pop(n) + for f in filenames: + if f.startswith(".git") or f == ".DS_Store" or f.startswith("---"): + continue + finame = Path(os.path.join(dirpath, f)) + arcname = finame.relative_to(in_path) + print(f"> {arcname}") + z.add(finame, arcname=arcname) + ofh.seek(0) + with archive.open("wb") as ifh: + dctx.copy_stream(ofh, ifh) + + +if __name__ == "__main__": + x = Path(sys.argv[1]) + name = x.name + if name.endswith(".tar.zst"): + y = x.with_name(name[:-8]) + if x.exists(): + if not y.exists(): + print(f"extracting from: {x}") + extract_zst(x, y) + else: + print(f"not extracting, existing target: {y}") + else: + print(f"not extracting, does not exist: {x}") + else: + y = x.with_name(name + ".tar.zst") + if x.exists(): + if not y.exists(): + print(f"compressing to tar.zst: {x}") + compress_zst(x, y) + else: + print(f"not compressing, existing tar.zst: {x}") + else: + print(f"not compressing, does not exist: {x}") From fc289b648d5aa1d7d2ce344f9741a1a9d1586b43 Mon Sep 17 00:00:00 2001 From: Jeff Newman Date: Wed, 21 Jun 2023 13:34:55 -0500 Subject: [PATCH 5/7] fix isnan for apple silicon --- .pre-commit-config.yaml | 8 ++++---- sharrow/sparse.py | 14 +++++++++----- 2 files changed, 13 insertions(+), 9 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 835834c..30a97c0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.4.0 hooks: - id: check-yaml - id: end-of-file-fixer @@ -14,18 +14,18 @@ repos: - id: nbstripout - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.257 + rev: v0.0.274 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/pycqa/isort - rev: 5.10.1 + rev: 5.12.0 hooks: - id: isort args: ["--profile", "black", "--filter-files"] - repo: https://github.com/psf/black - rev: 22.10.0 + rev: 23.3.0 hooks: - id: black diff --git a/sharrow/sparse.py b/sharrow/sparse.py index 2adc8f0..f424e39 100644 --- a/sharrow/sparse.py +++ b/sharrow/sparse.py @@ -1,3 +1,5 @@ +import math + import numba as nb import numpy as np import pandas as pd @@ -197,15 +199,17 @@ def blenders(self): return b -@nb.generated_jit(nopython=True) +# fastmath must be false to ensure NaNs are detected here. +# wrapping this as such allows fastmath to be turned on in outer functions +# but not lose the ability to check for NaNs. Older versions of this function +# checked whether the float cast to an integer was -9223372036854775808, but +# that turns out to be not compatible with all hardware (i.e. Apple Silicon). +@nb.generated_jit(nopython=True, fastmath=False) def isnan_fast_safe(x): if isinstance(x, nb.types.Float): def func(x): - if int(x) == -9223372036854775808: - return True - else: - return False + return math.isnan(x) return func elif isinstance(x, (nb.types.UnicodeType, nb.types.UnicodeCharSeq)): From 8c795e338076d291c3f2bdb5031da27565024fb2 Mon Sep 17 00:00:00 2001 From: Jeff Newman Date: Wed, 21 Jun 2023 13:36:03 -0500 Subject: [PATCH 6/7] blacken --- sharrow/digital_encoding.py | 2 +- sharrow/flows.py | 8 ++------ sharrow/nested_logit.py | 1 - sharrow/relationships.py | 7 ++----- sharrow/selectors.py | 1 - sharrow/shared_memory.py | 2 -- sharrow/tests/conftest.py | 3 ++- sharrow/tests/test_categorical.py | 4 ---- sharrow/translate.py | 1 - 9 files changed, 7 insertions(+), 22 deletions(-) diff --git a/sharrow/digital_encoding.py b/sharrow/digital_encoding.py index e260022..22a8b27 100644 --- a/sharrow/digital_encoding.py +++ b/sharrow/digital_encoding.py @@ -167,7 +167,7 @@ def digitize_by_dictionary(arr, bitwidth=8): bin_edges = (bins[1:] - bins[:-1]) / 2 + bins[:-1] except TypeError: # bins are not numeric - bin_map = {x:n for n,x in enumerate(bins)} + bin_map = {x: n for n, x in enumerate(bins)} u, inv = np.unique(arr.data, return_inverse=True) result.data = np.array([bin_map.get(x) for x in u])[inv].reshape(arr.shape) result.attrs["digital_encoding"] = { diff --git a/sharrow/flows.py b/sharrow/flows.py index 33005a6..8215e38 100644 --- a/sharrow/flows.py +++ b/sharrow/flows.py @@ -1074,7 +1074,7 @@ def __initialize_1( self._used_aux_vars.append(aux_var) subspace_names = set() - for (k, _) in self.tree.subspaces_iter(): + for k, _ in self.tree.subspaces_iter(): subspace_names.add(k) for k in self.tree.subspace_fallbacks: subspace_names.add(k) @@ -1083,7 +1083,7 @@ def __initialize_1( ) self._optional_get_tokens = [] if optional_get_tokens: - for (_spacename, _varname) in optional_get_tokens: + for _spacename, _varname in optional_get_tokens: found = False if ( _spacename in self.tree.subspaces @@ -1665,7 +1665,6 @@ def __initialize_2( with rewrite( os.path.join(self.cache_dir, self.name, "__init__.py"), "wt" ) as f_code: - f_code.write( textwrap.dedent( f""" @@ -1719,7 +1718,6 @@ def __initialize_2( f_code.write("\n\n# machinery code\n\n") if self.tree.relationships_are_digitized: - if with_root_node_name is None: with_root_node_name = self.tree.root_node_name @@ -1803,7 +1801,6 @@ def __initialize_2( raise ValueError(f"invalid n_root_dims {n_root_dims}") else: - raise RuntimeError("digitization is now required") f_code.write(blacken(textwrap.dedent(line_template))) @@ -2441,7 +2438,6 @@ def _load( {k: result[:, n] for n, k in enumerate(self._raw_functions.keys())} ) elif as_dataarray: - if result_squeeze: result = squeeze(result, result_squeeze) result_p = squeeze(result_p, result_squeeze) diff --git a/sharrow/nested_logit.py b/sharrow/nested_logit.py index ee9a569..13e21fd 100644 --- a/sharrow/nested_logit.py +++ b/sharrow/nested_logit.py @@ -17,7 +17,6 @@ def _utility_to_probability( logprob, # float output shape=[nodes] probability, # float output shape=[nodes] ): - for up in range(n_alts, utility.size): up_nest = up - n_alts n_children_for_parent = len_slots[up_nest] diff --git a/sharrow/relationships.py b/sharrow/relationships.py index 134b8eb..f3ffdc6 100644 --- a/sharrow/relationships.py +++ b/sharrow/relationships.py @@ -577,7 +577,6 @@ def add_dataset(self, name, dataset, relationships=(), as_root=False): self.digitize_relationships(inplace=True) def add_items(self, items): - from collections.abc import Mapping, Sequence if isinstance(items, Sequence): @@ -707,7 +706,6 @@ def _getitem( just_node_name=False, dim_names_from_top=False, ): - if isinstance(item, (list, tuple)): from .dataset import Dataset @@ -790,7 +788,7 @@ def _getitem( # path_indexing = self._graph.edges[path[-1]].get('indexing') t1 = None # intermediate nodes on path - for (e, e_next) in zip(path[:-1], path[1:]): + for e, e_next in zip(path[:-1], path[1:]): r = self._get_relationship(e) r_next = self._get_relationship(e_next) if t1 is None: @@ -1039,7 +1037,7 @@ def drop_dims(self, dims, inplace=False, ignore_missing_dims=True): while boot_queue: b = boot_queue.pop() booted.add(b) - for (up, dn, _n) in obj._graph.edges.keys(): + for up, dn, _n in obj._graph.edges.keys(): if up == b: boot_queue.add(dn) @@ -1395,7 +1393,6 @@ def relationships_are_digitized(self): def _arg_tokenizer( self, spacename, spacearray, spacearrayname, exclude_dims=None, blends=None ): - if blends is None: blends = {} diff --git a/sharrow/selectors.py b/sharrow/selectors.py index 927cfaa..b057f89 100644 --- a/sharrow/selectors.py +++ b/sharrow/selectors.py @@ -134,7 +134,6 @@ def _filter( ds_ = ds if _names: - result = ( getattr(ds_, _func)(**loaders) .digital_encoding.strip(_names) diff --git a/sharrow/shared_memory.py b/sharrow/shared_memory.py index d2d114e..3bd273b 100644 --- a/sharrow/shared_memory.py +++ b/sharrow/shared_memory.py @@ -23,7 +23,6 @@ def si_units(x, kind="B", digits=3, shift=1000): - # nano micro milli kilo mega giga tera peta exa zeta yotta tiers = ["n", "ยต", "m", "", "K", "M", "G", "T", "P", "E", "Z", "Y"] @@ -219,7 +218,6 @@ def delete_shared_memory_files(key): @xr.register_dataset_accessor("shm") class SharedMemDatasetAccessor: - _parent_class = xr.Dataset def __init__(self, xarray_obj): diff --git a/sharrow/tests/conftest.py b/sharrow/tests/conftest.py index 7c54017..e532de1 100644 --- a/sharrow/tests/conftest.py +++ b/sharrow/tests/conftest.py @@ -1,6 +1,7 @@ +import pandas as pd import pytest import xarray as xr -import pandas as pd + from sharrow.dataset import construct diff --git a/sharrow/tests/test_categorical.py b/sharrow/tests/test_categorical.py index 64edb8e..5e9b9db 100644 --- a/sharrow/tests/test_categorical.py +++ b/sharrow/tests/test_categorical.py @@ -7,7 +7,6 @@ def test_simple_cat(tours_dataset: xr.Dataset): - tree = sharrow.DataTree(tours=tours_dataset) assert all(tours_dataset.TourMode.cat.categories == ["Bus", "Car", "Walk"]) @@ -26,7 +25,6 @@ def test_2_level_tree_cat( tours_dataset: xr.Dataset, person_dataset: xr.Dataset, ): - tree = sharrow.DataTree(tours=tours_dataset) tree.add_dataset("persons", person_dataset, "tours.person_id @ persons.person_id") @@ -53,7 +51,6 @@ def test_3_level_tree_cat( person_dataset: xr.Dataset, household_dataset: xr.Dataset, ): - tree = sharrow.DataTree(tours=tours_dataset) tree.add_dataset("persons", person_dataset, "tours.person_id @ persons.person_id") tree.add_dataset( @@ -83,7 +80,6 @@ def test_rootless_tree_cat( person_dataset: xr.Dataset, household_dataset: xr.Dataset, ): - tree = sharrow.DataTree(tours=tours_dataset, root_node_name=False) tree.add_dataset("persons", person_dataset, "tours.person_id @ persons.person_id") tree.add_dataset( diff --git a/sharrow/translate.py b/sharrow/translate.py index c0e5932..2e90611 100644 --- a/sharrow/translate.py +++ b/sharrow/translate.py @@ -21,7 +21,6 @@ def omx_to_zarr( time_periods=None, time_period_sep="__", ): - bucket = {} r1 = r2 = None From 2f40a2549869cf1f61965029e48c0d0afe01b8f3 Mon Sep 17 00:00:00 2001 From: Jeff Newman Date: Fri, 14 Jul 2023 09:45:55 -0500 Subject: [PATCH 7/7] categoricals from IntEnum --- .pre-commit-config.yaml | 8 +- sharrow/categorical.py | 152 ++++++++++++++++++++++++++++++ sharrow/dataset.py | 7 ++ sharrow/tests/test_categorical.py | 26 ++++- 4 files changed, 185 insertions(+), 8 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 835834c..30a97c0 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,7 +1,7 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.4.0 hooks: - id: check-yaml - id: end-of-file-fixer @@ -14,18 +14,18 @@ repos: - id: nbstripout - repo: https://github.com/charliermarsh/ruff-pre-commit - rev: v0.0.257 + rev: v0.0.274 hooks: - id: ruff args: [--fix, --exit-non-zero-on-fix] - repo: https://github.com/pycqa/isort - rev: 5.10.1 + rev: 5.12.0 hooks: - id: isort args: ["--profile", "black", "--filter-files"] - repo: https://github.com/psf/black - rev: 22.10.0 + rev: 23.3.0 hooks: - id: black diff --git a/sharrow/categorical.py b/sharrow/categorical.py index 30e5832..abddae2 100644 --- a/sharrow/categorical.py +++ b/sharrow/categorical.py @@ -1,6 +1,10 @@ from __future__ import annotations +from enum import IntEnum +from functools import reduce + import numpy as np +import pandas as pd import xarray as xr @@ -38,3 +42,151 @@ def category_array(self) -> np.ndarray: def is_categorical(self) -> bool: return "dictionary" in self.dataarray.attrs.get("digital_encoding", {}) + + +def _interpret_enum(e: type[IntEnum], value: int | str) -> IntEnum: + """ + Convert a string or integer into an Enum value. + + The + + Parameters + ---------- + e : Type[IntEnum] + The enum to use in interpretation. + value: int or str + The value to convert. Integer and simple string values are converted + to their corresponding value. Multiple string values can also be given + joined by the pipe operator, in the style of flags (e.g. "Red|Octagon"). + """ + if isinstance(value, int): + return e(value) + return reduce(lambda x, y: x | y, [getattr(e, v) for v in value.split("|")]) + + +def get_enum_name(e: type[IntEnum], value: int) -> str: + """ + Get the name of an enum by value, or a placeholder name if not found. + + This allows for dummy placeholder names is the enum is does not contain + all consecutive values between 0 and the maximum value, inclusive. + + Parameters + ---------- + e : Type[IntEnum] + The enum to use in interpretation. + value : int + The value for which to find a name. If not found in `e`, this + function will generate a new name as a string by prefixing `value` + with an underscore. + + Returns + ------- + str + """ + result = e._value2member_map_.get(value, f"_{value}") + try: + return result.name + except AttributeError: + return result + + +def int_enum_to_categorical_dtype(e: type[IntEnum]) -> pd.CategoricalDtype: + """ + Convert an integer-valued enum to a pandas CategoricalDtype. + + Parameters + ---------- + e : Type[IntEnum] + + Returns + ------- + pd.CategoricalDtype + """ + max_enum_value = int(max(e)) + categories = [get_enum_name(e, i) for i in range(max_enum_value + 1)] + return pd.CategoricalDtype(categories=categories) + + +def as_int_enum( + s: pd.Series, + e: type[IntEnum], + dtype: type[np.integer] | None = None, + categorical: bool = True, +) -> pd.Series: + """ + Encode a pandas Series as categorical, consistent with an IntEnum. + + Parameters + ---------- + s : pd.Series + e : Type[IntEnum] + dtype : Type[np.integer], optional + Specific dtype to use for the code point encoding. It is typically not + necessary to give this explicitly as the function will automatically + select the best (most efficient) bitwidth. + categorical : bool, default True + If set to false, the returned series will simply be integer encoded with + no formal Categorical dtype. + + Returns + ------- + pd.Series + """ + min_enum_value = int(min(e)) + max_enum_value = int(max(e)) + assert min_enum_value >= 0 + if dtype is None: + if max_enum_value < 256 and min_enum_value >= 0: + dtype = np.uint8 + elif max_enum_value < 128 and min_enum_value >= -128: + dtype = np.int8 + elif max_enum_value < 65536 and min_enum_value >= 0: + dtype = np.uint16 + elif max_enum_value < 32768 and min_enum_value >= -32768: + dtype = np.int16 + elif max_enum_value < 2_147_483_648 and min_enum_value >= -2_147_483_648: + dtype = np.int32 + else: + dtype = np.int64 + if not isinstance(s, pd.Series): + s = pd.Series(s) + result = s.apply(lambda x: _interpret_enum(e, x)).astype(dtype) + if categorical: + categories = [get_enum_name(e, i) for i in range(max_enum_value + 1)] + result = pd.Categorical.from_codes(codes=result, categories=categories) + return result + + +@pd.api.extensions.register_series_accessor("as_int_enum") +class _AsIntEnum: + """ + Encode a pandas Series as categorical, consistent with an IntEnum. + + Parameters + ---------- + s : pd.Series + e : Type[IntEnum] + dtype : Type[np.integer], optional + Specific dtype to use for the code point encoding. It is typically not + necessary to give this explicitly as the function will automatically + select the best (most efficient) bitwidth. + categorical : bool, default True + If set to false, the returned series will simply be integer encoded with + no formal Categorical dtype. + + Returns + ------- + pd.Series + """ + + def __init__(self, pandas_obj): + self._obj = pandas_obj + + def __call__( + self: pd.Series, + e: type[IntEnum], + dtype: type[np.integer] | None = None, + categorical: bool = True, + ): + return as_int_enum(self._obj, e, dtype, categorical) diff --git a/sharrow/dataset.py b/sharrow/dataset.py index 68d02e9..6ffab94 100755 --- a/sharrow/dataset.py +++ b/sharrow/dataset.py @@ -129,6 +129,13 @@ def dataset_from_dataframe_fast( If true, create a sparse arrays instead of dense numpy arrays. This can potentially save a large amount of memory if the DataFrame has a MultiIndex. Requires the sparse package (sparse.pydata.org). + preserve_cat : bool, default True + If true, preserve encoding of categorical columns. Xarray lacks an + official implementation of a categorical datatype, so sharrow's + dictionary-based digital encoding is applied instead. Note that in + native xarray usage, the resulting variable will look like integer + values instead of the category values. The `dataset.cat` accessor + can be used to interact with the categorical data. Returns ------- diff --git a/sharrow/tests/test_categorical.py b/sharrow/tests/test_categorical.py index 64edb8e..b500112 100644 --- a/sharrow/tests/test_categorical.py +++ b/sharrow/tests/test_categorical.py @@ -1,13 +1,15 @@ from __future__ import annotations +from enum import IntEnum + import numpy as np +import pandas as pd import xarray as xr import sharrow def test_simple_cat(tours_dataset: xr.Dataset): - tree = sharrow.DataTree(tours=tours_dataset) assert all(tours_dataset.TourMode.cat.categories == ["Bus", "Car", "Walk"]) @@ -26,7 +28,6 @@ def test_2_level_tree_cat( tours_dataset: xr.Dataset, person_dataset: xr.Dataset, ): - tree = sharrow.DataTree(tours=tours_dataset) tree.add_dataset("persons", person_dataset, "tours.person_id @ persons.person_id") @@ -53,7 +54,6 @@ def test_3_level_tree_cat( person_dataset: xr.Dataset, household_dataset: xr.Dataset, ): - tree = sharrow.DataTree(tours=tours_dataset) tree.add_dataset("persons", person_dataset, "tours.person_id @ persons.person_id") tree.add_dataset( @@ -83,7 +83,6 @@ def test_rootless_tree_cat( person_dataset: xr.Dataset, household_dataset: xr.Dataset, ): - tree = sharrow.DataTree(tours=tours_dataset, root_node_name=False) tree.add_dataset("persons", person_dataset, "tours.person_id @ persons.person_id") tree.add_dataset( @@ -97,3 +96,22 @@ def test_rootless_tree_cat( a = f.load_dataarray(dtype=np.int8) a = a.isel(expressions=0) assert all(a == np.asarray([0, 1, 0, 0, 0])) + + +def test_int_enum_categorical(): + class TourMode(IntEnum): + Car = 1 + Bus = 2 + Walk = 3 + + df = pd.DataFrame( + { + "TourMode": ["Car", "Bus", "Car", "Car", "Walk"], + "person_id": [441, 445, 552, 556, 934], + }, + index=pd.Index([4411, 4451, 5521, 5561, 9341], name="tour_id"), + ) + df["TourMode2"] = df["TourMode"].as_int_enum(TourMode) + assert df["TourMode2"].dtype == "category" + assert all(df["TourMode2"].cat.categories == ["_0", "Car", "Bus", "Walk"]) + assert all(df["TourMode2"].cat.codes == [1, 2, 1, 1, 3])