km3io


Namekm3io JSON
Version 1.0.2 PyPI version JSON
download
home_pagehttps://git.km3net.de/km3py/km3io
Summary"KM3NeT I/O library without ROOT"
upload_time2023-10-08 21:40:57
maintainerTamas Gal
docs_urlNone
author"Tamas Gal and Zineb Aly"
requires_python>=3.6
licenseMIT
keywords neutrino astroparticle physics hep root
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            The km3io Python package
========================

.. image:: https://git.km3net.de/km3py/km3io/badges/master/pipeline.svg
    :target: https://git.km3net.de/km3py/km3io/pipelines

.. image:: https://git.km3net.de/km3py/km3io/badges/master/coverage.svg
    :target: https://km3py.pages.km3net.de/km3io/coverage

.. image:: https://git.km3net.de/examples/km3badges/-/raw/master/docs-latest-brightgreen.svg
    :target: https://km3py.pages.km3net.de/km3io

.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.7382620.svg
   :target: https://doi.org/10.5281/zenodo.7382620

This software provides a set of Python classes to read KM3NeT ROOT files
without having ROOT, Jpp or aanet installed. It only depends on Python 3.5+ and the amazing `uproot <https://github.com/scikit-hep/uproot>`__ package and gives you access to the data via `numpy <https://www.numpy.org>`__ and `awkward <https://awkward-array.readthedocs.io>`__ arrays.

It's very easy to use and according to the `uproot <https://github.com/scikit-hep/uproot>`__ benchmarks, it is able to outperform the original ROOT I/O performance. 

Installation
============

Install km3io using pip::

    pip install km3io 

or conda::

    conda install km3io

To get the latest (stable) development release::

    pip install git+https://git.km3net.de/km3py/km3io.git

Docker::

    docker run -it docker.km3net.de/km3io

Singularity::

    wget https://sftp.km3net.de/singularity/km3io_v0.27.2.sif  # pick the version you like
    singularity shell km3io_v0.27.2.sif

**Reminder:** km3io is **not** dependent on aanet, ROOT or Jpp!

Questions
=========

If you have a question about km3io, please proceed as follows:

- Read the documentation below.
- Explore the `examples <https://km3py.pages.km3net.de/km3io/examples.html>`__ in the documentation.
- Haven't you found an answer to your question in the documentation, post a git issue with your question showing us an example of what you have tried first, and what you would like to do.
- Have you noticed a bug, please post it in a git issue, we appreciate your contribution.


Introduction
------------

Most of km3net data is stored in root files. These root files are created using the `KM3NeT Dataformat library <https://git.km3net.de/common/km3net-dataformat>`__
A ROOT file created with
`Jpp <https://git.km3net.de/common/jpp>`__ is an "online" file and all other software usually produces "offline" files.

km3io is a Python package that provides a set of classes: ``OnlineReader``, ``OfflineReader`` and a special class to read gSeaGen files. All of these ROOT files can be read installing any other software like Jpp, aanet or ROOT.

Data in km3io is returned as ``awkward.Array`` which is an advance Numpy-like container type to store
contiguous data for high performance computations.
Such an ``awkward.Array`` supports any level of nested arrays and records which can have different lengths, in contrast to Numpy where everything has to be rectangular.

The example is shown below shows the array which contains the ``dir_z`` values
of each track of the first 4 events. The type ``4 * var * float64`` means that
it has 4 subarrays with variable lengths of type ``float64``:

.. code-block:: python3

    >>> import km3io
    >>> from km3net_testdata import data_path
    >>> f = km3io.OfflineReader(data_path("offline/numucc.root"))
    >>> f[:4].tracks.dir_z
    <Array [[0.213, 0.213, ... 0.229, 0.323]] type='4 * var * float64'>

The same concept applies to all other branches, including ``hits``, ``mc_hits``,
``mc_tracks``, ``t_sec`` etc.

Architecture overview
---------------------

``km3io`` utilises ``uproot`` behind the scenes and creates a lazy and thin
wrapper which offers convenient slicing and iterations by delaying the access to
the actual ROOT data branches to the very last moment. When using the iteration
functionality, the data is loaded in chunks and the iteration is done over e.g.
events in each chunk or a bunch of frames in case of the summaryslice reader.

The base class for the event-based readout is the ``km3io.rootio.EventReader``
class. When subclassing this class, the branches, aliases and nested branches
need to be defined in the static variables which are then used to mask unwanted
attributes. Especially in case of the Offline ROOT format, where the "one class
fits all" design was chosen, it is distracting that e.g. a `Hit` has many
attributes which make no sense depending on the context (MC hit, raw hit etc.).
By specifing the branches explicitely, the user API will only expose the
meaningful fields.

The online ROOT format support is partly still based on ``uproot3``.

Many of the utility functions are using Numba to achieve the best possible
performance. ``km3io`` does not offer alternative implementations, so Numba is a
strict dependency and an integral part of the implementation.


Offline files reader
--------------------

In general an offline file has two attributes to access data: the header and the events. Let's start with the header.

Reading the file header
"""""""""""""""""""""""

To read an offline file start with opening it with the ``OfflineReader``:

.. code-block:: python3

  >>> import km3io
  >>> from km3net_testdata import data_path
  >>> f = km3io.OfflineReader(data_path("offline/numucc.root"))

Accessing is as easy as typing:

.. code-block:: python3

  >>> f.header
  <km3io.offline.Header at 0x7fcd81025990>

Printing it will give an overview of the structure:

.. code-block:: python3

  >>> print(f.header)
  MC Header:
  DAQ(livetime=394)
  PDF(i1=4, i2=58)
  can(zmin=0, zmax=1027, r=888.4)
  can_user: can_user(field_0=0.0, field_1=1027.0, field_2=888.4)
  coord_origin(x=0, y=0, z=0)
  cut_in(Emin=0, Emax=0, cosTmin=0, cosTmax=0)
  cut_nu(Emin=100, Emax=100000000.0, cosTmin=-1, cosTmax=1)
  cut_primary(Emin=0, Emax=0, cosTmin=0, cosTmax=0)
  cut_seamuon(Emin=0, Emax=0, cosTmin=0, cosTmax=0)
  decay: decay(field_0='doesnt', field_1='happen')
  detector: NOT
  drawing: Volume
  genhencut(gDir=2000, Emin=0)
  genvol(zmin=0, zmax=1027, r=888.4, volume=2649000000.0, numberOfEvents=100000)
  kcut: 2
  livetime(numberOfSeconds=0, errorOfSeconds=0)
  model(interaction=1, muon=2, scattering=0, numberOfEnergyBins=1, field_4=12)
  ngen: 100000.0
  norma(primaryFlux=0, numberOfPrimaries=0)
  nuflux: nuflux(field_0=0, field_1=3, field_2=0, field_3=0.5, field_4=0.0, field_5=1.0, field_6=3.0)
  physics(program='GENHEN', version='7.2-220514', date=181116, time=1138)
  seed(program='GENHEN', level=3, iseed=305765867, field_3=0, field_4=0)
  simul(program='JSirene', version=11012, date='11/17/18', time=7)
  sourcemode: diffuse
  spectrum(alpha=-1.4)
  start_run(run_id=1)
  target: isoscalar
  usedetfile: false
  xlat_user: 0.63297
  xparam: OFF
  zed_user: zed_user(field_0=0.0, field_1=3450.0)

To read the values in the header one can call them directly, as the structures
are simple ``namedtuple``-like objects:

.. code-block:: python3

  >>> f.header.DAQ.livetime
  394
  >>> f.header.cut_nu.Emin
  100
  >>> f.header.genvol.numberOfEvents
  100000


Reading offline events
""""""""""""""""""""""

Events are at the top level of an offline file, so that each branch of an event
is directly accessible at the ``OfflineReader`` instance. The ``.keys()`` method
can be used to list the available attributes. Notice that some of them are aliases
for backwards compatibility (like ``mc_tracks`` and ``mc_trks``). Another
backwards compatibility feature is the ``f.events`` attribute which is simply
mapping everything to ``f``, so that ``f.events.mc_tracks`` is the same as
``f.mc_tracks``.

.. code-block:: python3

  >>> f
  OfflineReader (10 events)
  >>> f.keys()
  {'comment', 'det_id', 'flags', 'frame_index', 'hits', 'id', 'index',
  'mc_hits', 'mc_id', 'mc_run_id', 'mc_t', 'mc_tracks', 'mc_trks',
  'n_hits', 'n_mc_hits', 'n_mc_tracks', 'n_mc_trks', 'n_tracks',
  'n_trks', 'overlays', 'run_id', 't_ns', 't_sec', 'tracks',
  'trigger_counter', 'trigger_mask', 'trks', 'usr', 'usr_names',
  'w', 'w2list', 'w3list'}
  >>> f.tracks
  <Branch [10] path='trks'>
  >>> f.events.tracks
  <Branch [10] path='trks'>

The ``[10]`` denotes that there are ``10`` events available, each containing a sub-array of ``tracks``.

Using <TAB> completion gives an overview of available data. Alternatively the attribute `fields`
can be used on event-branches and to see what is available for reading.

.. code-block:: python3

  >>> f.tracks.fields
  ['id',
  'pos_x',
  'pos_y',
  'pos_z',
  'dir_x',
  'dir_y',
  'dir_z',
  't',
  'E',
  'len',
  'lik',
  'rec_type',
  'rec_stages',
  'fitinf']


Reading the reconstructed values like energy and direction of an event can be done with:

.. code-block:: python3

  >>> f.events.tracks.E
  <Array [[117, 117, 0, 0, 0, ... 0, 0, 0, 0, 0]] type='10 * var * float64'>

The ``Array`` in this case is an `awkward <https://awkward-array.readthedocs.io>`__ array with the data type
``10 * var * float64`` which means that there are ``10`` sub-arrays with ``var``iable lengths of type ``float64``.
Awkward arrays allow high-performance access to arrays which are not rectangular (in contrast to ``numpy``).
Read the documention of AwkwardArray to learn how to work with these structures efficiently. One example
to retrieve the energy of the very first reconstructed track for the first three events is:

.. code-block:: python3

  >>> f.events.tracks.E[:3, 0]
  <Array [117, 4.4e+03, 8.37] type='3 * float64'>

Online files reader
-------------------

``km3io`` is able to read events, summary slices and timeslices. Timeslices are
currently only supported with split level of 2 or more, which means that reading
L0 timeslices is not working at the moment (but is in progress).

Let's have a look at some online data.

Reading online events
"""""""""""""""""""""

Now we use the ``OnlineReader`` to create our file object.

.. code-block:: python3

  import km3io
  f = km3io.OnlineReader(data_path("online/km3net_online.root"))


That's it, we created an object which gives access to all the events, but the
relevant data is still not loaded into the memory (lazy access)!
The structure is different compared to the ``OfflineReader``
because online files contain additional branches at the top level
(summaryslices and timeslices).

.. code-block:: python3

  >>> f.events
  Number of events: 3
  >>> f.events.snapshot_hits[1].tot[:10]
  array([27, 24, 21, 17, 22, 15, 24, 30, 19, 15], dtype=uint8)
  >>> f.events.triggered_hits[1].channel_id[:10]
  array([ 2,  3, 16, 22, 23,  0,  2,  3,  4,  5], dtype=uint8)

The resulting arrays are numpy arrays. The indexing convention is: the first indexing
corresponds to the event, the second to the branch and consecutive ones to the
optional dimensions of the arrays. In the last step we accessed the PMT channel IDs
of the first 10 hits of the second event.

Reading SummarySlices
"""""""""""""""""""""

The following example shows how to access summary slices. The summary slices are
returned in chunks to be more efficient with the I/O. The default chunk-size is
1000. In the example file we only have three summaryslices, so there is only a single
chunk. The first index passed to the summaryslices reader is corresponding to the
chunk and the second to the index of the summaryslice in that chunk.

.. code-block:: python3

  >>> f.summaryslices
  <SummarysliceReader 3 items, step_size=1000 (1 chunk)>
  >>> f.summaryslices[0]
  SummarysliceChunk(headers=<Array [{' cnt': 671088704, ... ] type='3 * {" cnt": uint32, " vers": uint16, " ...'>, slices=<Array [[{dom_id: 806451572, ... ch30: 48}]] type='3 * var * {"dom_id": int32, "...'>)
  >>> f.summaryslices[0].headers
  <Array [{' cnt': 671088704, ... ] type='3 * {" cnt": uint32, " vers": uint16, " ...'>
  >>> f.summaryslices[0].slices[2]
  <Array [{dom_id: 806451572, ... ch30: 48}] type='68 * {"dom_id": int32, "dq_stat...'>
  >>> f.summaryslices[0].slices[2].dom_id
  <Array [806451572, 806455814, ... 809544061] type='68 * int32'>
  >>> f.summaryslices[0].slices[2].ch23
  <Array [48, 43, 46, 54, 83, ... 51, 51, 52, 50] type='68 * uint8'>

Reading Timeslices
""""""""""""""""""

Timeslices are split into different streams since 2017 and ``km3io`` currently
supports everything except L0, i.e. L1, L2 and SN streams. The API is
work-in-progress and will be improved in future, however, all the data is
already accessible (although in ugly ways ;-)

To access the timeslice data, you need to specify which timeslice stream
to read:

.. code-block:: python3

  >>> f.timeslices
  Available timeslice streams: SN, L1
  >>> f.timeslices.stream("L1", 0).frames
  {806451572: <Table [<Row 0> <Row 1> <Row 2> ... <Row 981> <Row 982> <Row 983>] at 0x00014c167340>,
  806455814: <Table [<Row 984> <Row 985> <Row 986> ... <Row 1985> <Row 1986> <Row 1987>] at 0x00014c5f4760>,
  806465101: <Table [<Row 1988> <Row 1989> <Row 1990> ... <Row 2236> <Row 2237> <Row 2238>] at 0x00014c5f45e0>,
  806483369: <Table [<Row 2239> <Row 2240> <Row 2241> ... <Row 2965> <Row 2966> <Row 2967>] at 0x00014c12b910>,
  ...
  809544061: <Table [<Row 48517> <Row 48518> <Row 48519> ... <Row 49240> <Row 49241> <Row 49242>] at 0x00014ca57100>}

The frames are represented by a dictionary where the key is the ``DOM ID`` and
the value an awkward array of hits, with the usual fields to access the PMT
channel, time and ToT:

.. code-block:: python3

   >>> f.timeslices.stream("L1", 0).frames[809524432].dtype
   dtype([('pmt', 'u1'), ('tdc', '<u4'), ('tot', 'u1')])
   >>> f.timeslices.stream("L1", 0).frames[809524432].tot
  array([25, 27, 28, ..., 29, 22, 28], dtype=uint8)






            

Raw data

            {
    "_id": null,
    "home_page": "https://git.km3net.de/km3py/km3io",
    "name": "km3io",
    "maintainer": "Tamas Gal",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "tgal@km3net.de",
    "keywords": "neutrino,astroparticle,physics,HEP,root",
    "author": "\"Tamas Gal and Zineb Aly\"",
    "author_email": "tgal@km3net.de",
    "download_url": "https://files.pythonhosted.org/packages/72/d7/fe7fee7d0f0bb93498209426dce67a70d822302cc145074bb927ab7230ee/km3io-1.0.2.tar.gz",
    "platform": null,
    "description": "The km3io Python package\n========================\n\n.. image:: https://git.km3net.de/km3py/km3io/badges/master/pipeline.svg\n    :target: https://git.km3net.de/km3py/km3io/pipelines\n\n.. image:: https://git.km3net.de/km3py/km3io/badges/master/coverage.svg\n    :target: https://km3py.pages.km3net.de/km3io/coverage\n\n.. image:: https://git.km3net.de/examples/km3badges/-/raw/master/docs-latest-brightgreen.svg\n    :target: https://km3py.pages.km3net.de/km3io\n\n.. image:: https://zenodo.org/badge/DOI/10.5281/zenodo.7382620.svg\n   :target: https://doi.org/10.5281/zenodo.7382620\n\nThis software provides a set of Python classes to read KM3NeT ROOT files\nwithout having ROOT, Jpp or aanet installed. It only depends on Python 3.5+ and the amazing `uproot <https://github.com/scikit-hep/uproot>`__ package and gives you access to the data via `numpy <https://www.numpy.org>`__ and `awkward <https://awkward-array.readthedocs.io>`__ arrays.\n\nIt's very easy to use and according to the `uproot <https://github.com/scikit-hep/uproot>`__ benchmarks, it is able to outperform the original ROOT I/O performance. \n\nInstallation\n============\n\nInstall km3io using pip::\n\n    pip install km3io \n\nor conda::\n\n    conda install km3io\n\nTo get the latest (stable) development release::\n\n    pip install git+https://git.km3net.de/km3py/km3io.git\n\nDocker::\n\n    docker run -it docker.km3net.de/km3io\n\nSingularity::\n\n    wget https://sftp.km3net.de/singularity/km3io_v0.27.2.sif  # pick the version you like\n    singularity shell km3io_v0.27.2.sif\n\n**Reminder:** km3io is **not** dependent on aanet, ROOT or Jpp!\n\nQuestions\n=========\n\nIf you have a question about km3io, please proceed as follows:\n\n- Read the documentation below.\n- Explore the `examples <https://km3py.pages.km3net.de/km3io/examples.html>`__ in the documentation.\n- Haven't you found an answer to your question in the documentation, post a git issue with your question showing us an example of what you have tried first, and what you would like to do.\n- Have you noticed a bug, please post it in a git issue, we appreciate your contribution.\n\n\nIntroduction\n------------\n\nMost of km3net data is stored in root files. These root files are created using the `KM3NeT Dataformat library <https://git.km3net.de/common/km3net-dataformat>`__\nA ROOT file created with\n`Jpp <https://git.km3net.de/common/jpp>`__ is an \"online\" file and all other software usually produces \"offline\" files.\n\nkm3io is a Python package that provides a set of classes: ``OnlineReader``, ``OfflineReader`` and a special class to read gSeaGen files. All of these ROOT files can be read installing any other software like Jpp, aanet or ROOT.\n\nData in km3io is returned as ``awkward.Array`` which is an advance Numpy-like container type to store\ncontiguous data for high performance computations.\nSuch an ``awkward.Array`` supports any level of nested arrays and records which can have different lengths, in contrast to Numpy where everything has to be rectangular.\n\nThe example is shown below shows the array which contains the ``dir_z`` values\nof each track of the first 4 events. The type ``4 * var * float64`` means that\nit has 4 subarrays with variable lengths of type ``float64``:\n\n.. code-block:: python3\n\n    >>> import km3io\n    >>> from km3net_testdata import data_path\n    >>> f = km3io.OfflineReader(data_path(\"offline/numucc.root\"))\n    >>> f[:4].tracks.dir_z\n    <Array [[0.213, 0.213, ... 0.229, 0.323]] type='4 * var * float64'>\n\nThe same concept applies to all other branches, including ``hits``, ``mc_hits``,\n``mc_tracks``, ``t_sec`` etc.\n\nArchitecture overview\n---------------------\n\n``km3io`` utilises ``uproot`` behind the scenes and creates a lazy and thin\nwrapper which offers convenient slicing and iterations by delaying the access to\nthe actual ROOT data branches to the very last moment. When using the iteration\nfunctionality, the data is loaded in chunks and the iteration is done over e.g.\nevents in each chunk or a bunch of frames in case of the summaryslice reader.\n\nThe base class for the event-based readout is the ``km3io.rootio.EventReader``\nclass. When subclassing this class, the branches, aliases and nested branches\nneed to be defined in the static variables which are then used to mask unwanted\nattributes. Especially in case of the Offline ROOT format, where the \"one class\nfits all\" design was chosen, it is distracting that e.g. a `Hit` has many\nattributes which make no sense depending on the context (MC hit, raw hit etc.).\nBy specifing the branches explicitely, the user API will only expose the\nmeaningful fields.\n\nThe online ROOT format support is partly still based on ``uproot3``.\n\nMany of the utility functions are using Numba to achieve the best possible\nperformance. ``km3io`` does not offer alternative implementations, so Numba is a\nstrict dependency and an integral part of the implementation.\n\n\nOffline files reader\n--------------------\n\nIn general an offline file has two attributes to access data: the header and the events. Let's start with the header.\n\nReading the file header\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nTo read an offline file start with opening it with the ``OfflineReader``:\n\n.. code-block:: python3\n\n  >>> import km3io\n  >>> from km3net_testdata import data_path\n  >>> f = km3io.OfflineReader(data_path(\"offline/numucc.root\"))\n\nAccessing is as easy as typing:\n\n.. code-block:: python3\n\n  >>> f.header\n  <km3io.offline.Header at 0x7fcd81025990>\n\nPrinting it will give an overview of the structure:\n\n.. code-block:: python3\n\n  >>> print(f.header)\n  MC Header:\n  DAQ(livetime=394)\n  PDF(i1=4, i2=58)\n  can(zmin=0, zmax=1027, r=888.4)\n  can_user: can_user(field_0=0.0, field_1=1027.0, field_2=888.4)\n  coord_origin(x=0, y=0, z=0)\n  cut_in(Emin=0, Emax=0, cosTmin=0, cosTmax=0)\n  cut_nu(Emin=100, Emax=100000000.0, cosTmin=-1, cosTmax=1)\n  cut_primary(Emin=0, Emax=0, cosTmin=0, cosTmax=0)\n  cut_seamuon(Emin=0, Emax=0, cosTmin=0, cosTmax=0)\n  decay: decay(field_0='doesnt', field_1='happen')\n  detector: NOT\n  drawing: Volume\n  genhencut(gDir=2000, Emin=0)\n  genvol(zmin=0, zmax=1027, r=888.4, volume=2649000000.0, numberOfEvents=100000)\n  kcut: 2\n  livetime(numberOfSeconds=0, errorOfSeconds=0)\n  model(interaction=1, muon=2, scattering=0, numberOfEnergyBins=1, field_4=12)\n  ngen: 100000.0\n  norma(primaryFlux=0, numberOfPrimaries=0)\n  nuflux: nuflux(field_0=0, field_1=3, field_2=0, field_3=0.5, field_4=0.0, field_5=1.0, field_6=3.0)\n  physics(program='GENHEN', version='7.2-220514', date=181116, time=1138)\n  seed(program='GENHEN', level=3, iseed=305765867, field_3=0, field_4=0)\n  simul(program='JSirene', version=11012, date='11/17/18', time=7)\n  sourcemode: diffuse\n  spectrum(alpha=-1.4)\n  start_run(run_id=1)\n  target: isoscalar\n  usedetfile: false\n  xlat_user: 0.63297\n  xparam: OFF\n  zed_user: zed_user(field_0=0.0, field_1=3450.0)\n\nTo read the values in the header one can call them directly, as the structures\nare simple ``namedtuple``-like objects:\n\n.. code-block:: python3\n\n  >>> f.header.DAQ.livetime\n  394\n  >>> f.header.cut_nu.Emin\n  100\n  >>> f.header.genvol.numberOfEvents\n  100000\n\n\nReading offline events\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nEvents are at the top level of an offline file, so that each branch of an event\nis directly accessible at the ``OfflineReader`` instance. The ``.keys()`` method\ncan be used to list the available attributes. Notice that some of them are aliases\nfor backwards compatibility (like ``mc_tracks`` and ``mc_trks``). Another\nbackwards compatibility feature is the ``f.events`` attribute which is simply\nmapping everything to ``f``, so that ``f.events.mc_tracks`` is the same as\n``f.mc_tracks``.\n\n.. code-block:: python3\n\n  >>> f\n  OfflineReader (10 events)\n  >>> f.keys()\n  {'comment', 'det_id', 'flags', 'frame_index', 'hits', 'id', 'index',\n  'mc_hits', 'mc_id', 'mc_run_id', 'mc_t', 'mc_tracks', 'mc_trks',\n  'n_hits', 'n_mc_hits', 'n_mc_tracks', 'n_mc_trks', 'n_tracks',\n  'n_trks', 'overlays', 'run_id', 't_ns', 't_sec', 'tracks',\n  'trigger_counter', 'trigger_mask', 'trks', 'usr', 'usr_names',\n  'w', 'w2list', 'w3list'}\n  >>> f.tracks\n  <Branch [10] path='trks'>\n  >>> f.events.tracks\n  <Branch [10] path='trks'>\n\nThe ``[10]`` denotes that there are ``10`` events available, each containing a sub-array of ``tracks``.\n\nUsing <TAB> completion gives an overview of available data. Alternatively the attribute `fields`\ncan be used on event-branches and to see what is available for reading.\n\n.. code-block:: python3\n\n  >>> f.tracks.fields\n  ['id',\n  'pos_x',\n  'pos_y',\n  'pos_z',\n  'dir_x',\n  'dir_y',\n  'dir_z',\n  't',\n  'E',\n  'len',\n  'lik',\n  'rec_type',\n  'rec_stages',\n  'fitinf']\n\n\nReading the reconstructed values like energy and direction of an event can be done with:\n\n.. code-block:: python3\n\n  >>> f.events.tracks.E\n  <Array [[117, 117, 0, 0, 0, ... 0, 0, 0, 0, 0]] type='10 * var * float64'>\n\nThe ``Array`` in this case is an `awkward <https://awkward-array.readthedocs.io>`__ array with the data type\n``10 * var * float64`` which means that there are ``10`` sub-arrays with ``var``iable lengths of type ``float64``.\nAwkward arrays allow high-performance access to arrays which are not rectangular (in contrast to ``numpy``).\nRead the documention of AwkwardArray to learn how to work with these structures efficiently. One example\nto retrieve the energy of the very first reconstructed track for the first three events is:\n\n.. code-block:: python3\n\n  >>> f.events.tracks.E[:3, 0]\n  <Array [117, 4.4e+03, 8.37] type='3 * float64'>\n\nOnline files reader\n-------------------\n\n``km3io`` is able to read events, summary slices and timeslices. Timeslices are\ncurrently only supported with split level of 2 or more, which means that reading\nL0 timeslices is not working at the moment (but is in progress).\n\nLet's have a look at some online data.\n\nReading online events\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nNow we use the ``OnlineReader`` to create our file object.\n\n.. code-block:: python3\n\n  import km3io\n  f = km3io.OnlineReader(data_path(\"online/km3net_online.root\"))\n\n\nThat's it, we created an object which gives access to all the events, but the\nrelevant data is still not loaded into the memory (lazy access)!\nThe structure is different compared to the ``OfflineReader``\nbecause online files contain additional branches at the top level\n(summaryslices and timeslices).\n\n.. code-block:: python3\n\n  >>> f.events\n  Number of events: 3\n  >>> f.events.snapshot_hits[1].tot[:10]\n  array([27, 24, 21, 17, 22, 15, 24, 30, 19, 15], dtype=uint8)\n  >>> f.events.triggered_hits[1].channel_id[:10]\n  array([ 2,  3, 16, 22, 23,  0,  2,  3,  4,  5], dtype=uint8)\n\nThe resulting arrays are numpy arrays. The indexing convention is: the first indexing\ncorresponds to the event, the second to the branch and consecutive ones to the\noptional dimensions of the arrays. In the last step we accessed the PMT channel IDs\nof the first 10 hits of the second event.\n\nReading SummarySlices\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nThe following example shows how to access summary slices. The summary slices are\nreturned in chunks to be more efficient with the I/O. The default chunk-size is\n1000. In the example file we only have three summaryslices, so there is only a single\nchunk. The first index passed to the summaryslices reader is corresponding to the\nchunk and the second to the index of the summaryslice in that chunk.\n\n.. code-block:: python3\n\n  >>> f.summaryslices\n  <SummarysliceReader 3 items, step_size=1000 (1 chunk)>\n  >>> f.summaryslices[0]\n  SummarysliceChunk(headers=<Array [{' cnt': 671088704, ... ] type='3 * {\" cnt\": uint32, \" vers\": uint16, \" ...'>, slices=<Array [[{dom_id: 806451572, ... ch30: 48}]] type='3 * var * {\"dom_id\": int32, \"...'>)\n  >>> f.summaryslices[0].headers\n  <Array [{' cnt': 671088704, ... ] type='3 * {\" cnt\": uint32, \" vers\": uint16, \" ...'>\n  >>> f.summaryslices[0].slices[2]\n  <Array [{dom_id: 806451572, ... ch30: 48}] type='68 * {\"dom_id\": int32, \"dq_stat...'>\n  >>> f.summaryslices[0].slices[2].dom_id\n  <Array [806451572, 806455814, ... 809544061] type='68 * int32'>\n  >>> f.summaryslices[0].slices[2].ch23\n  <Array [48, 43, 46, 54, 83, ... 51, 51, 52, 50] type='68 * uint8'>\n\nReading Timeslices\n\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\"\n\nTimeslices are split into different streams since 2017 and ``km3io`` currently\nsupports everything except L0, i.e. L1, L2 and SN streams. The API is\nwork-in-progress and will be improved in future, however, all the data is\nalready accessible (although in ugly ways ;-)\n\nTo access the timeslice data, you need to specify which timeslice stream\nto read:\n\n.. code-block:: python3\n\n  >>> f.timeslices\n  Available timeslice streams: SN, L1\n  >>> f.timeslices.stream(\"L1\", 0).frames\n  {806451572: <Table [<Row 0> <Row 1> <Row 2> ... <Row 981> <Row 982> <Row 983>] at 0x00014c167340>,\n  806455814: <Table [<Row 984> <Row 985> <Row 986> ... <Row 1985> <Row 1986> <Row 1987>] at 0x00014c5f4760>,\n  806465101: <Table [<Row 1988> <Row 1989> <Row 1990> ... <Row 2236> <Row 2237> <Row 2238>] at 0x00014c5f45e0>,\n  806483369: <Table [<Row 2239> <Row 2240> <Row 2241> ... <Row 2965> <Row 2966> <Row 2967>] at 0x00014c12b910>,\n  ...\n  809544061: <Table [<Row 48517> <Row 48518> <Row 48519> ... <Row 49240> <Row 49241> <Row 49242>] at 0x00014ca57100>}\n\nThe frames are represented by a dictionary where the key is the ``DOM ID`` and\nthe value an awkward array of hits, with the usual fields to access the PMT\nchannel, time and ToT:\n\n.. code-block:: python3\n\n   >>> f.timeslices.stream(\"L1\", 0).frames[809524432].dtype\n   dtype([('pmt', 'u1'), ('tdc', '<u4'), ('tot', 'u1')])\n   >>> f.timeslices.stream(\"L1\", 0).frames[809524432].tot\n  array([25, 27, 28, ..., 29, 22, 28], dtype=uint8)\n\n\n\n\n\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": "\"KM3NeT I/O library without ROOT\"",
    "version": "1.0.2",
    "project_urls": {
        "Homepage": "https://git.km3net.de/km3py/km3io"
    },
    "split_keywords": [
        "neutrino",
        "astroparticle",
        "physics",
        "hep",
        "root"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "742cc597d81ff1631dd69c9565b4cb13c5df1017a09825a61e84ee10f8ec9975",
                "md5": "98fbe105173c566c38ba58bdf0e93f34",
                "sha256": "3f3fd41c87b8be53efa11a751d5524d55e192ac5ff17cb47bd06f5e3d32b5a67"
            },
            "downloads": -1,
            "filename": "km3io-1.0.2-py2.py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "98fbe105173c566c38ba58bdf0e93f34",
            "packagetype": "bdist_wheel",
            "python_version": "py2.py3",
            "requires_python": ">=3.6",
            "size": 34181,
            "upload_time": "2023-10-08T21:40:55",
            "upload_time_iso_8601": "2023-10-08T21:40:55.280573Z",
            "url": "https://files.pythonhosted.org/packages/74/2c/c597d81ff1631dd69c9565b4cb13c5df1017a09825a61e84ee10f8ec9975/km3io-1.0.2-py2.py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "72d7fe7fee7d0f0bb93498209426dce67a70d822302cc145074bb927ab7230ee",
                "md5": "0663fa0654f9c6d467adef4bb1815c99",
                "sha256": "0eb6a4d5820214f912c04aebecc7e7c5f12b7af5b63aeb97496f5fd53226ad86"
            },
            "downloads": -1,
            "filename": "km3io-1.0.2.tar.gz",
            "has_sig": false,
            "md5_digest": "0663fa0654f9c6d467adef4bb1815c99",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 306150,
            "upload_time": "2023-10-08T21:40:57",
            "upload_time_iso_8601": "2023-10-08T21:40:57.783152Z",
            "url": "https://files.pythonhosted.org/packages/72/d7/fe7fee7d0f0bb93498209426dce67a70d822302cc145074bb927ab7230ee/km3io-1.0.2.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-10-08 21:40:57",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "km3io"
}
        
Elapsed time: 0.17085s