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 package and gives you access to the data via numpy arrays.
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 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 ROOT I/O performance.
...
...
@@ -59,6 +58,17 @@ Tutorial
* `Offline files reader <#offline-file-reader>`__
* `reading events data <#reading-events-data>`__
* `reading hits data <#reading-hits-data>`__
* `reading tracks data <#reading-tracks-data>`__
* `reading mc hits data <#reading-mc-hits-data>`__
* `reading mc tracks data <#reading-mc-tracks-data>`__
Introduction
------------
...
...
@@ -67,7 +77,7 @@ Most of km3net data is stored in root files. These root files are either created
km3io is a Python package that provides a set of classes (``DaqReader`` and ``OfflineReader``) to read both daq root files and offline root files without any dependency to aanet, Jpp or ROOT.
Data in km3io is often returned as a "lazyarray", a "jagged lazyarray", "a jagged array" or a Numpy array. A lazyarray is an array-like object that reads data on demand! In a lazyarray, only the first and the last chunks of data are read in memory. A lazyarray can be used with all Numpy's universal `functions <https://docs.scipy.org/doc/numpy/referenceufuncs.html>`__. Here is how a lazyarray looks like:
Data in km3io is often returned as a "lazyarray", a "jagged lazyarray" or a `Numpy <https://docs.scipy.org/doc/numpy>`__ array. A lazyarray is an array-like object that reads data on demand! In a lazyarray, only the first and the last chunks of data are read in memory. A lazyarray can be used with all Numpy's universal `functions <https://docs.scipy.org/doc/numpy/reference/ufuncs.html>`__. Here is how a lazyarray looks like:
.. code-block:: python3
...
...
@@ -112,10 +122,10 @@ That's it! Now let's have a look at the hits data:
In the following, we will explore each tree using km3io package.
reading events data
"""""""""""""""""""
to read data in events tree with km3io:
.. code-block:: python3
>>> r.events
<OfflineEvents: 10 parsed events>
to get the total number of events in the events tree:
.. code-block:: python3
>>> len(r.events)
10
the branches stored in the events tree in an offline file can be easily accessed with a tab completion as seen below:
.. image:: /home/zineb/Desktop/events.png
to get data from the events tree, chose any branch of interest with the tab completion, the following is a non exaustive set of examples.
to get event ids:
.. code-block:: python3
>>> r.events.id
<ChunkedArray [1 2 3 ... 8 9 10] at 0x7f249eeb6f10>
to get detector ids:
.. code-block:: python3
>>> r.events.det_id
<ChunkedArray [44 44 44 ... 44 44 44] at 0x7f249eeba050>
to get frame_index:
.. code-block:: python3
>>> r.events.frame_index
<ChunkedArray [182 183 202 ... 185 185 204] at 0x7f249eeba410>
to get snapshot hits:
.. code-block:: python3
>>> r.events.hits
<ChunkedArray [176 125 318 ... 84 255 105] at 0x7f249eebaa10>
to illustrate the strength of this data structure, we will play around with `r.events.hits` using Numpy universal `functions <https://docs.scipy.org/doc/numpy/reference/ufuncs.html>`__.
.. code-block:: python3
>>> import numpy as np
>>> np.log(r.events.hits)
<ChunkedArray [5.170483995038151 4.8283137373023015 5.762051382780177 ... 4.430816798843313 5.541263545158426 4.653960350157523] at 0x7f249b8ebb90>
to get all data from one specific event (for example event 0):
.. code-block:: python3
>>> r.events[0]
offline event:
id : 1
det_id : 44
mc_id : 0
run_id : 5971
mc_run_id : 0
frame_index : 182
trigger_mask : 22
trigger_counter : 0
overlays : 60
hits : 176
trks : 56
w : []
w2list : []
w3list : []
mc_t : 0.0
mc_hits : 0
mc_trks : 0
comment : b''
index : 0
flags : 0
t_fSec : 1567036818
t_fNanoSec : 200000000
to get a specific value from event 0, for example the number of overlays:
.. code-block:: python3
>>> r.events[0].overlays
60
>>> reader[5]['trks']
56
So event 5 has exactly 60 hits and 56 tracks. Let's explore in more details
if you are interested in a specific event (let's say event 0), you can access the corresponding hits tree by doing the following:
.. code-block:: python3
>>> r[0].hits
<OfflineHits: 176 parsed elements>
notice that now there are 176 parsed elements (as opposed to 10 elements parsed when r.hits is called). This means that in event 0 there are 176 hits! To get the dom ids from this event:
if you are interested in a specific event (let's say event 0), you can access the corresponding tracks tree by doing the following:
.. code-block:: python3
>>> r[0].tracks
<OfflineTracks: 56 parsed elements>
notice that now there are 56 parsed elements (as opposed to 10 elements parsed when r.tracks is called). This means that in event 0 there is data about 56 possible tracks! To get the tracks likelihood from this event:
to get all data of a specific track (let's say track 0) from event 0:
.. code-block:: python3
>>>r[0].tracks[0]
offline track:
fUniqueID : 0
fBits : 33554432
id : 1
pos_x : 445.835395997812
pos_y : 615.1089636184813
pos_z : 125.1448339836911
dir_x : 0.0368711082700674
dir_y : -0.48653048395923415
dir_z : -0.872885221293917
t : 70311446.46401498
E : 99.10458562488608
len : 0.0
lik : 294.6407542676734
type : 0
rec_type : 4000
rec_stages : [1, 3, 5, 4]
status : 0
mother_id : -1
hit_ids : []
error_matrix : []
comment : 0
JGANDALF_BETA0_RAD : 0.004957442219414389
JGANDALF_BETA1_RAD : 0.003417848024252858
JGANDALF_CHI2 : -294.6407542676734
JGANDALF_NUMBER_OF_HITS : 142.0
JENERGY_ENERGY : 99.10458562488608
JENERGY_CHI2 : 1.7976931348623157e+308
JGANDALF_LAMBDA : 4.2409761837248484e-12
JGANDALF_NUMBER_OF_ITERATIONS : 10.0
JSTART_NPE_MIP : 24.88469697331908
JSTART_NPE_MIP_TOTAL : 55.88169412579765
JSTART_LENGTH_METRES : 98.89582506402911
JVETO_NPE : 0.0
JVETO_NUMBER_OF_HITS : 0.0
JENERGY_MUON_RANGE_METRES : 344.9767431592819
JENERGY_NOISE_LIKELIHOOD : -333.87773581129136
JENERGY_NDF : 1471.0
JENERGY_NUMBER_OF_HITS : 101.0
to get a specific value from track 0 in event 0, let's say for example the liklihood:
.. code-block:: python3
>>>r[0].tracks[0].lik
294.6407542676734
reading mc hits data
""""""""""""""""""""
to read mc hits data:
.. code-block:: python3
>>>r.mc_hits
<OfflineHits: 10 parsed elements>
that's it! All branches in mc hits tree can be accessed in the exact same way described in the section `reading hits data <#reading-hits-data>`__ . All data is easily accesible and if you are stuck, hit tab key to see all the available branches:
.. image:: /home/zineb/Desktop/mc_hits.png
reading mc tracks data
""""""""""""""""""""""
to read mc tracks data:
.. code-block:: python3
>>>r.mc_tracks
<OfflineTracks: 10 parsed elements>
that's it! All branches in mc tracks tree can be accessed in the exact same way described in the section `reading tracks data <#reading-tracks-data>`__ . All data is easily accesible and if you are stuck, hit tab key to see all the available branches: