From d8a4b7203952bb7bd85cbf6d2ed481d610c83e67 Mon Sep 17 00:00:00 2001 From: Jim Pivarski Date: Wed, 16 Sep 2020 19:58:08 -0500 Subject: [PATCH] Start writing the readthedocs. (#101) * Start writing the readthedocs. * Writing. * Writing. * Can't get the sidebar right. * Determining documentation organization. * Generating documentation for all the docstrings; need to fix many warnings. * Touching up the front page a little. * Fixed all Sphinx warnings. * Report is now a regular class that can be documented. * Writing. * Writing. * Writing. * Writing. * Finished the 'Getting started guide'. --- .gitignore | 6 + .readthedocs.yml | 9 + README.md | 16 +- docs-img/logo/logo-300px-white.png | Bin 0 -> 6794 bytes docs-sphinx/basic.rst | 994 ++++++++++++++++++++++++++++ docs-sphinx/conf.py | 57 ++ docs-sphinx/index.rst | 91 +++ docs-sphinx/make_changelog.py | 135 ++++ docs-sphinx/prepare_docstrings.py | 188 ++++++ docs-sphinx/requirements.txt | 1 + docs-sphinx/uproot3-to-4.rst | 6 + uproot4/__init__.py | 76 +-- uproot4/behaviors/TBranch.py | 552 +++++++++------ uproot4/behaviors/TBranchElement.py | 6 +- uproot4/behaviors/TH1.py | 2 +- uproot4/behaviors/TProfile.py | 4 +- uproot4/behaviors/TTree.py | 24 +- uproot4/behaviors/__init__.py | 4 +- uproot4/cache.py | 4 +- uproot4/compression.py | 20 +- uproot4/containers.py | 122 ++-- uproot4/deserialization.py | 82 +-- uproot4/dynamic.py | 8 +- uproot4/extras.py | 5 +- uproot4/interpretation/__init__.py | 56 +- uproot4/interpretation/grouped.py | 16 +- uproot4/interpretation/identify.py | 42 +- uproot4/interpretation/jagged.py | 32 +- uproot4/interpretation/library.py | 50 +- uproot4/interpretation/numerical.py | 46 +- uproot4/interpretation/objects.py | 102 +-- uproot4/interpretation/strings.py | 44 +- uproot4/language/__init__.py | 10 +- uproot4/language/python.py | 10 +- uproot4/model.py | 358 +++++----- uproot4/models/RNTuple.py | 2 +- uproot4/models/TArray.py | 16 +- uproot4/models/TAtt.py | 16 +- uproot4/models/TBasket.py | 25 +- uproot4/models/TBranch.py | 24 +- uproot4/models/THashList.py | 2 +- uproot4/models/TLeaf.py | 48 +- uproot4/models/TList.py | 2 +- uproot4/models/TNamed.py | 2 +- uproot4/models/TObjArray.py | 4 +- uproot4/models/TObjString.py | 2 +- uproot4/models/TObject.py | 2 +- uproot4/models/TRef.py | 6 +- uproot4/models/TString.py | 2 +- uproot4/models/TTree.py | 16 +- uproot4/models/__init__.py | 22 +- uproot4/reading.py | 364 +++++----- uproot4/source/__init__.py | 6 +- uproot4/source/chunk.py | 84 +-- uproot4/source/cursor.py | 136 ++-- uproot4/source/file.py | 26 +- uproot4/source/futures.py | 92 +-- uproot4/source/http.py | 64 +- uproot4/source/object.py | 16 +- uproot4/source/xrootd.py | 32 +- uproot4/streamers.py | 62 +- 61 files changed, 2954 insertions(+), 1297 deletions(-) create mode 100644 .readthedocs.yml create mode 100644 docs-img/logo/logo-300px-white.png create mode 100644 docs-sphinx/basic.rst create mode 100644 docs-sphinx/conf.py create mode 100644 docs-sphinx/index.rst create mode 100644 docs-sphinx/make_changelog.py create mode 100644 docs-sphinx/prepare_docstrings.py create mode 100644 docs-sphinx/requirements.txt create mode 100644 docs-sphinx/uproot3-to-4.rst diff --git a/.gitignore b/.gitignore index b6e47617d..a5e8c79f0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,9 @@ +# Sphinx documentation +docs-sphinx/_build +docs-sphinx/uproot4.rst +docs-sphinx/uproot4.*.rst +docs-sphinx/*.toctree + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/.readthedocs.yml b/.readthedocs.yml new file mode 100644 index 000000000..6c1fb8326 --- /dev/null +++ b/.readthedocs.yml @@ -0,0 +1,9 @@ +version: 2 + +sphinx: + configuration: docs-sphinx/conf.py + +python: + version: 3.7 + install: + - requirements: docs-sphinx/requirements.txt diff --git a/README.md b/README.md index 1f76de56f..522f57d9d 100644 --- a/README.md +++ b/README.md @@ -33,11 +33,19 @@ Note that Uproot 3 returns old-style [Awkward 0](https://github.com/scikit-hep/a # Installation -Install uproot like any other Python package: +Usually, you'll want to install Uproot with `Awkward Array `__ because this is the default array format. -```bash -pip install uproot # maybe with sudo or --user, -U to update, or in venv -``` +.. code-block:: bash + + pip install uproot4 awkward1 + +But if you are working in a limited environment, Uproot can be installed without Awkward Array. + +.. code-block:: bash + + pip install uproot4 + +Just be sure to pass ``library="np"`` to any function that returns arrays to specify that you want NumPy arrays, rather than Awkward arrays. Other array libraries include `Pandas `__ and `CuPy `__, which, like Awkward, would need to be explicitly installed. # Dependencies diff --git a/docs-img/logo/logo-300px-white.png b/docs-img/logo/logo-300px-white.png new file mode 100644 index 0000000000000000000000000000000000000000..236332639cf6deefb44785c8010919463d244a56 GIT binary patch literal 6794 zcmd@(hd&$6+p#66nnjHws7<3pDXpDYwWEkwLG4krw$|RUSA7vx5*1?AYN(=C+tdhJ zqSN%q64#Lz6epw?kN{_V4#tG$OU2je-aHVqf*rcl0Q@*5o#5H4h?q+ z_5g&3hbwsd`-Hf;1bQe01bde4XbJ!T0!%QyyVeoq+ZExhPBv}Hu@K&yb7B<-)@^N^)a)`2Fzeu)3HEIVS$P+c><%L zN}TI$c@rd9Cr`Rh67hbYPMVG9IBTB{DtBQes4L-~AZ`X@(hFCi(KLMQnw3`gq~pi0 zx5ETI`Dn{|q-`%F+3mh}Y-g>qipPD6dj(8j2-JJM9WGe+%(@NTnuz_F`cV7+bJ46- zIW21m1div$sW8gXyAYa1q$o8Qd7!Wf&eIFvUNNdPB+`UD#!xCG?ahYj!U}=?z}`TZ z71+re9nRf6cfk%LL38glX`k2Uo>ly7@JnYlW&ViTi6sRl+wG&9fr6eF`@`@|`nr*R z39tvZG&>MfzUZo)7;g$bvnLnB@u{m8u+5S=mNV7Ci#=K^`5Y1!P&jM*DhNgM@PA~`K`-WsmOy4zX60M(t zls7RUOg)R(N%NMEQybirhOSyz-SPJ`^ zbh$Db{Z(P{uKEI!15r$zu#5A<2{)}mn`krvJ*?$)TeNZ?1IoH+@id>gMG+mj;E=+7)ougDRA^l>TrA$%|ms8 zuh2JXycfi7q>rSevv#65iC0~JQwPP#MwHj7P77GSEE`vO5K^86`Aii)j>fZaCbaEz4TxGQzQAFtG3)41urF;#5r?EX(GazqZ3bXNQ zH#Xm2C;_oMc(eurog~zzpc*Ypd4jm# zjjTc^0akhhr2Ir0bnT$tc{u3AgrmQ!Nkx{i=D(E|RLNW(W=HO0p{AxJwNUto3N{mW{DqpA3ouGH~TbHuuhVj2hRmQ>t)pq4ooVkn5yX$9Ih8lq?aw*jxt%XX@pPa zw+6h8hGtoXq)igs(N+?ERfp0fUbJ>ar#X4o;m^4`j0tvmgW*owyMXdY-ApFAnqrZ>q~fswsn?`7RR`wT^UelBRJXulcPqQ#4QYb5SFvCHUj zSLic4H#^T9a?UOJ=Z8Kk`68l>91i03jI$tBk@AEtshcrfsy4l&xZJOh40aguV6tUW z*t9$Xp`JWwN?3(XE$@Y>(GAng8t@&5qqcds^;mdCt5<%hpH`%=ONExhs~8ie{n$2r zVY}&G0bH;Sz-gTTJ>Q-X>wEE;gcCfO`ydlAX54k3EX;5ss7MuO*wDzba=Qhbi8S_# z)qttJIK_Q|gSulpo@UKeKUMvYa4S9w6w20TKMcvYCt~}sKexgJ>(HU4E)PQv@v_8I zzqnQC^amK>d1M`7Z;^&gikuO6Pm7xn1PQ z$@c!^F8sjCX7Yt?NDj_gg?_2(7MW>0YyTKjJ~`FTE_<}%In19BIC2(^QMG|iX(2@e zzJ91WlH$J9YhD=o@K?s?dJ)nBIJ(WanId$o8&^^0m?#(|lv0=`H=#w+;9skHs?zs3h ziIaY!Rcnk(EHIY}LpulN-Q{Y)ekEsu^-(d8vOZz-=~<5PSY5FVMJ1x?*iGsIU|m*0 zWaSn5aLMmHtfY(OKpvwy>N4Af>B9#KUcY57zL$d?lc*4-GD5`LGZRd#DNcT{cE+HV zV8`@wu;FtC1Nh@?Y@V;KJpTjpYHV8wge zhy&THRuPRo%$*#Ro&>G?w0Ks>7X)CluKpL3{CyUfRa~#kMooYU%hdNigoU{lbe|o? zo+y7(2*IRLkYv+4{2X%g%FP#Z*63`s%LqHF70>mA#nKl7V(^#0h@-ExFqgqfS^qrc zM84I?O&$J%3B$EiGTIh|%IqyJdZZkb0ywG=vHo%s``r9D!ti$aoR#)OnvC|Vv8UwUWR6|V1fH!oi8@NL>ja5=UTXL$a=FX9Q7C4RQCzJTNf!_kO?D{56b5_?*?PYy+1 z5Oy_vuTdYP8e0U$XL4hjt__}jmB%PBh3yc961^7}n;s+=TPrWgSCF!>$1G z#<%(~3rGi-Csm`QgRDHazeKY_m&jM9nN3*kmXAEGj_zv3$< zw$gZGE31<{a#YLZsS_O0!VNk9HmQ^{`1qD&vb&%c0K56Eb=Y3+u)%WZ5d0PsWompa zpR&V?=_@8~=_KBK?!(O%NT9{jKGF0^Dn`{7+DFVy$lLlnl*Ih(mz_~VX4%~# z8H@srDuh_X(i)P0?UK;vm#6k@^>-L)nM2CtsiS5E@vkb*7Zb`Re$QX~Ae--_qglOF?|y zviy0Y4zJ><3+SD;v3s0elRsRT4Uu+?x@M#^)4N*rNV)gERcxP)Hr;kT~a$-~Os@y0H@20}bPwg$k6~ z&EDlZnry8soKx?Lmdh^I>UQw6uoUXRXhXw~Aa&7%) z%TY7;aEmpj8wMkvFvWd-sr6Kj+9A0gBERBgwnZ_ZW#SrCD14>ouXInh|FJarpA|6T z7tnl*9L5^|7uM=QBlK*L`wBie4(O3deAmvxHB?$&+)=gkp5vU|?e~2>5odF+zY#5e zDj0^^rIp01c3H$u>$6cbHC&9Ej`Tjld(EIB57Hd)5b)=@Znr+YkEH0L4fV1=9sx?X z(fxZWv9Dbqm_VB$fmAW8!ZKYWi2m@@zQXw<)|8DN7i7`W!f-_6S%oz(vmc%%aJPJC zWx6hBJ=`MoEz(omyJ<}b%lRAW{(E%-->5X~ik5;sI92j_v%swr6~21y?eFF<3e>n3 zvC!fg6K1bR&UPyP{)3AAt$Y(p_a6BUa zg?w}(>)l3*Z4h$3mv4bB&B2w=oFP}H;U5cvW~+(FJ0#0r%)Ofj5ys+0`5z3Vx`Z11 z+#5>1IFv~6&&f%JS98E{bd6cLZ!=6W=iK&MrM`@hEZo~*HWW)$1;l}v1gGw7ji7pG z^HbIPI)S|@se+HAZQ5Ixe~$dT+J5Y0l8`k#v6VZbWtGY^)WVr*oyKC@8=+KX#{UtF z8#nCe>k@hCkKNi+ujqud{MpD9VP^X5hI|*P-cBJXa5X4Z`$nNf8#3y$v~ z!6g*_<$O5a%M_0?^*ZV4`d94ZVX*IC>ygBgqUr7{RBf#{4OgW55X$G;XV=1%JBri} zdO`k-k4ir5tB3j8>|Q!g_Z5;wXZq{tKhOUUH%4<3c$G&wz`@0-M6u|h9ER_aTGeo( zkHHq@xj~^Kd_1?wEUUS#p8hO-UL`0E8F#ay_4EDu3|)t3Hsc;CyIq|C ze7)iOr#g~z`aDkzVQKUUY3J&j`(csO8@Zgr*%pP z2FYTJ|L5>z-f%U+M$wX9_TXlV-Jtt3{t~q*Sn8nTFS}B$Ve~ZhfK~GF)Ece&9PY)9 zU#m<06gea@RSzD}NgV_|Fj?%rkz(KB-B-1#)sBew<^4MU@jBvRtR*{>C1={6{^;YOB6?^UD`3sv5oETAldJ?ph%+1|6>`N=oB{Pa(y53?7Xd<5BXQ$+tD;e;MhWbX``bgO3 zXRz3^T?2p0fRUB-d;wiC93fWOmh7$>bYt)|nC|q>{ozTIuq?UCQGX7Px_u=AN>qSh z)8cJ!wsHSQ#kb)j_WA5G6SbleLHgRAk}Xk+{u>qC>%c`bg6nWQmxM>8KNF$!U)4ay zZ~aH5D39Os!fE&bjMlvd{Wp055>t=vk(WkQv0@78a({Du8LcHEFP`5P+ai}@tsGNI zZLIwtx7%)21qQ5rD{o+xE?cWnmu~LWzMmwzJ;GaK*VvLBL%XFwjRxA7OUq6?V()aa z#2r+IW#sPHrulO0g*}{vP{vq_3a zzsYe8yh}$mj-9JqvQc|B-Mqk_G8I>=*!5-)`{mu#!#^#$-AxAVHZXi7ias#t-{UMQ z`H+~q{r1_0Isfi0;Hup1WD$Y{L1`dqGq_b96mcWi*XsJ*Tbc+KrP~8Z>+zra?gQP* z%{HgJYS|*__l&R>m;H0d$c4DJI1SD%zUr9-{m#i@$t*vGm4fG1r)^yL@t0#V!GA>a7cA7}CivduM2G6v`R&G=boxqm;L+2wUzz}%# za_?>Ph+A8FC$cDr2Z)!HPCB~&{R6Wv<7X$7V|MPUx4tQZEK&a3%?Qyww`(wlMgl%w70UPDg%QgL}? zS{F`C0e<4vSysqtO~6ir{qV~zm&-0S@GL14ch{wvHD#rTvb|eN4& z!_#NyBP+N&XG%VPdRPa$zcl{LO!*S@E_vN@Lo&FvMCitTRpThFT|LsQs!8UxXRsnY zuBcp`YV|1KpDva{Fijoo#8>fj{GB*PRgL%+1t8I2ZtZ+MOtk}VqtH&_S_?Gzy1?Z= zyOrqx6=H0~@2x576`M-F_pdSgzhbU_lzN%d8ZLr?SWle8f1Tnm{2;Z^su2lv7=Gg@ z+UXkgll~waGrna8do4eVb?iw_Y8z`$@IbR)PqBUdyA4an6Wik!v@8hgF12q8Ij}Jc z7(Y(c(_E=cufDbApuFrj(6{3My zDfiOm>KQL=%_}Kbd+LKWml5YaG+IA-4EPPQ>QJh=c4M&lrA!ts*O?rZQpzw6m`{#6qA5Nb(>bf~RSsp9e zNS{e90;)wc5q~jLlJ;T`;r+^*H06w2x-6Bg*boy^7v>VCwJzYsz&L|CyuK|o@GLG)lnpj-%h}SWix00yvLlZ&m9n2*8G~+u;%~{kP z;JVe(NQ|mg)PrNuHR`*`TfVNB#U5_Sc!wtfvg(S^?|N#njbJ}9Z~4Rz zyp82+YcgN8x@|&)8l57Jfa$FJXXE znBSU_AoA}Aim>gm!WU8M#cdRYxCeVNW8z^b3ssyf*mo>+!S3dZB22e4t@j>?GzEUj z_~_$|x5qqx1ywgww-#{d%F35VWUcOJAz#gEWUX=!F^mP3$M^p~fG$wbj0kvQvxDQp z2lxt5NOQ=jz=*7c7#}QL_+JHKoJzt_zRtz}N`j^s5JlIy^uJ~LKdgwBrFQ5=zyC(- cH-G6Y&dd|-rX)Qs{*3@IeKWn6I;e#I0f2zn^8f$< literal 0 HcmV?d00001 diff --git a/docs-sphinx/basic.rst b/docs-sphinx/basic.rst new file mode 100644 index 000000000..d0b9c1c9e --- /dev/null +++ b/docs-sphinx/basic.rst @@ -0,0 +1,994 @@ +Getting started guide +===================== + +Opening a file +-------------- + +Open a ROOT file for reading with the `uproot4.open `__ function. + +.. code-block:: python + + >>> import uproot4 + >>> file = uproot4.open("path/to/dataset.root") + +The `uproot4.open `__ function can also be used like this: + +.. code-block:: python + + >>> with uproot4.open("path/to/dataset.root") as file: + ... do_something... + +to automatically close the file after leaving the ``with`` block. The path-name argument can be a local file (as above), a URL ("``http://``" or "``https://``"), or XRootD ("``root://``") if you have the `Python interface to XRootD `__ installed. It can also be a Python file-like object with ``read`` and ``seek`` methods, but such objects can't be read in parallel. + +The `uproot4.open `__ function has many options, including alternate handlers for each input type, ``num_workers`` to control parallel reading, and caches (``object_cache`` and ``array_cache``). The defaults attempt to optimize parallel processing, caching, and batching of remote requests, but better performance can often be obtained by tuning these parameters. + +Finding objects in a file +------------------------- + +The object returned by `uproot4.open `__ represents a TDirectory inside the file (``/``). + +.. code-block:: python + + >>> file = uproot4.open("https://scikit-hep.org/uproot/examples/nesteddirs.root") + >>> file + + +This object is a Python `Mapping `__, which means that you can get a list of contents with :py:meth:`~uproot4.reading.ReadOnlyDirectory.keys`. + +.. code-block:: python + + >>> file.keys() + ['one;1', 'one/two;1', 'one/two/tree;1', 'one/tree;1', 'three;1', 'three/tree;1'] + +and extract an item (read it from the file) with square brackets. The cycle number (after ``;``) doesn't have to be included and you can extract from TDirectories in TDirectories with slashes (``/``). + +.. code-block:: python + + >>> file["one"] + + >>> file["one"]["two"] + + >>> file["one"]["two"]["tree"] + + >>> file["one/two/tree"] + + +Data, including nested TDirectories, are not read from disk until they are explicitly requested with square brackets (or another `Mapping `__ function, like :py:meth:`~uproot4.reading.ReadOnlyDirectory.values` or :py:meth:`~uproot4.reading.ReadOnlyDirectory.items`). + +You can get the names of classes without reading the objects by using :py:meth:`~uproot4.reading.ReadOnlyDirectory.classnames`. + +.. code-block:: python + + >>> file.classnames() + {'one': 'TDirectory', 'one/two': 'TDirectory', 'one/two/tree': 'TTree', 'one/tree': 'TTree', + 'three': 'TDirectory', 'three/tree': 'TTree'} + +As a shortcut, you can open a file and jump straight to the object by separating the file path and object path with a colon (``:``). + +.. code-block:: python + + >>> events = uproot4.open("https://scikit-hep.org/uproot/examples/Zmumu.root:events") + >>> events + + +Colon separators are only allowed in strings, so you can open files that have colons in their names by wrapping them in a `pathlib.Path `__. + +Extracting histograms from a file +--------------------------------- + +Uproot can read most types of objects, but only a few of them have been overloaded with specialized behaviors. + +.. code-block:: python + + >>> file = uproot4.open("https://scikit-hep.org/uproot/examples/hepdata-example.root") + >>> file.classnames() + {'hpx': 'TH1F', 'hpxpy': 'TH2F', 'hprof': 'TProfile', 'ntuple': 'TNtuple'} + +Classes unknown to Uproot can be accessed through their members (raw C++ members that have been serialized into the file): + +.. code-block:: python + + >>> file["hpx"].all_members + {'@fUniqueID': 0, '@fBits': 50331656, 'fName': 'hpx', 'fTitle': 'This is the px distribution', + 'fLineColor': 602, 'fLineStyle': 1, 'fLineWidth': 1, 'fFillColor': 0, 'fFillStyle': 1001, + 'fMarkerColor': 1, 'fMarkerStyle': 1, 'fMarkerSize': 1.0, 'fNcells': 102, + 'fXaxis': , + 'fYaxis': , + 'fZaxis': , 'fBarOffset': 0, 'fBarWidth': 1000, + 'fEntries': 75000.0, 'fTsumw': 74994.0, 'fTsumw2': 74994.0, 'fTsumwx': -97.16475860591163, + 'fTsumwx2': 75251.86518025988, 'fMaximum': -1111.0, 'fMinimum': -1111.0, 'fNormFactor': 0.0, + 'fContour': , 'fSumw2': , + 'fOption': , 'fFunctions': , + 'fBufferSize': 0, 'fBuffer': array([], dtype=float64), 'fBinStatErrOpt': 0, 'fN': 102} + + >>> file["hpx"].member("fName") + 'hpx' + +But some classes, like :py:class:`~uproot4.behaviors.TH1.TH1`, :py:class:`~uproot4.behaviors.TProfile.TProfile`, and :py:class:`~uproot4.behaviors.TH2.TH2`, have high-level "behaviors" defined in :py:mod:`uproot4.behaviors` to make them easier to use. + +Histograms have :py:meth:`~uproot4.behaviors.TH1.TH1.edges`, :py:meth:`~uproot4.behaviors.TH1.TH1.values`, and :py:meth:`~uproot4.behaviors.TH1.TH1.values_errors` methods to extract histogram axes and bin contents directly into NumPy arrays. (Keep in mind that a histogram axis with *N* bins has *N + 1* edges, and that the edges include underflow and overflow as ``-np.inf`` and ``np.inf`` endpoints.) + +.. code-block:: python + + >>> file["hpx"].edges() + array([ -inf, -4. , -3.92, -3.84, -3.76, -3.68, -3.6 , -3.52, -3.44, + -3.36, -3.28, -3.2 , -3.12, -3.04, -2.96, -2.88, -2.8 , -2.72, + -2.64, -2.56, -2.48, -2.4 , -2.32, -2.24, -2.16, -2.08, -2. , + -1.92, -1.84, -1.76, -1.68, -1.6 , -1.52, -1.44, -1.36, -1.28, + -1.2 , -1.12, -1.04, -0.96, -0.88, -0.8 , -0.72, -0.64, -0.56, + -0.48, -0.4 , -0.32, -0.24, -0.16, -0.08, 0. , 0.08, 0.16, + 0.24, 0.32, 0.4 , 0.48, 0.56, 0.64, 0.72, 0.8 , 0.88, + 0.96, 1.04, 1.12, 1.2 , 1.28, 1.36, 1.44, 1.52, 1.6 , + 1.68, 1.76, 1.84, 1.92, 2. , 2.08, 2.16, 2.24, 2.32, + 2.4 , 2.48, 2.56, 2.64, 2.72, 2.8 , 2.88, 2.96, 3.04, + 3.12, 3.2 , 3.28, 3.36, 3.44, 3.52, 3.6 , 3.68, 3.76, + 3.84, 3.92, 4. , inf]) + >>> file["hpx"].values() + array([2.000e+00, 2.000e+00, 3.000e+00, 1.000e+00, 1.000e+00, 2.000e+00, + 4.000e+00, 6.000e+00, 1.200e+01, 8.000e+00, 9.000e+00, 1.500e+01, + 1.500e+01, 3.100e+01, 3.500e+01, 4.000e+01, 6.400e+01, 6.400e+01, + 8.100e+01, 1.080e+02, 1.240e+02, 1.560e+02, 1.650e+02, 2.090e+02, + 2.620e+02, 2.970e+02, 3.920e+02, 4.320e+02, 4.660e+02, 5.210e+02, + 6.040e+02, 6.570e+02, 7.880e+02, 9.030e+02, 1.079e+03, 1.135e+03, + 1.160e+03, 1.383e+03, 1.458e+03, 1.612e+03, 1.770e+03, 1.868e+03, + 1.861e+03, 1.946e+03, 2.114e+03, 2.175e+03, 2.207e+03, 2.273e+03, + 2.276e+03, 2.329e+03, 2.325e+03, 2.381e+03, 2.417e+03, 2.364e+03, + 2.284e+03, 2.188e+03, 2.164e+03, 2.130e+03, 1.940e+03, 1.859e+03, + 1.763e+03, 1.700e+03, 1.611e+03, 1.459e+03, 1.390e+03, 1.237e+03, + 1.083e+03, 1.046e+03, 8.880e+02, 7.520e+02, 7.420e+02, 6.730e+02, + 5.550e+02, 5.330e+02, 3.660e+02, 3.780e+02, 2.720e+02, 2.560e+02, + 2.000e+02, 1.740e+02, 1.320e+02, 1.180e+02, 1.000e+02, 8.900e+01, + 8.600e+01, 3.900e+01, 3.700e+01, 2.500e+01, 2.300e+01, 2.000e+01, + 1.600e+01, 1.400e+01, 9.000e+00, 1.300e+01, 8.000e+00, 2.000e+00, + 2.000e+00, 6.000e+00, 1.000e+00, 0.000e+00, 1.000e+00, 4.000e+00], + dtype=float32) + >>> file["hprof"].values_errors() + (array([17.99833584, 17.05295467, 16.96826426, 15.18948269, 13.73788834, + 13.37521982, 13.5103693 , 12.64630063, 12.6601193 , 11.82483637, + 11.62344678, 11.47207673, 10.05298678, 10.03059732, 9.61441732, + 8.77662256, 8.6208066 , 8.17996864, 7.41270794, 7.49722647, + 6.98081953, 6.505285 , 6.25185173, 5.81357581, 5.58440386, + 5.01104751, 4.91228925, 4.52465974, 4.24002511, 4.07746299, + 3.63879339, 3.52214183, 3.25587136, 2.96102029, 2.70619968, + 2.58419117, 2.36279976, 2.14934465, 2.00779036, 1.83823925, + 1.71255197, 1.61313089, 1.44907926, 1.34713526, 1.24584489, + 1.17076595, 1.12473963, 1.11984797, 1.02812853, 1.04176022, + 1.01975455, 1.00031317, 1.07947053, 1.02964734, 1.06030445, + 1.15428476, 1.17458553, 1.31746264, 1.29098442, 1.45532587, + 1.58397301, 1.72741128, 1.8171251 , 1.99961636, 2.19764745, + 2.33289525, 2.57368246, 2.74573281, 2.91219718, 3.15770185, + 3.33105952, 3.6855651 , 4.01111874, 4.31449181, 4.54825707, + 4.93563452, 5.19188255, 5.47676609, 5.73479857, 6.18110869, + 6.40689125, 7.04866284, 7.23857685, 7.55534168, 8.16915879, + 9.01906589, 8.7895729 , 9.3652438 , 9.57024695, 10.27966509, + 11.08611178, 11.11813177, 12.65668541, 12.17647505, 12.39317608, + 16.51897812, 13.30313969, 14.63502661, 14.96741772, 0. , + 18.32199478, 17.84037463]), + array([0.24254264, 0.74212103, 0.49400663, 0. , 0. , + 0.24649804, 0.55553737, 0.24357922, 0.22461613, 0.34906168, + 0.43563347, 0.51286511, 0.20863074, 0.28308077, 0.28915414, + 0.16769727, 0.17257732, 0.12765099, 0.10176558, 0.15209837, + 0.11509671, 0.1014912 , 0.1143207 , 0.09759737, 0.09257268, + 0.06761853, 0.07883833, 0.06391972, 0.07016808, 0.06790635, + 0.05330255, 0.05630489, 0.05523831, 0.04797496, 0.04255815, + 0.04422412, 0.04089869, 0.03453675, 0.03943858, 0.03461427, + 0.03618794, 0.03408547, 0.03170797, 0.03121938, 0.03011256, + 0.02926609, 0.03012814, 0.02977365, 0.02974839, 0.03081958, + 0.0313295 , 0.0293942 , 0.02925847, 0.0293043 , 0.02804402, + 0.03117598, 0.03010833, 0.03149117, 0.02909491, 0.0325676 , + 0.03445547, 0.03480207, 0.0327122 , 0.03860859, 0.03885261, + 0.03856341, 0.04624045, 0.04543318, 0.04864621, 0.05203739, + 0.04324402, 0.05850656, 0.05970975, 0.0659423 , 0.07220151, + 0.08170132, 0.08712811, 0.08092333, 0.09191357, 0.10837656, + 0.10509033, 0.15493381, 0.12013956, 0.11435862, 0.183943 , + 0.36368702, 0.13346263, 0.18325723, 0.17988976, 0.19265302, + 0.35247309, 0.18420323, 0.59593532, 0.21540243, 0.11755951, + 1.66198443, 0.13528127, 0.45343914, 0. , 0. , + 0. , 0.1681792 ])) + +Since Uproot is an I/O library, it intentionally does not have methods for plotting or manipulating histograms. Instead, it has methods for exporting them to other libraries. + +.. code-block:: python + + >>> file["hpxpy"].to_numpy() + (array([[0., 0., 0., ..., 0., 0., 0.], + [0., 0., 0., ..., 0., 0., 0.], + [0., 0., 0., ..., 0., 0., 0.], + ..., + [0., 0., 0., ..., 0., 0., 0.], + [0., 0., 0., ..., 0., 0., 0.], + [0., 0., 0., ..., 0., 0., 0.]], dtype=float32), + array([-4. , -3.8, -3.6, -3.4, -3.2, -3. , -2.8, -2.6, -2.4, -2.2, -2. , + -1.8, -1.6, -1.4, -1.2, -1. , -0.8, -0.6, -0.4, -0.2, 0. , 0.2, + 0.4, 0.6, 0.8, 1. , 1.2, 1.4, 1.6, 1.8, 2. , 2.2, 2.4, + 2.6, 2.8, 3. , 3.2, 3.4, 3.6, 3.8, 4. ]), + array([-4. , -3.8, -3.6, -3.4, -3.2, -3. , -2.8, -2.6, -2.4, -2.2, -2. , + -1.8, -1.6, -1.4, -1.2, -1. , -0.8, -0.6, -0.4, -0.2, 0. , 0.2, + 0.4, 0.6, 0.8, 1. , 1.2, 1.4, 1.6, 1.8, 2. , 2.2, 2.4, + 2.6, 2.8, 3. , 3.2, 3.4, 3.6, 3.8, 4. ])) + + >>> file["hpxpy"].to_boost() + Histogram( + Regular(40, -4, 4, metadata={ + '@fUniqueID': 0, '@fBits': 50331648, 'fNdivisions': 510, 'fAxisColor': 1, + 'fLabelColor': 1, 'fLabelFont': 42, 'fLabelOffset': 0.004999999888241291, + 'fLabelSize': 0.03500000014901161, 'fTickLength': 0.029999999329447746, + 'fTitleOffset': 1.0, 'fTitleSize': 0.03500000014901161, 'fTitleColor': 1, + 'fTitleFont': 42, 'fNbins': 40, 'fXmin': -4.0, 'fXmax': 4.0, 'fFirst': 0, + 'fLast': 0, 'fBits2': 0, 'fTimeDisplay': False, + 'fTimeFormat': , 'name': 'xaxis', 'title': ''}), + Regular(40, -4, 4, metadata={ + '@fUniqueID': 0, '@fBits': 50331648, 'fNdivisions': 510, 'fAxisColor': 1, + 'fLabelColor': 1, 'fLabelFont': 42, 'fLabelOffset': 0.004999999888241291, + 'fLabelSize': 0.03500000014901161, 'fTickLength': 0.029999999329447746, + 'fTitleOffset': 1.0, 'fTitleSize': 0.03500000014901161, 'fTitleColor': 1, + 'fTitleFont': 42, 'fNbins': 40, 'fXmin': -4.0, 'fXmax': 4.0, 'fFirst': 0, + 'fLast': 0, 'fBits2': 0, 'fTimeDisplay': False, + 'fTimeFormat': , 'name': 'yaxis', 'title': ''}), + storage=Double()) # Sum: 74985.0 (75000.0 with flow) + + >>> file["hpxpy"].to_hist() + # Traceback (most recent call last): + # File "/home/jpivarski/irishep/uproot4/uproot4/extras.py", line 237, in hist + # import hist + # ModuleNotFoundError: No module named 'hist' + # + # During handling of the above exception, another exception occurred: + # + # Traceback (most recent call last): + # File "", line 1, in + # File "/home/jpivarski/irishep/uproot4/uproot4/behaviors/TH2.py", line 127, in to_hist + # return uproot4.extras.hist().Hist(self.to_boost()) + # File "/home/jpivarski/irishep/uproot4/uproot4/extras.py", line 239, in hist + # raise ImportError( + # ImportError: install the 'hist' package with: + # + # pip install hist + +If one of those libraries is not currently installed, a hint is provided for how to get it. + +For histogramming, I recommend + +- `mplhep `__ for plotting NumPy-like histograms in Matplotlib. +- `boost-histogram `__ for fast filling and manipulation. +- `hist `__ for plotting, filling, manipulation, and fitting all in one package. + +Inspecting a TBranches of a TTree +--------------------------------- + +:py:class:`~uproot4.behaviors.TTree.TTree`, with the lists of :py:class:`~uproot4.behaviors.TBranch.TBranch` it contains, are Uproot's most important "overloaded behaviors." Like :py:class:`~uproot4.reading.ReadOnlyDirectory`, a TTree is a `Mapping `__, though it maps TBranch names to the (already read) :py:class:`~uproot4.behaviors.TBranch.TBranch` objects it contains. Since TBranches can contain more TBranches, both of these are subclasses of a general :py:class:`~uproot4.behaviors.TBranch.HasBranches`. + +.. code-block:: python + + >>> events = uproot4.open("https://scikit-hep.org/uproot/examples/Zmumu.root:events") + + >>> events.keys() + ['Type', 'Run', 'Event', 'E1', 'px1', 'py1', 'pz1', 'pt1', 'eta1', 'phi1', 'Q1', 'E2', 'px2', + 'py2', 'pz2', 'pt2', 'eta2', 'phi2', 'Q2', 'M'] + + >>> events.values() + [, , + , , + , , + , , + , , + , , + , , + , , + , , + , ] + + >>> events["M"] + + +Like a TDirectory's :py:meth:`~uproot4.reading.ReadOnlyDirectory.classnames`, you can access the TBranch data types without reading data by calling :py:meth:`~uproot4.behaviors.TBranch.HasBranches.typenames`. + +.. code-block:: python + + >>> events.typenames() + {'Type': 'char*', 'Run': 'int32_t', 'Event': 'int32_t', 'E1': 'double', 'px1': 'double', + 'py1': 'double', 'pz1': 'double', 'pt1': 'double', 'eta1': 'double', 'phi1': 'double', + 'Q1': 'int32_t', 'E2': 'double', 'px2': 'double', 'py2': 'double', 'pz2': 'double', + 'pt2': 'double', 'eta2': 'double', 'phi2': 'double', 'Q2': 'int32_t', 'M': 'double'} + +In an interactive session, it's often more convenient to call :py:meth:`~uproot4.behaviors.TBranch.HasBranches.show`. + +.. code-block:: python + + >>> events.show() + name | typename | interpretation + ---------------------+--------------------------+------------------------------- + Type | char* | AsStrings() + Run | int32_t | AsDtype('>i4') + Event | int32_t | AsDtype('>i4') + E1 | double | AsDtype('>f8') + px1 | double | AsDtype('>f8') + py1 | double | AsDtype('>f8') + pz1 | double | AsDtype('>f8') + pt1 | double | AsDtype('>f8') + eta1 | double | AsDtype('>f8') + phi1 | double | AsDtype('>f8') + Q1 | int32_t | AsDtype('>i4') + E2 | double | AsDtype('>f8') + px2 | double | AsDtype('>f8') + py2 | double | AsDtype('>f8') + pz2 | double | AsDtype('>f8') + pt2 | double | AsDtype('>f8') + eta2 | double | AsDtype('>f8') + phi2 | double | AsDtype('>f8') + Q2 | int32_t | AsDtype('>i4') + M | double | AsDtype('>f8') + +The third column, ``interpretation``, indicates how data in the TBranch will be interpreted as an array. + +Reading a TBranch as an array +----------------------------- + +A TBranch may be turned into an array with the :py:meth:`~uproot4.behaviors.TBranch.TBranch.array` method. The array is not read from disk until this method is called (or other array-fetching methods described below). + +.. code-block:: python + + >>> events = uproot4.open("https://scikit-hep.org/uproot/examples/Zmumu.root:events") + >>> events["M"].array() + + +By default, the array is an Awkward array, as shown above. This assumes that Awkward Array is installed (see `How to install `__). If you can't install it or want to use NumPy for other reasons, pass ``library="np"`` instead of the default ``library="ak"``. + +.. code-block:: python + + >>> events["M"].array(library="np") + array([82.46269156, 83.62620401, 83.30846467, ..., 95.96547966, + 96.49594381, 96.65672765]) + +Another library option is ``library="pd"`` for Pandas, and a single TBranch is (usually) presented as a `pandas.Series `__. + +.. code-block:: python + + >>> events["M"].array(library="pd") + 0 82.462692 + 1 83.626204 + 2 83.308465 + 3 82.149373 + 4 90.469123 + ... + 2299 60.047138 + 2300 96.125376 + 2301 95.965480 + 2302 96.495944 + 2303 96.656728 + Length: 2304, dtype: float64 + +If you don't have the specified library (including the default, Awkward), you'll be prompted with instructions to install it. + +.. code-block:: python + + >>> events["M"].array(library="cp") + Traceback (most recent call last): + File "/home/jpivarski/irishep/uproot4/uproot4/extras.py", line 60, in cupy + import cupy + ModuleNotFoundError: No module named 'cupy' + + ... + + ImportError: install the 'cupy' package with: + + pip install cupy + + or + + conda install cupy + +(CuPy can only be used on computers with GPUs.) + +The :py:meth:`~uproot4.behaviors.TBranch.TBranch.array` method has many options, including limitations on reading (``entry_start`` and ``entry_stop``), parallelization (``decompression_executor`` and ``interpretation_executor``), and caching (``array_cache``). For details, see the reference documentation for :py:meth:`~uproot4.behaviors.TBranch.TBranch.array`. + +Reading multiple TBranches as a group of arrays +----------------------------------------------- + +To read more than one TBranch, you could use the :py:meth:`~uproot4.behaviors.TBranch.TBranch.array` method from the previous section multiple times, but you could also use :py:meth:`~uproot4.behaviors.TBranch.HasBranches.arrays` (plural) on the TTree itself. + +.. code-block:: python + + >>> events = uproot4.open("https://scikit-hep.org/uproot/examples/Zmumu.root:events") + + >>> momentum = events.arrays(["px1", "py1", "pz1"]) + >>> momentum + + +The return value is a group of arrays, where a "group" has different meanings in different libraries. For Awkward Array (above), a group is an array of records, which can be projected like this: + +.. code-block:: python + + >>> momentum["px1"] + + +For NumPy, a group is a dict of arrays. + +.. code-block:: python + + >>> momentum = events.arrays(["px1", "py1", "pz1"], library="np") + >>> momentum + {'px1': array([-41.19528764, 35.11804977, 35.11804977, ..., 32.37749196, + 32.37749196, 32.48539387]), + 'py1': array([ 17.4332439 , -16.57036233, -16.57036233, ..., 1.19940578, + 1.19940578, 1.2013503 ]), + 'pz1': array([-68.96496181, -48.77524654, -48.77524654, ..., -74.53243061, + -74.53243061, -74.80837247])} + + >>> momentum["px1"] + array([-41.19528764, 35.11804977, 35.11804977, ..., 32.37749196, + 32.37749196, 32.48539387]) + +For Pandas, a group is a `pandas.DataFrame `__. + +.. code-block:: python + + >>> momentum = events.arrays(["px1", "py1", "pz1"], library="pd") + >>> momentum + px1 py1 pz1 + 0 -41.195288 17.433244 -68.964962 + 1 35.118050 -16.570362 -48.775247 + 2 35.118050 -16.570362 -48.775247 + 3 34.144437 -16.119525 -47.426984 + 4 22.783582 15.036444 -31.689894 + ... ... ... ... + 2299 19.054651 14.833954 22.051323 + 2300 -68.041915 -26.105847 -152.235018 + 2301 32.377492 1.199406 -74.532431 + 2302 32.377492 1.199406 -74.532431 + 2303 32.485394 1.201350 -74.808372 + + [2304 rows x 3 columns] + + >>> momentum["px1"] + 0 -41.195288 + 1 35.118050 + 2 35.118050 + 3 34.144437 + 4 22.783582 + ... + 2299 19.054651 + 2300 -68.041915 + 2301 32.377492 + 2302 32.377492 + 2303 32.485394 + Name: px1, Length: 2304, dtype: float64 + +Even though you can extract individual arrays from these objects, they're read, decompressed, and interpreted as soon as you ask for them. Unless you're working with small files, be sure not to read everything when you only want a few of the arrays! + +Filtering TBranches +------------------- + +If no arguments are passed to :py:meth:`~uproot4.behaviors.TBranch.HasBranches.arrays`, *all* TBranches will be read. If your file has many TBranches, this might not be desirable or possible. You can select specific TBranches by name, as in the previous section, but you can also use a filter (``filter_name``, ``filter_typename``, or ``filter_branch``) to select TBranches by name, type, or other attributes. + +The :py:meth:`~uproot4.behaviors.TBranch.HasBranches.keys`, :py:meth:`~uproot4.behaviors.TBranch.HasBranches.values`, :py:meth:`~uproot4.behaviors.TBranch.HasBranches.items`, and :py:meth:`~uproot4.behaviors.TBranch.HasBranches.typenames` methods take the same arguments, so you can test your filters before reading any data. + +.. code-block:: python + + >>> events = uproot4.open("https://scikit-hep.org/uproot/examples/Zmumu.root:events") + + >>> events.keys(filter_name="px*") + ['px1', 'px2'] + >>> events.arrays(filter_name="px*") + + + >>> events.keys(filter_name="/p[xyz][0-9]/i") + ['px1', 'py1', 'pz1', 'px2', 'py2', 'pz2'] + >>> events.arrays(filter_name="/p[xyz][0-9]/i") + + + >>> events.keys(filter_branch=lambda b: b.compression_ratio > 10) + ['Run', 'Q1', 'Q2'] + >>> events.arrays(filter_branch=lambda b: b.compression_ratio > 10) + + +Computing expressions and cuts +------------------------------ + +The first argument of :py:meth:`~uproot4.behaviors.TBranch.HasBranches.arrays`, which we used above to pass explicit TBranch names, + +.. code-block:: python + + >>> events = uproot4.open("https://scikit-hep.org/uproot/examples/Zmumu.root:events") + + >>> events.arrays(["px1", "py1", "pz1"]) + + +can also compute expressions: + +.. code-block:: python + + >>> events.arrays("sqrt(px1**2 + py1**2)") + + +If the TTree has any aliases, you can refer to those aliases by name, or you can create new aliases to give better names to the keys of the output dict, Awkward records, or Pandas columns. + +.. code-block:: python + + >>> events.arrays("pt1", aliases={"pt1": "sqrt(px1**2 + py1**2)"}) + + +The second argument is a ``cut``, or filter on entries. Whereas the uncut array (above) has 2304 entries, the cut array (below) has 290 entries. + +.. code-block:: python + + >>> events.arrays(["M"], "pt1 > 50", aliases={"pt1": "sqrt(px1**2 + py1**2)"}) + + +Note that expressions are *not*, in general, computed more quickly if expressed in these strings. The above is equivalent to the following: + +.. code-block:: python + + >>> import numpy as np + >>> arrays = events.arrays(["px1", "py1", "M"]) + >>> pt1 = np.sqrt(arrays.px1**2 + arrays.py1**2) + >>> arrays.M[pt1 > 50] + + +but perhaps more convenient. If what you want to compute requires more than one expression, you'll have to move it out of strings into Python. + +The default ``language`` is :py:class:`~uproot4.language.python.PythonLanguage`, but other languages, like ROOT's `TTree::Draw syntax `_ are foreseen *in the future*. Thus, implicit loops (e.g. ``Sum$(...)``) have to be translated to their Awkward equivalents and ``ROOT::Math`` functions have to be translated to their NumPy equivalents. + +Nested data structures +---------------------- + +Not all datasets have one value per entry. In particle physics, we often have different numbers of particles (and particle attributes) per collision event. + +.. code-block:: python + + >>> events = uproot4.open("https://scikit-hep.org/uproot/examples/HZZ.root:events") + >>> events.show() + name | typename | interpretation + ---------------------+--------------------------+------------------------------- + NJet | int32_t | AsDtype('>i4') + Jet_Px | float[] | AsJagged(AsDtype('>f4')) + Jet_Py | float[] | AsJagged(AsDtype('>f4')) + Jet_Pz | float[] | AsJagged(AsDtype('>f4')) + Jet_E | float[] | AsJagged(AsDtype('>f4')) + Jet_btag | float[] | AsJagged(AsDtype('>f4')) + Jet_ID | bool[] | AsJagged(AsDtype('bool')) + NMuon | int32_t | AsDtype('>i4') + Muon_Px | float[] | AsJagged(AsDtype('>f4')) + Muon_Py | float[] | AsJagged(AsDtype('>f4')) + Muon_Pz | float[] | AsJagged(AsDtype('>f4')) + Muon_E | float[] | AsJagged(AsDtype('>f4')) + Muon_Charge | int32_t[] | AsJagged(AsDtype('>i4')) + Muon_Iso | float[] | AsJagged(AsDtype('>f4')) + +These datasets have a natural expression as Awkward Arrays: + +.. code-block:: python + + >>> events.keys(filter_name="/(Jet|Muon)_P[xyz]/") + ['Jet_Px', 'Jet_Py', 'Jet_Pz', 'Muon_Px', 'Muon_Py', 'Muon_Pz'] + >>> ak_arrays = events.arrays(filter_name="/(Jet|Muon)_P[xyz]/") + >>> ak_arrays[:2].tolist() + [{'Jet_Px': [], + 'Jet_Py': [], + 'Jet_Pz': [], + 'Muon_Px': [-52.89945602416992, 37.7377815246582], + 'Muon_Py': [-11.654671669006348, 0.6934735774993896], + 'Muon_Pz': [-8.16079330444336, -11.307581901550293]}, + {'Jet_Px': [-38.87471389770508], + 'Jet_Py': [19.863452911376953], + 'Jet_Pz': [-0.8949416279792786], + 'Muon_Px': [-0.8164593577384949], + 'Muon_Py': [-24.404258728027344], + 'Muon_Pz': [20.199968338012695]}] + +See the `Awkward Array documentation `__ for data analysis techniques using these types. (Python for loops work, but it's faster and usually more convenient to use Awkward Array's suite of NumPy-like functions.) + +The same dataset *can* be read as a NumPy array with ``dtype="O"`` (Python objects), which puts NumPy arrays inside of NumPy arrays. + +.. code-block:: python + + >>> np_arrays = events.arrays(filter_name="/(Jet|Muon)_P[xyz]/", library="np") + >>> np_arrays + {'Jet_Px': array([array([], dtype=float32), array([-38.874714], dtype=float32), + array([], dtype=float32), ..., array([-3.7148185], dtype=float32), + array([-36.361286, -15.256871], dtype=float32), + array([], dtype=float32)], dtype=object), + 'Jet_Py': array([array([], dtype=float32), array([19.863453], dtype=float32), + array([], dtype=float32), ..., array([-37.202377], dtype=float32), + array([ 10.173571, -27.175364], dtype=float32), + array([], dtype=float32)], dtype=object), + 'Jet_Pz': array([array([], dtype=float32), array([-0.8949416], dtype=float32), + array([], dtype=float32), ..., array([41.012222], dtype=float32), + array([226.42921 , 12.119683], dtype=float32), + array([], dtype=float32)], dtype=object), + 'Muon_Px': array([array([-52.899456, 37.73778 ], dtype=float32), + array([-0.81645936], dtype=float32), + array([48.98783 , 0.8275667], dtype=float32), ..., + array([-29.756786], dtype=float32), + array([1.1418698], dtype=float32), + array([23.913206], dtype=float32)], dtype=object), + 'Muon_Py': array([array([-11.654672 , 0.6934736], dtype=float32), + array([-24.404259], dtype=float32), + array([-21.723139, 29.800508], dtype=float32), ..., + array([-15.303859], dtype=float32), + array([63.60957], dtype=float32), + array([-35.665077], dtype=float32)], dtype=object), + 'Muon_Pz': array([array([ -8.160793, -11.307582], dtype=float32), + array([20.199968], dtype=float32), + array([11.168285, 36.96519 ], dtype=float32), ..., + array([-52.66375], dtype=float32), + array([162.17632], dtype=float32), + array([54.719437], dtype=float32)], dtype=object)} + +These "nested" NumPy arrays are not slicable as multidimensional arrays because NumPy can't assume that all of the Python objects it contains have NumPy type. + +.. code-block:: python + + >>> ak_arrays["Muon_Px"][:10, 0] # first Muon_Px of the first 10 events + + + >>> np_arrays["Muon_Px"][:10, 0] + # Traceback (most recent call last): + # File "", line 1, in + # IndexError: too many indices for array: array is 1-dimensional, but 2 were indexed + +The Pandas form for this type of data is a `DataFrame with MultiIndex rows `__. + +.. code-block:: python + + >>> events.arrays(filter_name="/(Jet|Muon)_P[xyz]/", library="pd") + ( + Jet_Px Jet_Py Jet_Pz + entry subentry + 1 0 -38.874714 19.863453 -0.894942 + 3 0 -71.695213 93.571579 196.296432 + 1 36.606369 21.838793 91.666283 + 2 -28.866419 9.320708 51.243221 + 4 0 3.880162 -75.234055 -359.601624 + ... ... ... ... + 2417 0 -33.196457 -59.664749 -29.040150 + 1 -26.086025 -19.068407 26.774284 + 2418 0 -3.714818 -37.202377 41.012222 + 2419 0 -36.361286 10.173571 226.429214 + 1 -15.256871 -27.175364 12.119683 + + [2773 rows x 3 columns], + + Muon_Px Muon_Py Muon_Pz + entry subentry + 0 0 -52.899456 -11.654672 -8.160793 + 1 37.737782 0.693474 -11.307582 + 1 0 -0.816459 -24.404259 20.199968 + 2 0 48.987831 -21.723139 11.168285 + 1 0.827567 29.800508 36.965191 + ... ... ... ... + 2416 0 -39.285824 -14.607491 61.715790 + 2417 0 35.067146 -14.150043 160.817917 + 2418 0 -29.756786 -15.303859 -52.663750 + 2419 0 1.141870 63.609570 162.176315 + 2420 0 23.913206 -35.665077 54.719437 + + [3825 rows x 3 columns] + ) + +Each row of the DataFrame represents one particle and the row index is broken down into "entry" and "subentry" levels. If the selected TBranches include data with different numbers of values per entry, then the return value is not a DataFrame, but a tuple of DataFrames, one for each multiplicity. See the `Pandas documentation on joining `__ for tips on how to analyze DataFrames with partially shared keys ("entry" but not "subentry"). + +Iterating over intervals of entries +----------------------------------- + +If you're working with large datasets, you might not have enough memory to read all entries from the TBranches you need or you might not be able to compute derived quantities for the same number of entries. + +In general, array-based workflows must iterate over batches with an optimized step size: + +- If the batches are too large, you'll run out of memory. +- If the batches are too small, the process will be slowed by the overhead of preparing to calculate each batch. (Array functions like the ones in NumPy and Awkward Array do one-time setup operations in slow Python and large-scale number crunching in compiled code.) + +Procedural workflows, which operate on one entry (e.g. one particle physics collision event) at a time can be seen as an extreme of the latter, in which the batch size is one. + +The :py:meth:`~uproot4.behaviors.TBranch.HasBranches.iterate` method has an interface like :py:meth:`~uproot4.behaviors.TBranch.TBranch.arrays`, except that takes a ``step_size`` parameter and iterates over batches of that size, rather than returning a single array group. + +.. code-block:: python + + >>> events = uproot4.open("https://scikit-hep.org/uproot/examples/Zmumu.root:events") + + >>> for batch in events.iterate(step_size=500): + ... print(repr(batch)) + ... + + + + + + +With a ``step_size`` of 500, each array group has 500 entries except the last, which can have fewer (304 in this case). Also be aware that the above example reads all TBranches! You will likely want to select TBranches (columns) and the number of entries (rows) to define a batch. (See `Filtering TBranches <#filtering-tbranches>`__ above.) + +Since the optimal step size is "whatever fits in memory," it's better to tune it in memory-size units than number-of-entries units. Different data types have different numbers of bytes per item, but more importantly, different applications extract different sets of TBranches, so "*N* entries" tuned for one application would not be a good tune for another. + +For this reason, it's better to set the ``step_size`` to a number of bytes, such as + +.. code-block:: python + + >>> for batch in events.iterate(step_size="50 kB"): + ... print(repr(batch)) + ... + + + + + +(but much larger in a real case). Here, ``"50 kB"`` corresponds to 667 entries (with the last step being the remainder). It's possible to calculate the number of entries for a given memory size outside of iteration using :py:meth:`~uproot4.behaviors.TBranch.HasBranches.num_entries_for`. + +.. code-block:: python + + >>> events.num_entries_for("50 kB") + 667 + >>> events.num_entries_for("50 kB", filter_name="/p[xyz][12]/") + 1530 + >>> events.keys(filter_typename="double") + ['E1', 'px1', 'py1', 'pz1', 'pt1', 'eta1', 'phi1', 'E2', 'px2', 'py2', 'pz2', 'pt2', 'eta2', + 'phi2', 'M'] + >>> events.num_entries_for("50 kB", filter_typename="double") + 702 + +The number of entries for ``"50 kB"`` depends strongly on which TBranches are being requested. It's the memory size, not the number of entries, that matters most when tuning a workflow for a computer with limited memory. + +See the :py:meth:`~uproot4.behaviors.TBranch.HasBranches.iterate` documentation for more, including a ``report=True`` option to get a :py:class:`~uproot4.behaviors.TBranch.Report` with each batch of data with entry numbers for bookkeeping. + +.. code-block:: python + + >>> for batch, report in events.iterate(step_size="50 kB", report=True): + ... print(report) + ... + Report(, 0, 667) + Report(, 667, 1334) + Report(, 1334, 2001) + Report(, 2001, 2304) + +Just as ``library="np"`` and ``library="pd"`` can be used to get NumPy and Pandas output in :py:meth:`~uproot4.behaviors.TBranch.TBranch.array` and :py:meth:`~uproot4.behaviors.TBranch.HasBranches.arrays`, it can be used to yield NumPy arrays and Pandas DataFrames iteratively: + +.. code-block:: python + + >>> for batch in events.iterate(step_size="100 kB", library="pd"): + ... print(batch) + ... + Type Run Event E1 ... eta2 phi2 Q2 M + 0 GT 148031 10507008 82.201866 ... -1.05139 -0.440873 -1 82.462692 + 1 TT 148031 10507008 62.344929 ... -1.21769 2.741260 1 83.626204 + 2 GT 148031 10507008 62.344929 ... -1.21769 2.741260 1 83.308465 + 3 GG 148031 10507008 60.621875 ... -1.21769 2.741260 1 82.149373 + 4 GT 148031 105238546 41.826389 ... 1.44434 -2.707650 -1 90.469123 + ... ... ... ... ... ... ... ... .. ... + 1328 GT 148031 607496200 4.385337 ... 1.76576 -0.582806 1 7.039820 + 1329 GT 148031 607496200 4.385337 ... 1.81014 2.523670 -1 11.655561 + 1330 TT 148031 607496200 8.301393 ... 1.76576 -0.582806 1 18.127933 + 1331 TT 148031 607496200 8.301393 ... 1.81014 2.523670 -1 6.952658 + 1332 TT 148031 607496200 8.301393 ... 2.18148 0.343855 1 1.759080 + + [1333 rows x 20 columns] + Type Run Event E1 ... eta2 phi2 Q2 M + 1333 GT 148031 607496200 8.301393 ... 1.765760 -0.582806 1 18.099339 + 1334 GT 148031 607496200 8.301393 ... 1.810140 2.523670 -1 6.959646 + 1335 GG 148031 607496200 132.473942 ... 1.765760 -0.582806 1 93.373860 + 1336 GT 148031 608388587 59.548441 ... -0.565288 0.529327 -1 90.782261 + 1337 TT 148031 608388587 51.504863 ... -0.746182 -2.573870 1 90.685446 + ... ... ... ... ... ... ... ... .. ... + 2299 GG 148029 99768888 32.701650 ... -0.645971 -2.404430 -1 60.047138 + 2300 GT 148029 99991333 168.780121 ... -1.570440 0.037027 1 96.125376 + 2301 TT 148029 99991333 81.270136 ... -1.482700 -2.775240 -1 95.965480 + 2302 GT 148029 99991333 81.270136 ... -1.482700 -2.775240 -1 96.495944 + 2303 GG 148029 99991333 81.566217 ... -1.482700 -2.775240 -1 96.656728 + + [971 rows x 20 columns] + +Iterating over many files +------------------------- + +Large datasets usually consist of many files, and abstractions like `ROOT's TChain `__ simplify multi-file workflows by making a collection of files look like a single file. + +Uproot's :py:meth:`~uproot4.behaviors.TBranch.HasBranches.iterate` takes a step in the opposite direction: it breaks single-file access into batches, and designing a workflow around batches is like designing a workflow around files. To apply such an interface to many files, all that is needed is a way to express the list of files. + +The `uproot4.iterate `__ function (as opposed to the `HasBranches.iterate `__ method) takes a list of files as its first argument: + +.. code-block:: python + + >>> for batch in uproot4.iterate(["dir1/*.root:events", "dir2/*.root:events"]): + ... do_something... + +As with the single-file method, you'll want to restrict the set of TBranches to include only those you use. (See `Filtering TBranches <#filtering-tbranches>`__ above.) + +The specification of file names has to include paths to the ``TTree`` objects (more generally, :py:class:`~uproot4.behaviors.TBranch.HasBranches` objects), so the colon (``:``) separating file path and object path `described above <#finding-objects-in-a-file>` is more than just a convenience in this case. Since it is possible for file paths to include colons as part of the file or directory name, the following alternate syntax can also be used: + +.. code-block:: python + + >>> for batch in uproot4.iterate([{"dir1/*.root": "events"}, {"dir2/*.root": "events"}]): + ... do_something... + +If the ``step_size`` (same meaning as in previous section) is smaller than the file size, the last batch of each file will likely be smaller than the rest: batches from one file are not mixed with batches from another file. Thus, the largest meaningful ``step_size`` is the number of entries in the file (:py:attr:`~uproot4.behaviors.TBranch.HasBranches.num_entries`). See the next section for concatenating small files. + +In multi-file iteration, the :py:class:`~uproot4.behaviors.TBranch.Report` returned by ``report=True`` distinguishes between global entry numbers (:py:attr:`~uproot4.behaviors.TBranch.Report.global_entry_start` and :py:attr:`~uproot4.behaviors.TBranch.Report.global_entry_stop`), which start once at the beginning of iteration, and TTree entry numbers (:py:attr:`~uproot4.behaviors.TBranch.Report.tree_entry_start` and :py:attr:`~uproot4.behaviors.TBranch.Report.tree_entry_stop`), which restart at the beginning of each TTree. The :py:attr:`~uproot4.behaviors.TBranch.Report.tree`, :py:attr:`~uproot4.behaviors.TBranch.Report.file`, and :py:attr:`~uproot4.behaviors.TBranch.Report.file_path` attributes are also more useful in multi-file iteration. + +Reading many files into big arrays +---------------------------------- + +Although it iterates over multiple files, the `uproot4.iterate `__ function is not a direct analogy of `ROOT's TChain `__ because it does not make multi-file workflows look like single-file (non-iterating) workflows. + +The simplest way to access many files is to concatenate them into one array. The `uproot4.concatenate `__ function is a multi-file analogue of the `HasBranches.arrays `__ method, in that it returns a single array group. + +.. code-block:: python + + >>> events.concatenate(["dir1/*.root:events", "dir2/*.root:events"], filter_name="p*1") + + +The arrays of all files have been entirely read into memory. In general, this is only possible if + +- the files are small, +- the number of files is small, or +- the selected branches do not represent a large fraction of the files. + +If your computer has enough memory to do this, then it will likely be the fastest way to process the data, and it's certainly easier than accumulating partial results in a loop. However, if you're working on a small subsample that will be scaled up to a bigger analysis, then it would be a bad idea to develop your analysis with this interface. You would likely need to restructure it as a loop later. + +(As a multi-file function, `uproot4.concatenate `__ specifies file paths and TTree object paths just like `uproot4.iterate `__.) + +Reading on demand with lazy arrays +---------------------------------- + +Lazy-loading is a third way to access multi-file datasets, like `uproot4.iterate `__ and `uproot4.concatenate `__ above. As such, it's a third analogy with `ROOT's TChain `__. + +The interface to `uproot4.lazy `__ is like `uproot4.concatenate `__ in that it returns a single object, not an iterator that you have to iterate through, but it is like `uproot4.iterate `__ in that the data are not loaded immediately and do not need to reside in memory all at once. + +.. code-block:: python + + >>> array = events.lazy(["dir1/*.root:events", "dir2/*.root:events"]) + >>> array + + +When `uproot4.lazy `__ is called, it opens all of the specified files and TTree metadata, but none of the TBranch data. It uses the TBranch names and types, as well as the TTree :py:attr:`~uproot4.behaviors.TTree.TTree.num_entries`, to define the data type and prepare batches for reading. Only when you access items in the array, such as printing them to the screen or performing a calculation on them, are the relevant TBranches read (in batches). + +This lazy-loading uses an Awkward Array feature, so ``library="ak"`` is the only library option. + +The fact that the data are being loaded on demand is (intentionally) hidden; one of the few ways to demonstrate that it is happening is by watching its cache fill up. When we first open a lazy array, the cache is empty. + +.. code-block:: python + + >>> array = uproot4.lazy("https://scikit-hep.org/uproot/examples/Zmumu.root:events", + ... step_size=100) + >>> array.cache + + +If we then ask for a single element from a single field, it loads one TBranch-batch. Since we specified the ``step_size=100`` (much too small for a real case; the default is ``"100 MB"``), this TBranch-bath is 100 entries, or 800 bytes. + +.. code-block:: python + + >>> array["px1", 0] + -41.1952876442 + >>> array.cache + + +Requesting another element from the same TBranch-batch doesn't load anything else. The whole batch is already in memory. + +.. code-block:: python + + >>> array["px1", 1] + 35.1180497674 + >>> array.cache + + +Requesting an element from the next TBranch-batch loads the next batch. + +.. code-block:: python + + >>> array["px1", 100] + 27.3430272161 + >>> array.cache + + +Requesting a different TBranch also loads a batch. + +.. code-block:: python + + >>> array["py1", 100] + 11.351229626 + >>> array.cache + + +Performing a calculation on these two fields, ``array.px1`` and ``array.py1``, loads all batches for these two TBranches. Derived quantities, such as the result of the square root operation, are normal arrays (not lazy). + +.. code-block:: python + + >>> import numpy as np + >>> np.sqrt(array.px1**2 + array.py1**2) + + >>> array.cache + + +Although lazy arrays combine the convenience of `uproot4.concatenate `__ with the gradual loading of `uproot4.iterate `__, it is not always the most efficient way to process data. Derived quantities are fully resident in memory, and most data analyses compute more quantities than they read. + +Moreover, if a lazy array is larger than its cache, reading the last batches will cause the first batches to be evicted from the cache. If it is accessed again, the first batches will need to be fully re-read, which evicts the last batches, guaranteeing that data will never be found in the cache when it's needed. + +For example, in a calculation like this: + +.. code-block:: python + + >>> p = np.sqrt(array.px1**2 + array.py1**2 + array.pz1**2) + >>> pt = np.sqrt(array.px1**2 + array.py1**2) + +if the three TBranches ``px1``, ``py1``, ``pz1`` don't entirely fit into their shared cache or individual caches, then none of the data loaded while computing ``p`` will be available to compute ``pt``. Small enough caches can guarantee file re-reading, which would be the slowest step in simple calculations like the above. + +On the other hand, if you make the cache(s) large enough to accommodate all the arrays you'll be loading, then you might as well load them entirely into memory (with `uproot4.concatenate `__). Avoiding the overhead of managing lazy batch-loading can only streamline a workflow. + +So when are lazy arrays useful? + +Lazy arrays are especially useful for exploring a large dataset in a convenient way. If you don't know which TBranches you will be looking at, lazy arrays save you the upfront cost of reading them all, if that were even possible. You can perform calculations interactively without having to set up iterative loops, developing the pieces of a data analysis that will later be incorporated into an efficient loop based on `uproot4.iterate `__. + +Caching and memory management +----------------------------- + +Many of the functions described above have ``object_cache`` and ``array_cache`` options. + +The ``object_cache`` stores a number of objects like TDirectories, histograms, and TTrees. The main effect of this is that + +.. code-block:: python + + >>> file = uproot4.open("https://scikit-hep.org/uproot/examples/hepdata-example.root") + >>> histogram = file["hpx"] + >>> (histogram, histogram) + (, ) + +and + +.. code-block:: python + + >>> (file["hpx"], file["hpx"]) + (, ) + +have identical performance. Not having to declare names for things that are already referenced by name simplifies bookkeeping. + +The ``array_cache`` stores array outputs up to a maximum number of bytes. The arrays must have an ``nbytes`` attribute or property to track usage. As with the ``object_cache``, the ``array_cache`` ensures that + +.. code-block:: python + + >>> events = uproot4.open("https://scikit-hep.org/uproot/examples/Zmumu.root:events") + >>> array = events["px1"].array() + >>> (array, array) + (, + ) + +and + +.. code-block:: python + + >>> (events["px1"].array(), events["px1"].array()) + (, + ) + +have the same performance, assuming that the caches are not overrun. + +The default caches are global objects, ``uproot4.object_cache`` (:py:class:`~uproot4.cache.LRUCache`) and ``uproot4.array_cache`` (:py:class:`~uproot4.cache.LRUArrayCache`). + +.. code-block:: python + + >>> uproot4.object_cache + + >>> uproot4.array_cache + + +The defaults should be fine for general use, but you may want to override them for performance tuning. The `uproot4.open `__ function lets you specify a new ``object_cache`` and ``array_cache`` for a specific file, which can be any `MutableMapping `__ (including a plain dict, which would keep objects forever) or ``None`` if you don't want any cache. + +Similarly, the array-fetching methods and functions: + +- :py:meth:`~uproot4.behaviors.TBranch.TBranch.array` +- :py:meth:`~uproot4.behaviors.TBranch.HasBranches.arrays` +- :py:meth:`~uproot4.behaviors.TBranch.HasBranches.iterate` +- `uproot4.iterate `__ +- `uproot4.concatenate `__ +- `uproot4.lazy `__ + +have an ``array_cache`` option that allows you to override the file's ``array_cache``. + +Parallel processing +------------------- + +Data are or can be read in parallel in each of the following three stages. + +- Physically reading bytes from disk or remote sources: the parallel processing or single-thread background processing is handled by the specific :py:class:`~uproot4.source.chunk.Source` type, which can be influenced with `uproot4.open `__ options (particularly ``num_workers`` and ``num_fallback_workers``). +- Decompressing TBasket (:py:class:`~uproot4.models.TBasket.Model_TBasket`) data: depends on the ``decompression_executor``. +- Interpreting decompressed data with an array :py:class:`~uproot4.interpretation.Interpretation`: depends on the ``interpretation_executor``. + +Like the caches, the default values for the last two are global ``uproot4.decompression_executor`` and ``uproot4.interpretation_executor`` objects. The default ``decompression_executor`` is a :py:class:`~uproot4..source.futures.ThreadPoolExecutor` with as many workers as your computer has CPU cores. Decompression workloads are executed in compiled extensions with the `Python GIL `__ released, so they can afford to run with full parallelism. The default ``interpretation_executor`` is a :py:class:`~uproot4.source.futures.TrivialExecutor` that behaves like an distributed executor, but actually runs sequentially. Most interpretation workflows are not computationally intensive or are currently implemented in Python, so they would not currently benefit from parallelism. + +If, however, you're working in an environment that puts limits on parallel processing (e.g. the CMS LPC or informal university computers), you may want to modify the defaults, either locally through a ``decompression_executor`` or ``interpretation_executor`` function parameter, or globally by replacing the global object. diff --git a/docs-sphinx/conf.py b/docs-sphinx/conf.py new file mode 100644 index 000000000..9848d8ff7 --- /dev/null +++ b/docs-sphinx/conf.py @@ -0,0 +1,57 @@ +# Configuration file for the Sphinx documentation builder. +# +# This file only contains a selection of the most common options. For a full +# list see the documentation: +# https://www.sphinx-doc.org/en/master/usage/configuration.html + +# -- Path setup -------------------------------------------------------------- + +# If extensions (or modules to document with autodoc) are in another directory, +# add these directories to sys.path here. If the directory is relative to the +# documentation root, use os.path.abspath to make it absolute, like shown here. +# +# import os +# import sys +# sys.path.insert(0, os.path.abspath(".")) + +# -- Project information ----------------------------------------------------- + +project = "Uproot" +copyright = "2020, Jim Pivarski" +author = "Jim Pivarski" + +# -- General configuration --------------------------------------------------- + +# Add any Sphinx extension module names here, as strings. They can be +# extensions coming with Sphinx (named "sphinx.ext.*") or your custom +# ones. +extensions = ["sphinx.ext.autodoc", "sphinx.ext.napoleon"] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ["_templates"] + +# List of patterns, relative to source directory, that match files and +# directories to ignore when looking for source files. +# This pattern also affects html_static_path and html_extra_path. +exclude_patterns = ["_build", "Thumbs.db", ".DS_Store"] + +# -- Options for HTML output ------------------------------------------------- + +# The theme to use for HTML and HTML Help pages. See the documentation for +# a list of builtin themes. +# +html_theme = "sphinx_rtd_theme" +html_logo = "../docs-img/logo/logo-300px-white.png" +html_show_sourcelink = False +html_theme_options = {"logo_only": True, "sticky_navigation": False} + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +html_static_path = [] # "_static" + +# Additional stuff +master_doc = "index" + +exec(open("prepare_docstrings.py").read(), dict(globals())) +# exec(open("make_changelog.py").read(), dict(globals())) diff --git a/docs-sphinx/index.rst b/docs-sphinx/index.rst new file mode 100644 index 000000000..f54e5b8f5 --- /dev/null +++ b/docs-sphinx/index.rst @@ -0,0 +1,91 @@ +.. toctree:: + :caption: Tutorials + :hidden: + + basic + uproot3-to-4 + +.. include:: uproot4.toctree + +.. include:: uproot4.reading.toctree + +.. include:: uproot4.behaviors.toctree + +.. include:: uproot4.model.toctree + +.. include:: uproot4.streamers.toctree + +.. include:: uproot4.cache.toctree + +.. include:: uproot4.compression.toctree + +.. include:: uproot4.deserialization.toctree + +.. include:: uproot4.source.toctree + +.. include:: uproot4.interpretation.toctree + +.. include:: uproot4.containers.toctree + +.. include:: uproot4.language.toctree + +.. include:: uproot4.models.toctree + +.. include:: uproot4.const.toctree + +.. include:: uproot4.extras.toctree + +.. include:: uproot4.version.toctree + +.. toctree:: + :hidden: + + uproot4.dynamic + +.. |br| raw:: html + +
+ +.. image:: https://github.com/scikit-hep/uproot4/raw/master/docs-img/logo/logo-300px.png + :width: 300px + :alt: Uproot + +|br| Uproot is a library for reading (and soon, writing) ROOT files in pure Python and NumPy. + +How to install +============== + +Usually, you'll want to install Uproot with `Awkward Array `__ because this is the default array format. + +.. code-block:: bash + + pip install uproot4 awkward1 + +But if you are working in a limited environment, Uproot can be installed without Awkward Array. + +.. code-block:: bash + + pip install uproot4 + +Just be sure to pass ``library="np"`` to any function that returns arrays to specify that you want NumPy arrays, rather than Awkward arrays. Other array libraries include `Pandas `__ and `CuPy `__, which, like Awkward, would need to be explicitly installed. + +Documentation +============= + +**ROOT** is a C++ toolkit for data analysis, part of which is the ROOT file format. Over an exabyte of particle physics data are stored in ROOT files around the world. + +**Uproot** is a Python implementation of ROOT I/O, independent of the ROOT toolkit itself (including ROOT's Python interface, PyROOT). + +- If you need help understanding ROOT and its ecosystem, see the `ROOT project documentation `__. +- If you know what a ROOT file is but are unfamiliar with Uproot, see the :doc:`basic`. +- If you are migrating from an older version to Uproot 4, see the :doc:`uproot3-to-4`. +- If you need detailed descriptions of a class's properties or a function's parameters, see the left-bar on this site (≡ button on mobile) or use ``help`` in Python, ``?`` or shift-tab in iPython/Jupyter. + +Getting help +============ + +Report bugs, request features, and ask for additional documentation on `GitHub Issues `__. + +If you have a problem that's too specific to be new documentation or it isn't exclusively related to Uproot, it might be more appropriate to ask on `StackOverflow with the [uproot] tag `__. Be sure to include tags for any other libraries that you use, such as boost-histogram or Pandas. + +The `Gitter Scikit-HEP/community `__ is a way to get in touch with all Scikit-HEP developers and users. diff --git a/docs-sphinx/make_changelog.py b/docs-sphinx/make_changelog.py new file mode 100644 index 000000000..f3b47a289 --- /dev/null +++ b/docs-sphinx/make_changelog.py @@ -0,0 +1,135 @@ +# # BSD 3-Clause License; see https://github.com/jpivarski/awkward-1.0/blob/master/LICENSE + +# import math +# import json +# import subprocess +# import re +# import http.client +# import datetime + +# tagslist_text = subprocess.run(["git", "show-ref", "--tags"], stdout=subprocess.PIPE).stdout +# tagslist = dict(re.findall(rb"([0-9a-f]{40}) refs/tags/([0-9\.]+)", tagslist_text)) + +# subjects_text = subprocess.run(["git", "log", "--format='format:%H %s'"], stdout=subprocess.PIPE).stdout +# subjects = re.findall(rb"([0-9a-f]{40}) (.*)", subjects_text) + +# github_connection = http.client.HTTPSConnection("api.github.com") +# github_releases = [] +# numpages = int(math.ceil(len(tagslist) / 30.0)) +# for pageid in range(numpages): +# print("Requesting GitHub data, page {0} of {1}".format(pageid + 1, numpages)) +# github_connection.request("GET", r"/repos/scikit-hep/awkward-1.0/releases?page={0}&per_page=30".format(pageid + 1), headers={"User-Agent": "awkward1-changelog"}) +# github_releases_text = github_connection.getresponse().read() +# try: +# github_releases_page = json.loads(github_releases_text) +# except: +# print(github_releases_text) +# raise +# print(len(github_releases_page)) +# github_releases.extend(github_releases_page) + +# releases = {x["tag_name"]: x["body"] for x in github_releases if "tag_name" in x and "body" in x} +# dates = {x["tag_name"]: datetime.datetime.fromisoformat(x["published_at"].rstrip("Z")).strftime("%A, %d %B, %Y") for x in github_releases if "tag_name" in x and "published_at" in x} +# tarballs = {x["tag_name"]: x["tarball_url"] for x in github_releases if "tag_name" in x and "tarball_url" in x} +# zipballs = {x["tag_name"]: x["zipball_url"] for x in github_releases if "tag_name" in x and "zipball_url" in x} + +# pypi_connection = http.client.HTTPSConnection("pypi.org") + +# def pypi_exists(tag): +# print("Looking for release {0} on PyPI...".format(tag)) +# pypi_connection.request("HEAD", "/project/awkward1/{0}/".format(tag)) +# response = pypi_connection.getresponse() +# response.read() +# return response.status == 200 + +# with open("_auto/changelog.rst", "w") as outfile: +# outfile.write("Release history\n") +# outfile.write("---------------\n") + +# first = True +# numprs = None + +# for taghash, subject in subjects: +# if taghash in tagslist: +# tag = tagslist[taghash].decode() +# tagurl = "https://github.com/scikit-hep/awkward-1.0/releases/tag/{0}".format(tag) + +# if numprs == 0: +# outfile.write("*(no pull requests)*\n") +# numprs = 0 + +# header_text = "\nRelease `{0} <{1}>`__\n".format(tag, tagurl) +# outfile.write(header_text) +# outfile.write("="*len(header_text) + "\n\n") + +# if tag in dates: +# date_text = "**" + dates[tag] + "**" +# else: +# date_text = "" + +# assets = [] +# if pypi_exists(tag): +# assets.append("`pip `__".format(tag)) +# if tag in tarballs: +# assets.append("`tar <{0}>`__".format(tarballs[tag])) +# if tag in zipballs: +# assets.append("`zip <{0}>`__".format(zipballs[tag])) +# if len(assets) == 0: +# assets_text = "" +# else: +# assets_text = " ({0})".format(", ".join(assets)) + +# if len(date_text) + len(assets_text) > 0: +# outfile.write("{0}{1}\n\n".format(date_text, assets_text)) + +# if tag in releases: +# text = releases[tag].strip().replace("For details, see the [release history](https://awkward-array.readthedocs.io/en/latest/_auto/changelog.html).", "") +# text = re.sub(r"([a-zA-Z0-9\-_]+/[a-zA-Z0-9\-_]+)#([1-9][0-9]*)", r"`\1#\2 `__", text) +# text = re.sub(r"([^a-zA-Z0-9\-_])#([1-9][0-9]*)", r"\1`#\2 `__", text) +# outfile.write(text + "\n\n") + +# first = False + +# m = re.match(rb"(.*) \(#([1-9][0-9]*)\)", subject) +# if m is not None: +# if numprs is None: +# numprs = 0 +# numprs += 1 + +# if first: +# header_text = "\nUnreleased (`master branch `__ on GitHub)\n" +# outfile.write(header_text) +# outfile.write("="*len(header_text) + "\n\n") + +# text = m.group(1).decode().strip() +# prnum = m.group(2).decode() +# prurl = "https://github.com/scikit-hep/awkward-1.0/pull/{0}".format(prnum) + +# known = [prnum] +# for issue in re.findall(r"([a-zA-Z0-9\-_]+/[a-zA-Z0-9\-_]+)#([1-9][0-9]*)", text): +# known.append(issue) +# for issue in re.findall(r"([^a-zA-Z0-9\-_])#([1-9][0-9]*)", text): +# known.append(issue[1]) + +# text = re.sub(r"`", "``", text) +# text = re.sub(r"([a-zA-Z0-9\-_]+/[a-zA-Z0-9\-_]+)#([1-9][0-9]*)", r"`\1#\2 `__", text) +# text = re.sub(r"([^a-zA-Z0-9\-_])#([1-9][0-9]*)", r"\1`#\2 `__", text) +# if re.match(r".*[a-zA-Z0-9_]$", text): +# text = text + "." + +# body_text = subprocess.run(["git", "log", "-1", taghash.decode(), "--format='format:%b'"], stdout=subprocess.PIPE).stdout.decode() +# addresses = [] +# for issue in re.findall(r"([a-zA-Z0-9\-_]+/[a-zA-Z0-9\-_]+)#([1-9][0-9]*)", body_text): +# if issue not in known: +# addresses.append("`{0}#{1} `__".format(issue[0], issue[1])) +# for issue in re.findall(r"([^a-zA-Z0-9\-_])#([1-9][0-9]*)", body_text): +# if issue[1] not in known: +# addresses.append("`#{0} `__".format(issue[1])) +# if len(addresses) == 0: +# addresses_text = "" +# else: +# addresses_text = " (**also:** {0})".format(", ".join(addresses)) + +# outfile.write("* PR `#{0} <{1}>`__: {2}{3}\n".format(prnum, prurl, text, addresses_text)) + +# first = False diff --git a/docs-sphinx/prepare_docstrings.py b/docs-sphinx/prepare_docstrings.py new file mode 100644 index 000000000..d4dff3192 --- /dev/null +++ b/docs-sphinx/prepare_docstrings.py @@ -0,0 +1,188 @@ +# BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/master/LICENSE + +import importlib +import inspect +import pkgutil +import os.path + + +order = [ + "uproot4", + "uproot4.reading", + "uproot4.behaviors", + "uproot4.model", + "uproot4.streamers", + "uproot4.cache", + "uproot4.compression", + "uproot4.deserialization", + "uproot4.source", + "uproot4.interpretation", + "uproot4.containers", + "uproot4.language", + "uproot4.models", + "uproot4.const", + "uproot4.extras", + "uproot4.version", +] + +toctree = open("uproot4.toctree", "w") +toctree.write( + """.. toctree:: + :caption: Reference + :hidden: + +""" +) + + +def ensure(objname, filename, content): + overwrite = not os.path.exists(filename) + if not overwrite: + overwrite = open(filename, "r").read() != content + if overwrite: + open(filename, "w").write(content) + print(objname, "(OVERWRITTEN)") + else: + print(objname) + + +def handle_module(modulename, module): + content = """{0} +{1} + +.. automodule:: {0} +""".format( + modulename, "=" * len(modulename) + ) + ensure(modulename, modulename + ".rst", content) + toctree.write(" " + modulename + "\n") + + if modulename != "uproot4" and all( + not x.startswith("_") for x in modulename.split(".") + ): + + def good(obj): + if inspect.isfunction(obj) or inspect.isclass(obj): + if obj.__module__ == modulename: + return True + return False + + def line_order(pair): + name, obj = pair + return inspect.getsourcelines(obj)[1] + + for pair in sorted(inspect.getmembers(module, good), key=line_order): + name, obj = pair + if not name.startswith("_"): + if inspect.isclass(obj): + handle_class(modulename + "." + name, obj) + elif inspect.isfunction(obj): + handle_function(modulename + "." + name, obj) + + +def handle_class(classname, cls): + def line_order(obj): + if isinstance(obj, property): + obj = obj.fget + return inspect.getsourcelines(obj)[1] + + methods = {} + mro = list(cls.__mro__) + + for index, basecls in enumerate(mro): + if basecls.__module__.startswith("uproot4."): + + def good(obj): + if inspect.ismethod(obj) or inspect.isfunction(obj): + module, name = obj.__module__, obj.__name__ + elif isinstance(obj, property): + module, name = obj.fget.__module__, obj.fget.__name__ + else: + module, name = "", "" + if module.startswith("uproot4."): + if index + 1 >= len(mro) or obj is not getattr( + mro[index + 1], name, None + ): + return True + return False + + for name, obj in inspect.getmembers(basecls, good): + if name in basecls.__dict__ and not name.startswith("_"): + fill = [] + fill.append(name) + fill.append("-" * len(fill[-1])) + fill.append("") + if basecls is not cls: + fill.append( + "Inherited from :doc:`{0}`.".format( + basecls.__module__ + "." + basecls.__name__ + ) + ) + fill.append("") + if isinstance(obj, property): + fill.append(".. autoattribute:: " + classname + "." + name) + else: + fill.append(".. automethod:: " + classname + "." + name) + fill.append("") + methods[name] = (index, line_order(obj), "\n".join(fill)) + + def prettymro(c): + fullname = c.__module__ + "." + c.__name__ + if c.__module__.startswith("uproot4."): + return "#. :doc:`" + fullname + "`" + else: + return "#. ``" + fullname + "``" + + content = """{0} +{1} + +{2} + +.. autoclass:: {0} + +{3} +""".format( + classname, + "=" * len(classname), + "\n".join(prettymro(c) for c in cls.__mro__[1:] if c is not object), + "\n".join([text for index, line, text in sorted(methods.values())]), + ) + + ensure(classname, classname + ".rst", content) + toctree.write(" " + classname + "\n") + + +def handle_function(functionname, cls): + content = """{0} +{1} + +.. autofunction:: {0} +""".format( + functionname, "=" * len(functionname) + ) + ensure(functionname, functionname + ".rst", content) + toctree.write(" " + functionname + "\n") + + +for modulename in order: + module = importlib.import_module(modulename) + + if modulename != "uproot4": + toctree = open(modulename + ".toctree", "w") + toctree.write( + """.. toctree:: + :hidden: + +""" + ) + + handle_module(modulename, module) + if module.__file__.endswith("__init__.py") and modulename != "uproot4": + for submodulename in sorted( + [ + modulename + "." + name + for loader, name, is_pkg in pkgutil.walk_packages(module.__path__) + ] + ): + submodule = importlib.import_module(submodulename) + handle_module(submodulename, submodule) diff --git a/docs-sphinx/requirements.txt b/docs-sphinx/requirements.txt new file mode 100644 index 000000000..edca8ad78 --- /dev/null +++ b/docs-sphinx/requirements.txt @@ -0,0 +1 @@ +sphinx>=2.4.4 diff --git a/docs-sphinx/uproot3-to-4.rst b/docs-sphinx/uproot3-to-4.rst new file mode 100644 index 000000000..172c7c2a6 --- /dev/null +++ b/docs-sphinx/uproot3-to-4.rst @@ -0,0 +1,6 @@ +Uproot 3 → 4 cheat-sheet +======================== + +I'm collecting ideas for this cheat-sheet on the `Uproot 4 wiki `__. + +If you think of something that would be good for me to write here, dump it there (doesn't need to be polished). diff --git a/uproot4/__init__.py b/uproot4/__init__.py index aebd6835a..0f7a86f8b 100644 --- a/uproot4/__init__.py +++ b/uproot4/__init__.py @@ -11,63 +11,63 @@ uproot4.open("path/to/filename.root") -but we refer to it in the documentation as :doc:`uproot4.reading.open`. +but we refer to it in the documentation as :py:func:`~uproot4.reading.open`. Typical entry points for file-reading are -* :doc:`uproot4.reading.open` -* :doc:`uproot4.behaviors.TBranch.iterate` -* :doc:`uproot4.behaviors.TBranch.concatenate` -* :doc:`uproot4.behaviors.TBranch.lazy` +* :py:func:`~uproot4.reading.open` +* :py:func:`~uproot4.behaviors.TBranch.iterate` +* :py:func:`~uproot4.behaviors.TBranch.concatenate` +* :py:func:`~uproot4.behaviors.TBranch.lazy` though they would usually be accessed as ``uproot4.iterate``, ``uproot4.concatenate``, and ``uproot4.lazy``. The most useful classes are -* :doc:`uproot4.behaviors.TBranch.HasBranches` (``TTree`` or ``TBranch``) -* :doc:`uproot4.behaviors.TBranch.TBranch` -* :doc:`uproot4.behaviors.TH1` -* :doc:`uproot4.behaviors.TH2` -* :doc:`uproot4.behaviors.TProfile` +* :py:class:`~uproot4.behaviors.TBranch.HasBranches` (``TTree`` or ``TBranch``) +* :py:class:`~uproot4.behaviors.TBranch.TBranch` +* :py:class:`~uproot4.behaviors.TH1` +* :py:class:`~uproot4.behaviors.TH2` +* :py:class:`~uproot4.behaviors.TProfile` though they would usually be accessed through instances that have been read from files. The submodules of Uproot are: -* :doc:`uproot4.version`: for access to the version number. -* :doc:`uproot4.extras`: import functions for the libraries that Uproot can - use, but does not require as dependencies. If a library can't be imported, - these functions provide instructions for installing them. -* :doc:`uproot4.dynamic`: initially empty module, in which dynamically - generated classes are defined. -* :doc:`uproot4.source`: the "physical layer," which reads bytes without - interpreting them from various backends, like files, HTTP(S), and XRootD. -* :doc:`uproot4.compression`: functions for compressing and decompressing data. -* :doc:`uproot4.reading`: entry-point for reading files, as well as classes +* :py:mod:`uproot4.reading`: entry-point for reading files, as well as classes for the three basic types that can't be modeled: ``TFile``, ``TDirectory``, and ``TKey``. -* :doc:`uproot4.streamers`: models for ``TStreamerInfo`` and its elements +* :py:mod:`uproot4.behaviors`: methods and properties to mix into instantiated + models, for a high-level user interface. +* :py:mod:`uproot4.model`: utilities for modeling C++ objects as Python objects. +* :py:mod:`uproot4.streamers`: models for ``TStreamerInfo`` and its elements to generate code for new models for classes in ROOT files. -* :doc:`uproot4.deserialization`: utility functions for deserialization, +* :py:mod:`uproot4.cache`: defines caches with least-recently used eviction + policies. +* :py:mod:`uproot4.compression`: functions for compressing and decompressing data. +* :py:mod:`uproot4.deserialization`: utility functions for deserialization, including the generation of new classes. -* :doc:`uproot4.model`: utilities for modeling C++ objects as Python objects. -* :doc:`uproot4.models`: predefined models for classes that are too basic - to rely on ``TStreamerInfo`` or too common to justify reading it. -* :doc:`uproot4.behaviors`: methods and properties to mix into instantiated - models, for a high-level user interface. -* :doc:`uproot4.interpretation`: prescriptions for converting ROOT types +* :py:mod:`uproot4.source`: the "physical layer," which reads bytes without + interpreting them from various backends, like files, HTTP(S), and XRootD. +* :py:mod:`uproot4.interpretation`: prescriptions for converting ROOT types into Pythonic arrays. -* :doc:`uproot4.containers`: interpretations and models for standard +* :py:mod:`uproot4.containers`: interpretations and models for standard containers, such as ``std::vector`` and arrays. -* :doc:`uproot4.compute`: computational backends for expressions in - :doc:`uproot4.behavior.TBranch.HasBranches.arrays`. -* :doc:`uproot4.cache`: defines caches with least-recently used eviction - policies. -* :doc:`uproot4.const`: integer constants used in ROOT serialization and +* :py:mod:`uproot4.language`: computational backends for expressions in + :py:mod:`uproot4.behavior.TBranch.HasBranches.arrays`. +* :py:mod:`uproot4.models`: predefined models for classes that are too basic + to rely on ``TStreamerInfo`` or too common to justify reading it. +* :py:mod:`uproot4.const`: integer constants used in ROOT serialization and deserialization. -* :doc:`uproot4._util`: non-public utilities used by any of the above. +* :py:mod:`uproot4.extras`: import functions for the libraries that Uproot can + use, but does not require as dependencies. If a library can't be imported, + these functions provide instructions for installing them. +* :py:mod:`uproot4.version`: for access to the version number. +* :py:mod:`uproot4.dynamic`: initially empty module, in which dynamically + generated classes are defined. +* :py:mod:`uproot4._util`: non-public utilities used by the above. """ from __future__ import absolute_import @@ -176,14 +176,14 @@ def behavior_of(classname): The search strategy for finding behavior classes is: 1. Translate the ROOT class name from C++ to Python with - :doc:`uproot4.model.classname_encode`. For example, + :py:func:`~uproot4.model.classname_encode`. For example, ``"ROOT::RThing"`` becomes ``"Model_ROOT_3a3a_RThing"``. 2. Look for a submodule of ``uproot4.behaviors`` without the ``"Model_"`` prefix. For example, ``"ROOT_3a3a_RThing"``. 3. Look for a class in that submodule with the fully encoded name. For example, ``"Model_ROOT_3a3a_RThing"``. - See :doc:`uproot4.behaviors` for details. + See :py:mod:`uproot4.behaviors` for details. """ name = classname_encode(classname) assert name.startswith("Model_") @@ -216,7 +216,7 @@ def behavior_of(classname): class KeyInFileError(KeyError): """ Exception raised by attempts to find ROOT objects in ``TDirectories`` - or ``TBranches`` in :doc:`uproot4.behaviors.TBranch.HasBranches`, which + or ``TBranches`` in :py:class:`~uproot4.behaviors.TBranch.HasBranches`, which both have a Python ``Mapping`` interface (square bracket syntax to extract items). diff --git a/uproot4/behaviors/TBranch.py b/uproot4/behaviors/TBranch.py index 1094c85eb..e5dff79c9 100644 --- a/uproot4/behaviors/TBranch.py +++ b/uproot4/behaviors/TBranch.py @@ -1,13 +1,14 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/master/LICENSE """ -Defines behaviors for :doc:`uproot4.behaviors.TBranch.TBranch` and -:doc:`uproot4.behaviors.TBranch.HasBranches` (both ``TBranch`` and ``TTree``). +Defines behaviors for :py:class:`~uproot4.behaviors.TBranch.TBranch` and +:py:class:`~uproot4.behaviors.TBranch.HasBranches` (both ``TBranch`` and +``TTree``). Most of the functionality of TTree-reading is implemented here. -See :doc:`uproot4.models.TBranch` for deserialization of the ``TBranch`` objects -themselves. +See :py:class:`~uproot4.models.TBranch` for deserialization of the ``TBranch`` +objects themselves. """ from __future__ import absolute_import @@ -17,7 +18,6 @@ import sys import re import threading -import collections import itertools try: @@ -105,19 +105,19 @@ def iterate( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. If the function + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. If the function returns False or None, the ``TBranch`` is excluded; if the function returns True, it is included with its standard - :doc:`uproot4.behaviors.TBranch.TBranch.interpretation`; if an - :doc:`uproot4.interpretation.Interpretation`, this interpretation + :py:class:`~uproot4.behaviors.TBranch.TBranch.interpretation`; if an + :py:class:`~uproot4.interpretation.Interpretation`, this interpretation overrules the standard one. aliases (None or dict of str \u2192 str): Mathematical expressions that can be used in ``expressions`` or other aliases (without cycles). Uses the ``language`` engine to evaluate. If None, only the - :doc:`uproot4.behaviors.TBranch.TBranch.aliases` are available. - language (:doc:`uproot4.language.Language`): Language used to interpret + :py:attr:`~uproot4.behaviors.TBranch.TBranch.aliases` are available. + language (:py:class:`~uproot4.language.Language`): Language used to interpret the ``expressions`` and ``aliases``. step_size (int or str): If an integer, the maximum number of entries to include in each iteration step; if a string, the maximum memory size @@ -130,7 +130,7 @@ def iterate( executor that is used to interpret uncompressed ``TBasket`` data as arrays; if None, the global ``uproot4.interpretation_executor`` is used. - library (str or :doc:`uproot4.interpretation.library.Library`): The library + library (str or :py:class:`~uproot4.interpretation.library.Library`): The library that is used to represent arrays. Options are ``"np"`` for NumPy, ``"ak"`` for Awkward Array, ``"pd"`` for Pandas, and ``"cp"`` for CuPy. @@ -140,11 +140,11 @@ def iterate( must be passed as ``how``, not an instance of that type (i.e. ``how=tuple``, not ``how=()``). report (bool): If True, this generator yields - (:doc:`uproot4.behaviors.TBranch.Report, arrays) pairs; if False, + (arrays, :py:class:`~uproot4.behaviors.TBranch.Report`) pairs; if False, it only yields arrays. The report has data about the ``TFile``, ``TTree``, and global and local entry ranges. custom_classes (None or dict): If a dict, override the classes from - the :doc:`uproot4.reading.ReadOnlyFile` or ``uproot4.classes``. + the :py:class:`~uproot4.reading.ReadOnlyFile` or ``uproot4.classes``. allow_missing (bool): If True, skip over any files that do not contain the specified ``TTree``. options: See below. @@ -178,10 +178,10 @@ def iterate( Options (type; default): - * file_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.file.MemmapSource`) - * xrootd_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.xrootd.XRootDSource`) - * http_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.http.HTTPSource`) - * object_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.object.ObjectSource`) + * file_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.file.MemmapSource`) + * xrootd_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.xrootd.XRootDSource`) + * http_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.http.HTTPSource`) + * object_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.object.ObjectSource`) * timeout (float for HTTP, int for XRootD; 30) * max_num_elements (None or int; None) * num_workers (int; 1) @@ -189,17 +189,17 @@ def iterate( * begin_chunk_size (memory_size; 512) * minimal_ttree_metadata (bool; True) - See also :doc:`uproot4.behavior.TBranch.HasBranches.iterate` to iterate + See also :py:meth:`~uproot4.behavior.TBranch.HasBranches.iterate` to iterate within a single file. Other file entry points: - * :doc:`uproot4.reading.open`: opens one file to read any of its objects. - * :doc:`uproot4.behaviors.TBranch.iterate` (this function): iterates through + * :py:func:`~uproot4.reading.open`: opens one file to read any of its objects. + * :py:func:`~uproot4.behaviors.TBranch.iterate` (this function): iterates through chunks of contiguous entries in ``TTrees``. - * :doc:`uproot4.behaviors.TBranch.concatenate`: returns a single concatenated + * :py:func:`~uproot4.behaviors.TBranch.concatenate`: returns a single concatenated array from ``TTrees``. - * :doc:`uproot4.behaviors.TBranch.lazy`: returns a lazily read array from + * :py:func:`~uproot4.behaviors.TBranch.lazy`: returns a lazily read array from ``TTrees``. """ files = _regularize_files(files) @@ -208,8 +208,10 @@ def iterate( ) library = uproot4.interpretation.library._regularize_library(library) - global_start = 0 + global_offset = 0 for file_path, object_path in files: + print(file_path, global_offset) + hasbranches = _regularize_object_path( file_path, object_path, custom_classes, allow_missing, options ) @@ -232,25 +234,15 @@ def iterate( report=report, ): if report: - arrays, local_report = item - global_entry_start = local_report.tree_entry_start - global_entry_stop = local_report.tree_entry_stop - global_entry_start += global_start - global_entry_stop += global_start - global_report = type(local_report)( - *( - (global_entry_start, global_entry_stop) - + local_report[2:] - ) - ) - arrays = library.global_index(arrays, global_start) - yield arrays, global_report - + arrays, report = item + arrays = library.global_index(arrays, global_offset) + report = report.to_global(global_offset) + yield arrays, report else: - arrays = library.global_index(item, global_start) + arrays = library.global_index(item, global_offset) yield arrays - global_start += hasbranches.num_entries + global_offset += hasbranches.num_entries def concatenate( @@ -284,19 +276,19 @@ def concatenate( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. If the function + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. If the function returns False or None, the ``TBranch`` is excluded; if the function returns True, it is included with its standard - :doc:`uproot4.behaviors.TBranch.TBranch.interpretation`; if an - :doc:`uproot4.interpretation.Interpretation`, this interpretation + :py:attr:`~uproot4.behaviors.TBranch.TBranch.interpretation`; if an + :py:class:`~uproot4.interpretation.Interpretation`, this interpretation overrules the standard one. aliases (None or dict of str \u2192 str): Mathematical expressions that can be used in ``expressions`` or other aliases (without cycles). Uses the ``language`` engine to evaluate. If None, only the - :doc:`uproot4.behaviors.TBranch.TBranch.aliases` are available. - language (:doc:`uproot4.language.Language`): Language used to interpret + :py:attr:`~uproot4.behaviors.TBranch.TBranch.aliases` are available. + language (:py:class:`~uproot4.language.Language`): Language used to interpret the ``expressions`` and ``aliases``. decompression_executor (None or Executor with a ``submit`` method): The executor that is used to decompress ``TBaskets``; if None, the @@ -308,7 +300,7 @@ def concatenate( array_cache (None, MutableMapping, or memory size): Cache of arrays; if None, do not use a cache; if a memory size, create a new cache of this size. - library (str or :doc:`uproot4.interpretation.library.Library`): The library + library (str or :py:class:`~uproot4.interpretation.library.Library`): The library that is used to represent arrays. Options are ``"np"`` for NumPy, ``"ak"`` for Awkward Array, ``"pd"`` for Pandas, and ``"cp"`` for CuPy. @@ -318,7 +310,7 @@ def concatenate( must be passed as ``how``, not an instance of that type (i.e. ``how=tuple``, not ``how=()``). custom_classes (None or dict): If a dict, override the classes from - the :doc:`uproot4.reading.ReadOnlyFile` or ``uproot4.classes``. + the :py:class:`~uproot4.reading.ReadOnlyFile` or ``uproot4.classes``. allow_missing (bool): If True, skip over any files that do not contain the specified ``TTree``. options: See below. @@ -354,10 +346,10 @@ def concatenate( Options (type; default): - * file_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.file.MemmapSource`) - * xrootd_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.xrootd.XRootDSource`) - * http_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.http.HTTPSource`) - * object_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.object.ObjectSource`) + * file_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.file.MemmapSource`) + * xrootd_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.xrootd.XRootDSource`) + * http_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.http.HTTPSource`) + * object_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.object.ObjectSource`) * timeout (float for HTTP, int for XRootD; 30) * max_num_elements (None or int; None) * num_workers (int; 1) @@ -367,12 +359,12 @@ def concatenate( Other file entry points: - * :doc:`uproot4.reading.open`: opens one file to read any of its objects. - * :doc:`uproot4.behaviors.TBranch.iterate`: iterates through chunks of + * :py:func:`~uproot4.reading.open`: opens one file to read any of its objects. + * :py:func:`~uproot4.behaviors.TBranch.iterate`: iterates through chunks of contiguous entries in ``TTrees``. - * :doc:`uproot4.behaviors.TBranch.concatenate` (this function): returns a + * :py:func:`~uproot4.behaviors.TBranch.concatenate` (this function): returns a single concatenated array from ``TTrees``. - * :doc:`uproot4.behaviors.TBranch.lazy`: returns a lazily read array from + * :py:func:`~uproot4.behaviors.TBranch.lazy`: returns a lazily read array from ``TTrees``. """ files = _regularize_files(files) @@ -435,13 +427,13 @@ def lazy( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. If the function + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. If the function returns False or None, the ``TBranch`` is excluded; if the function returns True, it is included with its standard - :doc:`uproot4.behaviors.TBranch.TBranch.interpretation`; if an - :doc:`uproot4.interpretation.Interpretation`, this interpretation + :py:attr:`~uproot4.behaviors.TBranch.TBranch.interpretation`; if an + :py:class:`~uproot4.interpretation.Interpretation`, this interpretation overrules the standard one. recursive (bool): If True, include all subbranches of branches as separate fields; otherwise, only search one level deep. @@ -458,11 +450,11 @@ def lazy( array_cache (None, MutableMapping, or memory size): Cache of arrays; if None, do not use a cache; if a memory size, create a new cache of this size. - library (str or :doc:`uproot4.interpretation.library.Library`): The library + library (str or :py:class:`~uproot4.interpretation.library.Library`): The library that is used to represent arrays. For lazy arrays, only ``"ak"`` for Awkward Array is allowed. custom_classes (None or dict): If a dict, override the classes from - the :doc:`uproot4.reading.ReadOnlyFile` or ``uproot4.classes``. + the :py:class:`~uproot4.reading.ReadOnlyFile` or ``uproot4.classes``. allow_missing (bool): If True, skip over any files that do not contain the specified ``TTree``. options: See below. @@ -489,7 +481,7 @@ def lazy( If the size of the fields used in a calculation do not fit into ``array_cache``, lazy arrays may be inefficient, repeatedly rereading data that could be read once by iterating through the calculation with - :doc:`uproot4.behavior.TBranch.iterate`. + :py:func:`~uproot4.behavior.TBranch.iterate`. Allowed types for the ``files`` parameter: @@ -510,10 +502,10 @@ def lazy( Options (type; default): - * file_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.file.MemmapSource`) - * xrootd_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.xrootd.XRootDSource`) - * http_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.http.HTTPSource`) - * object_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.object.ObjectSource`) + * file_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.file.MemmapSource`) + * xrootd_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.xrootd.XRootDSource`) + * http_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.http.HTTPSource`) + * object_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.object.ObjectSource`) * timeout (float for HTTP, int for XRootD; 30) * max_num_elements (None or int; None) * num_workers (int; 1) @@ -523,12 +515,12 @@ def lazy( Other file entry points: - * :doc:`uproot4.reading.open`: opens one file to read any of its objects. - * :doc:`uproot4.behaviors.TBranch.iterate`: iterates through chunks of + * :py:func:`~uproot4.reading.open`: opens one file to read any of its objects. + * :py:func:`~uproot4.behaviors.TBranch.iterate`: iterates through chunks of contiguous entries in ``TTrees``. - * :doc:`uproot4.behaviors.TBranch.concatenate`: returns a single + * :py:func:`~uproot4.behaviors.TBranch.concatenate`: returns a single concatenated array from ``TTrees``. - * :doc:`uproot4.behaviors.TBranch.lazy` (this function): returns a lazily + * :py:func:`~uproot4.behaviors.TBranch.lazy` (this function): returns a lazily read array from ``TTrees``. """ import awkward1 @@ -696,29 +688,170 @@ def real_filter_branch(branch): return awkward1.Array(out, cache=array_cache) -Report = collections.namedtuple( - "Report", - [ - "global_entry_start", - "global_entry_stop", - "tree_entry_start", - "tree_entry_stop", - "container", - "tree", - "file", - "file_path", - ], -) +class Report(object): + """ + Args: + source (:py:class:`~uproot4.behaviors.TBranch.HasBranches`): The + object (:py:class:`~uproot4.behaviors.TBranch.TBranch` or + :py:class:`~uproot4.behaviors.TTree.TTree`) that this batch of data + came from. + tree_entry_start (int): First entry in the batch, counting zero at + the start of the current ``TTree`` (current file). + tree_entry_stop (int): First entry *after* the batch (last entry plus + one), counting zero at the start of the ``TTree`` (current file). + global_offset (int): Number of entries between the start of iteration + and the start of this ``TTree``. The + :py:attr:`~uproot4.behaviors.TBranch.Report.global_entry_start` and + :py:attr:`~uproot4.behaviors.TBranch.Report.global_entry_stop` are + equal to :py:attr:`~uproot4.behaviors.TBranch.Report.tree_entry_start` + and :py:attr:`~uproot4.behaviors.TBranch.Report.tree_entry_stop` plus + ``global_offset``. + + Information about the current iteration of + :py:meth:`~uproot4.behaviors.TBranch.HasBranches.iterate` (the method) or + :py:func:`~uproot4.behaviors.TBranch.iterate` (the function). + + Since the :py:meth:`~uproot4.behaviors.TBranch.HasBranches.iterate` method + only iterates over data from one ``TTree``, its ``global_offset`` is always + zero; :py:attr:`~uproot4.behaviors.TBranch.Report.global_entry_start` and + :py:attr:`~uproot4.behaviors.TBranch.Report.global_entry_stop` are equal to + :py:attr:`~uproot4.behaviors.TBranch.Report.tree_entry_start` and + :py:attr:`~uproot4.behaviors.TBranch.Report.tree_entry_stop`, respectively. + + """ + + def __init__(self, source, tree_entry_start, tree_entry_stop, global_offset=0): + self._source = source + self._tree_entry_start = tree_entry_start + self._tree_entry_stop = tree_entry_stop + self._global_offset = global_offset + + def __repr__(self): + if self._global_offset == 0: + return "Report({0}, {1}, {2})".format( + self._source, self._tree_entry_start, self._tree_entry_stop + ) + else: + return "Report({0}, {1}, {2}, global_offset={3})".format( + self._source, + self._tree_entry_start, + self._tree_entry_stop, + self._global_offset, + ) + + @property + def source(self): + """ + The object (:py:class:`~uproot4.behaviors.TBranch.TBranch` or + :py:class:`~uproot4.behaviors.TTree.TTree`) that this batch of data + came from. + """ + return self._source + + @property + def tree(self): + """ + The :py:class:`~uproot4.behaviors.TTree.TTree` that this batch of data + came from. + """ + return self._source.tree + + @property + def file(self): + """ + The :py:class:`~uproot4.reading.ReadOnlyFile` that this batch of data + came from. + """ + return self._source.file + + @property + def file_path(self): + """ + The path/name of the :py:class:`~uproot4.reading.ReadOnlyFile` that + this batch of data came from. + """ + return self._source.file.file_path + + @property + def tree_entry_start(self): + """ + First entry in the batch, counting zero at the start of the current + ``TTree`` (current file). + """ + return self._tree_entry_start + + @property + def tree_entry_stop(self): + """ + First entry *after* the batch (last entry plus one), counting zero at + the start of the ``TTree`` (current file). + """ + return self._tree_entry_stop + + @property + def global_entry_start(self): + """ + First entry in the batch, counting zero at the start of iteration + (potentially over many files). + """ + return self._tree_entry_start + self._global_offset + + @property + def global_entry_stop(self): + """ + First entry *after* the batch (last entry plust one), counting zero at + the start of iteration (potentially over many files). + """ + return self._tree_entry_stop + self._global_offset + + @property + def start(self): + """ + A synonym for + :py:attr:`~uproot4.behaviors.TBranch.Report.global_entry_start`. + """ + return self._tree_entry_start + self._global_offset + + @property + def stop(self): + """ + A synonym for + :py:attr:`~uproot4.behaviors.TBranch.Report.global_entry_stop`. + """ + return self._tree_entry_stop + self._global_offset + + @property + def global_offset(self): + """ + Number of entries between the start of iteration and the start of this + ``TTree``. The + :py:attr:`~uproot4.behaviors.TBranch.Report.global_entry_start` and + :py:attr:`~uproot4.behaviors.TBranch.Report.global_entry_stop` are + equal to :py:attr:`~uproot4.behaviors.TBranch.Report.tree_entry_start` + and :py:attr:`~uproot4.behaviors.TBranch.Report.tree_entry_stop` plus + ``global_offset``. + """ + return self._global_offset + + def to_global(self, global_offset): + """ + Copies the data in this :py:class:`~uproot4.branches.TBranch.Report` to + another with a new + :py:attr:`~uproot4.branches.TBranch.Report.global_offset`. + """ + return Report( + self._source, self._tree_entry_start, self._tree_entry_stop, global_offset + ) class HasBranches(Mapping): """ Abstract class of behaviors for anything that "has branches," namely - :doc:`uproot4.behavior.TTree.TTree` and - :doc:`uproot4.behavior.TBranch.TBranch`, which mostly consist of array-reading + :py:class:`~uproot4.behavior.TTree.TTree` and + :py:class:`~uproot4.behavior.TBranch.TBranch`, which mostly consist of array-reading methods. - A :doc:`uproot4.behavior.TBranch.HasBranches` is a Python ``Mapping``, which + A :py:class:`~uproot4.behavior.TBranch.HasBranches` is a Python ``Mapping``, which uses square bracket syntax to extract subbranches: .. code-block:: python @@ -732,9 +865,9 @@ class HasBranches(Mapping): @property def branches(self): """ - The list of :doc:`uproot4.behavior.TBranch.TBranch` directly under - this :doc:`uproot4.behavior.TTree.TTree` or - :doc:`uproot4.behavior.TBranch.TBranch` (i.e. not recursive). + The list of :py:class:`~uproot4.behavior.TBranch.TBranch` directly under + this :py:class:`~uproot4.behavior.TTree.TTree` or + :py:class:`~uproot4.behavior.TBranch.TBranch` (i.e. not recursive). """ return self.member("fBranches") @@ -756,9 +889,9 @@ def show( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is included if the function returns True, excluded if it returns False. recursive (bool): If True, recursively descend into the branches' branches. @@ -770,7 +903,7 @@ def show( typename_width (int): Number of characters to reserve for the C++ typenames. interpretation_width (int): Number of characters to reserve for the - :doc:`uproot4.interpretation.Interpretation` displays. + :py:class:`~uproot4.interpretation.Interpretation` displays. stream (object with a ``write(str)`` method): Stream to write the output to. @@ -778,7 +911,7 @@ def show( Example: - .. code-block:: raw + .. code-block:: name | typename | interpretation ---------------------+----------------------+----------------------------------- @@ -803,7 +936,8 @@ def show( stream.write(formatter.format("name", "typename", "interpretation")) stream.write( - "-" * name_width + "\n" + + "-" * name_width + "-+-" + "-" * typename_width + "-+-" @@ -864,25 +998,25 @@ def arrays( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. If the function + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. If the function returns False or None, the ``TBranch`` is excluded; if the function returns True, it is included with its standard - :doc:`uproot4.behaviors.TBranch.TBranch.interpretation`; if an - :doc:`uproot4.interpretation.Interpretation`, this interpretation + :py:class:`~uproot4.behaviors.TBranch.TBranch.interpretation`; if an + :py:class:`~uproot4.interpretation.Interpretation`, this interpretation overrules the standard one. aliases (None or dict of str \u2192 str): Mathematical expressions that can be used in ``expressions`` or other aliases (without cycles). Uses the ``language`` engine to evaluate. If None, only the - :doc:`uproot4.behaviors.TBranch.TBranch.aliases` are available. - language (:doc:`uproot4.language.Language`): Language used to interpret + :py:attr:`~uproot4.behaviors.TBranch.TBranch.aliases` are available. + language (:py:class:`~uproot4.language.Language`): Language used to interpret the ``expressions`` and ``aliases``. entry_start (None or int): The first entry to include. If None, start at zero. If negative, count from the end, like a Python slice. entry_stop (None or int): The first entry to exclude (i.e. one greater than the last entry to include). If None, stop at - :doc:`uproot4.behavior.TTree.TTree.num_entries`. If negative, + :py:attr:`~uproot4.behavior.TTree.TTree.num_entries`. If negative, count from the end, like a Python slice. decompression_executor (None or Executor with a ``submit`` method): The executor that is used to decompress ``TBaskets``; if None, the @@ -894,7 +1028,7 @@ def arrays( array_cache (None, MutableMapping, or memory size): Cache of arrays; if None, use the file's cache; if a memory size, create a new cache of this size. - library (str or :doc:`uproot4.interpretation.library.Library`): The library + library (str or :py:class:`~uproot4.interpretation.library.Library`): The library that is used to represent arrays. Options are ``"np"`` for NumPy, ``"ak"`` for Awkward Array, ``"pd"`` for Pandas, and ``"cp"`` for CuPy. @@ -915,10 +1049,10 @@ def arrays( >>> my_tree["y"].array() - See also :doc:`uproot4.behavior.TBranch.TBranch.array` to read a single + See also :py:meth:`~uproot4.behavior.TBranch.TBranch.array` to read a single ``TBranch`` as an array. - See also :doc:`uproot4.behavior.TBranch.HasBranches.iterate` to iterate over + See also :py:meth:`~uproot4.behavior.TBranch.HasBranches.iterate` to iterate over the array in contiguous ranges of entries. """ keys = set(self.keys(recursive=True, full_paths=False)) @@ -1060,25 +1194,25 @@ def iterate( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. If the function + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. If the function returns False or None, the ``TBranch`` is excluded; if the function returns True, it is included with its standard - :doc:`uproot4.behaviors.TBranch.TBranch.interpretation`; if an - :doc:`uproot4.interpretation.Interpretation`, this interpretation + :py:attr:`~uproot4.behaviors.TBranch.TBranch.interpretation`; if an + :py:class:`~uproot4.interpretation.Interpretation`, this interpretation overrules the standard one. aliases (None or dict of str \u2192 str): Mathematical expressions that can be used in ``expressions`` or other aliases (without cycles). Uses the ``language`` engine to evaluate. If None, only the - :doc:`uproot4.behaviors.TBranch.TBranch.aliases` are available. - language (:doc:`uproot4.language.Language`): Language used to interpret + :py:attr:`~uproot4.behaviors.TBranch.TBranch.aliases` are available. + language (:py:class:`~uproot4.language.Language`): Language used to interpret the ``expressions`` and ``aliases``. entry_start (None or int): The first entry to include. If None, start at zero. If negative, count from the end, like a Python slice. entry_stop (None or int): The first entry to exclude (i.e. one greater than the last entry to include). If None, stop at - :doc:`uproot4.behavior.TTree.TTree.num_entries`. If negative, + :py:attr:`~uproot4.behavior.TTree.TTree.num_entries`. If negative, count from the end, like a Python slice. step_size (int or str): If an integer, the maximum number of entries to include in each iteration step; if a string, the maximum memory size @@ -1091,7 +1225,7 @@ def iterate( executor that is used to interpret uncompressed ``TBasket`` data as arrays; if None, the global ``uproot4.interpretation_executor`` is used. - library (str or :doc:`uproot4.interpretation.library.Library`): The library + library (str or :py:class:`~uproot4.interpretation.library.Library`): The library that is used to represent arrays. Options are ``"np"`` for NumPy, ``"ak"`` for Awkward Array, ``"pd"`` for Pandas, and ``"cp"`` for CuPy. @@ -1101,7 +1235,7 @@ def iterate( must be passed as ``how``, not an instance of that type (i.e. ``how=tuple``, not ``how=()``). report (bool): If True, this generator yields - (:doc:`uproot4.behaviors.TBranch.Report, arrays) pairs; if False, + (arrays, :py:class:`~uproot4.behaviors.TBranch.Report`) pairs; if False, it only yields arrays. The report has data about the ``TFile``, ``TTree``, and global and local entry ranges. @@ -1115,10 +1249,10 @@ def iterate( ... # each of the following have 100 entries ... array["x"], array["y"] - See also :doc:`uproot4.behavior.TBranch.HasBranches.arrays` to read + See also :py:meth:`~uproot4.behavior.TBranch.HasBranches.arrays` to read everything in a single step, without iteration. - See also :doc:`uproot4.behavior.TBranch.iterate` to iterate over many + See also :py:func:`~uproot4.behavior.TBranch.iterate` to iterate over many files. """ keys = set(self.keys(recursive=True, full_paths=False)) @@ -1174,9 +1308,6 @@ def iterate( self, step_size, entry_start, entry_stop, branchid_interpretation ) - if report: - tree = self.tree - previous_baskets = {} for sub_entry_start in uproot4._util.range( entry_start, entry_stop, entry_step @@ -1238,16 +1369,7 @@ def iterate( arrays = library.group(output, expression_context, how) if report: - yield arrays, Report( - sub_entry_start, - sub_entry_stop, - sub_entry_start, - sub_entry_stop, - self, - tree, - self.file, - self.file.file_path, - ) + yield arrays, Report(self, sub_entry_start, sub_entry_stop) else: yield arrays @@ -1268,9 +1390,9 @@ def keys( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is included if the function returns True, excluded if it returns False. recursive (bool): If True, descend into any nested subbranches. If False, only return the names of branches directly accessible @@ -1304,19 +1426,19 @@ def values( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is included if the function returns True, excluded if it returns False. recursive (bool): If True, descend into any nested subbranches. If False, only return branches that are directly accessible under this object. Returns the subbranches as a list of - :doc:`uproot4.behavior.TBranch.TBranch`. + :py:class:`~uproot4.behavior.TBranch.TBranch`. (Note: with ``recursive=False``, this is the same as - :doc:`uproot4.behavior.TBranch.HasBranches.branches`.) + :py:attr:`~uproot4.behavior.TBranch.HasBranches.branches`.) """ return list( self.itervalues( @@ -1341,9 +1463,9 @@ def items( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is included if the function returns True, excluded if it returns False. recursive (bool): If True, descend into any nested subbranches. If False, only return (name, branch) pairs for branches @@ -1353,7 +1475,7 @@ def items( name as the name without modification. Returns (name, branch) pairs of the subbranches as a list of 2-tuples - of (str, :doc:`uproot4.behavior.TBranch.TBranch`). + of (str, :py:class:`~uproot4.behavior.TBranch.TBranch`). """ return list( self.iteritems( @@ -1379,9 +1501,9 @@ def typenames( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is included if the function returns True, excluded if it returns False. recursive (bool): If True, descend into any nested subbranches. If False, only return (name, typename) pairs for branches @@ -1417,9 +1539,9 @@ def iterkeys( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is included if the function returns True, excluded if it returns False. recursive (bool): If True, descend into any nested subbranches. If False, only return the names of branches directly accessible @@ -1452,19 +1574,19 @@ def itervalues( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is included if the function returns True, excluded if it returns False. recursive (bool): If True, descend into any nested subbranches. If False, only return branches that are directly accessible under this object. Returns the subbranches as an iterator over - :doc:`uproot4.behavior.TBranch.TBranch`. + :py:class:`~uproot4.behavior.TBranch.TBranch`. (Note: with ``recursive=False``, this is the same as - :doc:`uproot4.behavior.TBranch.HasBranches.branches`.) + :py:attr:`~uproot4.behavior.TBranch.HasBranches.branches`.) """ for k, v in self.iteritems( filter_name=filter_name, @@ -1489,9 +1611,9 @@ def iteritems( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is included if the function returns True, excluded if it returns False. recursive (bool): If True, descend into any nested subbranches. If False, only return (name, branch) pairs for branches @@ -1501,7 +1623,7 @@ def iteritems( name as the name without modification. Returns (name, branch) pairs of the subbranches as an iterator over - 2-tuples of (str, :doc:`uproot4.behavior.TBranch.TBranch`). + 2-tuples of (str, :py:class:`~uproot4.behavior.TBranch.TBranch`). """ filter_name = uproot4._util.regularize_filter(filter_name) filter_typename = uproot4._util.regularize_filter(filter_typename) @@ -1552,9 +1674,9 @@ def itertypenames( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is included if the function returns True, excluded if it returns False. recursive (bool): If True, descend into any nested subbranches. If False, only return (name, typename) pairs for branches @@ -1609,21 +1731,21 @@ def num_entries_for( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is included if the function returns True, excluded if it returns False. aliases (None or dict of str \u2192 str): Mathematical expressions that can be used in ``expressions`` or other aliases (without cycles). Uses the ``language`` engine to evaluate. If None, only the - :doc:`uproot4.behaviors.TBranch.TBranch.aliases` are available. - language (:doc:`uproot4.language.Language`): Language used to interpret + :py:attr:`~uproot4.behaviors.TBranch.TBranch.aliases` are available. + language (:py:class:`~uproot4.language.Language`): Language used to interpret the ``expressions`` and ``aliases``. entry_start (None or int): The first entry to include. If None, start at zero. If negative, count from the end, like a Python slice. entry_stop (None or int): The first entry to exclude (i.e. one greater than the last entry to include). If None, stop at - :doc:`uproot4.behavior.TTree.TTree.num_entries`. If negative, + :py:attr:`~uproot4.behavior.TTree.TTree.num_entries`. If negative, count from the end, like a Python slice. Returns an *approximate* step size as a number of entries to read @@ -1640,7 +1762,7 @@ def num_entries_for( in memory, without considering ``cuts``). This is the algorithm that - :doc:`uproot4.behavior.TBranch.HasBranches.iterate` uses to convert a + :py:meth:`~uproot4.behavior.TBranch.HasBranches.iterate` uses to convert a ``step_size`` expressed in memory units into a number of entries. """ target_num_bytes = uproot4._util.memory_size(memory_size) @@ -1681,9 +1803,9 @@ def common_entry_offsets( filter to select ``TBranches`` by name. filter_typename (None, glob string, regex string in ``"/pattern/i"`` syntax, function of str \u2192 bool, or iterable of the above): A filter to select ``TBranches`` by type. - filter_branch (None or function of :doc:`uproot4.behaviors.TBranch.TBranch` \u2192 bool, :doc:`uproot4.interpretation.Interpretation`, or None): A + filter_branch (None or function of :py:class:`~uproot4.behaviors.TBranch.TBranch` \u2192 bool, :py:class:`~uproot4.interpretation.Interpretation`, or None): A filter to select ``TBranches`` using the full - :doc:`uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is + :py:class:`~uproot4.behaviors.TBranch.TBranch` object. The ``TBranch`` is included if the function returns True, excluded if it returns False. recursive (bool): If True, descend into any nested subbranches. If False, only consider branches directly accessible under this @@ -1692,9 +1814,9 @@ def common_entry_offsets( Returns entry offsets in which ``TBasket`` boundaries align in the specified set of branches. - If this :doc:`uproot4.behaviors.TBranch.TBranch` has no subbranches, + If this :py:class:`~uproot4.behaviors.TBranch.TBranch` has no subbranches, the output is identical to - :doc:`uproot4.behaviors.TBranch.TBranch.entry_offsets`. + :py:attr:`~uproot4.behaviors.TBranch.TBranch.entry_offsets`. """ common_offsets = None for branch in self.itervalues( @@ -1787,8 +1909,8 @@ class TBranch(HasBranches): """ Behaviors for a ``TBranch``, which mostly consist of array-reading methods. - Since a :doc:`uproot4.behavior.TBranch.TBranch` is a - :doc:`uproot4.behavior.TBranch.HasBranches`, it is also a Python + Since a :py:class:`~uproot4.behavior.TBranch.TBranch` is a + :py:class:`~uproot4.behavior.TBranch.HasBranches`, it is also a Python ``Mapping``, which uses square bracket syntax to extract subbranches: .. code-block:: python @@ -1820,16 +1942,16 @@ def array( ): u""" Args: - interpretation (None or :doc:`uproot4.interpretation.Interpretation`): An + interpretation (None or :py:class:`~uproot4.interpretation.Interpretation`): An interpretation of the ``TBranch`` data as an array. If None, the - standard :doc:`uproot4.behavior.TBranch.TBranch.interpretation` + standard :py:attr:`~uproot4.behavior.TBranch.TBranch.interpretation` is used, which is derived from - :doc:`uproot4.interpretation.identify.interpretation_of`. + :py:func:`~uproot4.interpretation.identify.interpretation_of`. entry_start (None or int): The first entry to include. If None, start at zero. If negative, count from the end, like a Python slice. entry_stop (None or int): The first entry to exclude (i.e. one greater than the last entry to include). If None, stop at - :doc:`uproot4.behavior.TTree.TTree.num_entries`. If negative, + :py:attr:`~uproot4.behavior.TTree.TTree.num_entries`. If negative, count from the end, like a Python slice. decompression_executor (None or Executor with a ``submit`` method): The executor that is used to decompress ``TBaskets``; if None, the @@ -1841,7 +1963,7 @@ def array( array_cache (None, MutableMapping, or memory size): Cache of arrays; if None, use the file's cache; if a memory size, create a new cache of this size. - library (str or :doc:`uproot4.interpretation.library.Library`): The library + library (str or :py:class:`~uproot4.interpretation.library.Library`): The library that is used to represent arrays. Options are ``"np"`` for NumPy, ``"ak"`` for Awkward Array, ``"pd"`` for Pandas, and ``"cp"`` for CuPy. @@ -1861,7 +1983,7 @@ def array( >>> array["y"] - See also :doc:`uproot4.behavior.TBranch.HasBranches.arrays` to read + See also :py:meth:`~uproot4.behavior.TBranch.HasBranches.arrays` to read multiple ``TBranches`` into a group of arrays or an array-group. """ if interpretation is None: @@ -1929,7 +2051,7 @@ def name(self): Note that ``TBranch`` names are not guaranteed to be unique; it is sometimes necessary to address a branch by its - :doc:`uproot4.behavior.TBranch.TBranch.index`. + :py:attr:`~uproot4.behavior.TBranch.TBranch.index`. """ return self.member("fName") @@ -1973,7 +2095,7 @@ def index(self): Integer position of this ``TBranch`` in its parent's list of branches. Useful for cases in which the - :doc:`uproot4.behavior.TBranch.TBranch.name` is not unique: the + :py:attr:`~uproot4.behavior.TBranch.TBranch.name` is not unique: the non-recursive index is always unique. """ for i, branch in enumerate(self.parent.branches): @@ -1985,18 +2107,18 @@ def index(self): @property def interpretation(self): """ - The standard :doc:`uproot4.interpretation.Interpretation` of this + The standard :py:class:`~uproot4.interpretation.Interpretation` of this ``TBranch`` as an array, derived from - :doc:`uproot4.interpretation.identify.interpretation_of`. + :py:func:`~uproot4.interpretation.identify.interpretation_of`. If no interpretation could be found, the value of this property - would be a :doc:`uproot4.interpretation.identify.UnknownInterpretation`, + would be a :py:exc:`~uproot4.interpretation.identify.UnknownInterpretation`, which is a Python ``Exception``. Since the exception is *returned*, rather than *raised*, a branch lacking an interpretation is not a fatal error. However, any attempt to use this exception object as an - :doc:`uproot4.interpretation.Interpretation` causes it to raise itself: + :py:class:`~uproot4.interpretation.Interpretation` causes it to raise itself: attempting to read a branch lacking an interpretation is a fatal error. """ if self._interpretation is None: @@ -2012,9 +2134,9 @@ def interpretation(self): def typename(self): """ The C++ typename of the ``TBranch``, derived from its - :doc:`uproot4.behavior.TBranch.TBranch.interpretation`. If the + :py:attr:`~uproot4.behavior.TBranch.TBranch.interpretation`. If the interpretation is - :doc:`uproot4.interpretation.identify.UnknownInterpretation`, the + :py:exc:`~uproot4.interpretation.identify.UnknownInterpretation`, the typename is ``"unknown"``. """ if self.interpretation is None: @@ -2028,12 +2150,12 @@ def num_entries(self): The number of entries in the ``TBranch``, as reported by ``fEntries``. In principle, this could disagree with the - :doc:`uproot4.behaviors.TTree.TTree.num_entries`, which is from the + :py:attr:`~uproot4.behaviors.TTree.TTree.num_entries`, which is from the ``TTree``'s ``fEntries``. The ``TBranch`` also has a ``fEntryNumber``, which ought to be equal to the ``TBranch`` and ``TTree``'s ``fEntries``, and the last value of - :doc:`uproot4.behaviors.TBranch.TBranch.entry_offsets` ought to be + :py:attr:`~uproot4.behaviors.TBranch.TBranch.entry_offsets` ought to be equal to the number of entries as well. """ return int(self.member("fEntries")) # or fEntryNumber? @@ -2047,7 +2169,7 @@ def entry_offsets(self): The number of ``entry_offsets`` in this list of integers is one more than the number of ``TBaskets``. The first is ``0`` and the last is the number of entries - (:doc:`uproot4.behaviors.TBranch.TBranch.num_entries`). + (:py:attr:`~uproot4.behaviors.TBranch.TBranch.num_entries`). """ if self._num_normal_baskets == 0: out = [0] @@ -2086,7 +2208,7 @@ def tree(self): @property def top_level(self): """ - True if the immediate :doc:`uproot4.behaviors.TBranch.TBranch.parent` + True if the immediate :py:attr:`~uproot4.behaviors.TBranch.TBranch.parent` is the ``TTree``; False otherwise. """ return isinstance(self.parent, uproot4.behaviors.TTree.TTree) @@ -2097,7 +2219,7 @@ def streamer(self): The ``TStreamerInfo`` or ``TStreamerElement`` for this ``TBranch``, which may be None. - If the :doc:`uproot4.reading.ReadOnlyFile.streamers` have not yet been + If the :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` have not yet been read, this method *might* cause them to be read. (Only ``TBranchElements`` can have streamers.) """ @@ -2166,12 +2288,12 @@ def context(self): @property def aliases(self): """ - The :doc:`uproot4.behaviors.TTree.TTree.aliases`, which are used as the + The :py:attr:`~uproot4.behaviors.TTree.TTree.aliases`, which are used as the ``aliases`` argument to - :doc:`uproot4.behaviors.TBranch.HasBranches.arrays`, - :doc:`uproot4.behaviors.TBranch.HasBranches.iterate`, - :doc:`uproot4.behaviors.TBranch.iterate`, and - :doc:`uproot4.behaviors.TBranch.concatenate` if one is not given. + :py:meth:`~uproot4.behaviors.TBranch.HasBranches.arrays`, + :py:meth:`~uproot4.behaviors.TBranch.HasBranches.iterate`, + :py:func:`~uproot4.behaviors.TBranch.iterate`, and + :py:func:`~uproot4.behaviors.TBranch.concatenate` if one is not given. The return type is always a dict of str \u2192 str, even if there are no aliases (an empty dict). @@ -2201,21 +2323,55 @@ def count_leaf(self): return None return leaves[0].member("fLeafCount") + @property + def compressed_bytes(self): + """ + The number of compressed bytes in all ``TBaskets`` of this ``TBranch``. + + The number of compressed bytes is specified in the ``TBranch`` metadata + and can be determined without reading any additional data. The + uncompressed bytes requires reading all of the ``TBasket`` ``TKeys`` at + least. + """ + return sum(self.basket_compressed_bytes(i) for i in range(self.num_baskets)) + + @property + def uncompressed_bytes(self): + """ + The number of uncompressed bytes in all ``TBaskets`` of this ``TBranch``. + + The number of uncompressed bytes cannot be determined without reading a + ``TKey``, which are small, but may be slow for remote connections because + of the latency of round-trip requests. + """ + return sum(self.basket_uncompressed_bytes(i) for i in range(self.num_baskets)) + + @property + def compression_ratio(self): + """ + The number of uncompressed bytes divided by the number of compressed + bytes for this ``TBranch``. + + See :py:attr:`~uproot4.behaviors.TBranch.TBranch.compressed_bytes` and + :py:attr:`~uproot4.behaviors.TBranch.TBranch.uncompressed_bytes`. + """ + return float(self.uncompressed_bytes) / float(self.compressed_bytes) + @property def num_baskets(self): """ The number of ``TBaskets`` in this ``TBranch``, including both normal (free) ``TBaskets`` and - :doc:`uproot4.behaviors.TBranch.TBranch.embedded_baskets`. + :py:attr:`~uproot4.behaviors.TBranch.TBranch.embedded_baskets`. """ return self._num_normal_baskets + len(self.embedded_baskets) def basket(self, basket_num): """ - The :doc:`uproot4.models.TBasket.Model_TBasket` at index ``basket_num``. + The :py:class:`~uproot4.models.TBasket.Model_TBasket` at index ``basket_num``. It may be a normal (free) ``TBasket`` or one of the - :doc:`uproot4.behaviors.TBranch.TBranch.embedded_baskets`. + :py:attr:`~uproot4.behaviors.TBranch.TBranch.embedded_baskets`. """ if 0 <= basket_num < self._num_normal_baskets: chunk, cursor = self.basket_chunk_cursor(basket_num) @@ -2234,8 +2390,8 @@ def basket(self, basket_num): def basket_chunk_cursor(self, basket_num): """ - Returns a :doc:`uproot4.source.chunk.Chunk` and - :doc:`uproot4.source.cursor.Cursor` as a 2-tuple for a given + Returns a :py:class:`~uproot4.source.chunk.Chunk` and + :py:class:`~uproot4.source.cursor.Cursor` as a 2-tuple for a given ``basket_num``. """ if 0 <= basket_num < self._num_normal_baskets: @@ -2301,11 +2457,11 @@ def basket_uncompressed_bytes(self, basket_num): def basket_key(self, basket_num): """ - The ``TKey`` (:doc:`uproot4.reading.ReadOnlyKey`) for the ``TBasket`` + The ``TKey`` (:py:class:`~uproot4.reading.ReadOnlyKey`) for the ``TBasket`` at ``basket_num``. Only applies to normal (free) ``TBaskets``, not - :doc:`uproot4.behaviors.TBranch.TBranch.embedded_baskets`. + :py:attr:`~uproot4.behaviors.TBranch.TBranch.embedded_baskets`. """ if 0 <= basket_num < self._num_normal_baskets: start = self.member("fBasketSeek")[basket_num] @@ -2355,12 +2511,12 @@ def embedded_baskets(self): def entries_to_ranges_or_baskets(self, entry_start, entry_stop): """ Returns a list of (start, stop) integer pairs for free (normal) - ``TBaskets`` and :doc:`uproot4.models.TBasket.Model_TBasket` objects + ``TBaskets`` and :py:class:`~uproot4.models.TBasket.Model_TBasket` objects for embedded ``TBaskets``. The intention is for this list to be updated in place, replacing (start, stop) integer pairs with - :doc:`uproot4.models.TBasket.Model_TBasket` objects as they get + :py:class:`~uproot4.models.TBasket.Model_TBasket` objects as they get read and interpreted. """ entry_offsets = self.entry_offsets @@ -2461,7 +2617,7 @@ def debug( Example output with ``dtype=">f4"`` and ``offset=3``. - .. code-block:: raw + .. code-block:: --+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+- 123 123 123 63 140 204 205 64 12 204 205 64 83 51 51 64 140 204 205 64 @@ -2499,7 +2655,7 @@ def debug_array(self, entry, skip_bytes=0, dtype=numpy.dtype("u1")): which to interpret the data. (The size of the array returned is truncated to this ``dtype.itemsize``.) - Like :doc:`uproot4.behaviors.TBranch.TBranch.debug`, but returns a + Like :py:meth:`~uproot4.behaviors.TBranch.TBranch.debug`, but returns a NumPy array for further inspection. """ dtype = numpy.dtype(dtype) diff --git a/uproot4/behaviors/TBranchElement.py b/uproot4/behaviors/TBranchElement.py index 235c78dda..b2318b45f 100644 --- a/uproot4/behaviors/TBranchElement.py +++ b/uproot4/behaviors/TBranchElement.py @@ -2,7 +2,7 @@ """ Defines the behaviors of ``TBranchElement``, which is entirely inherited from -functions in :doc:`uproot4.behaviors.TBranch.TBranch`. +functions in :py:class:`~uproot4.behaviors.TBranch.TBranch`. """ from __future__ import absolute_import @@ -15,8 +15,8 @@ class TBranchElement(uproot4.behaviors.TBranch.TBranch): Behaviors for a ``TBranchElement``, which mostly consist of array-reading methods. - Since a :doc:`uproot4.behavior.TBranchElement.TBranchElement` is a - :doc:`uproot4.behavior.TBranch.HasBranches`, it is also a Python + Since a :py:class:`~uproot4.behavior.TBranchElement.TBranchElement` is a + :py:class:`~uproot4.behavior.TBranch.HasBranches`, it is also a Python ``Mapping``, which uses square bracket syntax to extract subbranches: .. code-block:: python diff --git a/uproot4/behaviors/TH1.py b/uproot4/behaviors/TH1.py index 37a5b0c5d..8987871bd 100644 --- a/uproot4/behaviors/TH1.py +++ b/uproot4/behaviors/TH1.py @@ -102,7 +102,7 @@ def values(self): def values_errors(self): """ - The :doc:`uproot4.behaviors.TH1.Histogram.values` and their associated + The :py:meth:`~uproot4.behaviors.TH1.Histogram.values` and their associated errors (uncertainties) as a 2-tuple of arrays. The two arrays have the same ``shape``. diff --git a/uproot4/behaviors/TProfile.py b/uproot4/behaviors/TProfile.py index df6742d85..a28122d03 100644 --- a/uproot4/behaviors/TProfile.py +++ b/uproot4/behaviors/TProfile.py @@ -26,13 +26,13 @@ class Profile(uproot4.behaviors.TH1.Histogram): def effective_entries(self): """ The effective number of entries, which is a step in the calculation of - :doc:`uproot4.behaviors.TProfile.Profile.values`. + :py:meth:`~uproot4.behaviors.TProfile.Profile.values`. """ pass def values_errors(self, error_mode=""): """ - The :doc:`uproot4.behaviors.TH1.Histogram.values` and their associated + The :py:meth:`~uproot4.behaviors.TH1.Histogram.values` and their associated errors (uncertainties) as a 2-tuple of arrays. The two arrays have the same ``shape``. diff --git a/uproot4/behaviors/TTree.py b/uproot4/behaviors/TTree.py index 93181d20e..1e7b39394 100644 --- a/uproot4/behaviors/TTree.py +++ b/uproot4/behaviors/TTree.py @@ -2,7 +2,7 @@ """ Defines the behaviors of ``TTree``, which is almost entirely inherited from -functions in :doc:`uproot4.behaviors.TBranch`. +functions in :py:mod:`uproot4.behaviors.TBranch`. """ from __future__ import absolute_import @@ -14,8 +14,8 @@ class TTree(uproot4.behaviors.TBranch.HasBranches): """ Behaviors for a ``TTree``, which mostly consist of array-reading methods. - Since a :doc:`uproot4.behavior.TTree.TTree` is a - :doc:`uproot4.behavior.TBranch.HasBranches`, it is also a Python + Since a :py:class:`~uproot4.behavior.TTree.TTree` is a + :py:class:`~uproot4.behavior.TBranch.HasBranches`, it is also a Python ``Mapping``, which uses square bracket syntax to extract subbranches: .. code-block:: python @@ -71,7 +71,7 @@ def num_entries(self): The number of entries in the ``TTree``, as reported by ``fEntries``. In principle, this could disagree with the - :doc:`uproot4.behaviors.TBranch.TBranch.num_entries`, which is from the + :py:attr:`~uproot4.behaviors.TBranch.TBranch.num_entries`, which is from the ``TBranch``'s ``fEntries``. See that method's documentation for yet more ways the number of entries could, in principle, be inconsistent. """ @@ -88,10 +88,10 @@ def tree(self): def aliases(self): u""" The ``TTree``'s ``fAliases``, which are used as the ``aliases`` - argument to :doc:`uproot4.behaviors.TBranch.HasBranches.arrays`, - :doc:`uproot4.behaviors.TBranch.HasBranches.iterate`, - :doc:`uproot4.behaviors.TBranch.iterate`, and - :doc:`uproot4.behaviors.TBranch.concatenate` if one is not given. + argument to :py:meth:`~uproot4.behaviors.TBranch.HasBranches.arrays`, + :py:meth:`~uproot4.behaviors.TBranch.HasBranches.iterate`, + :py:func:`~uproot4.behaviors.TBranch.iterate`, and + :py:func:`~uproot4.behaviors.TBranch.concatenate` if one is not given. The return type is always a dict of str \u2192 str, even if there are no aliases (an empty dict). @@ -107,19 +107,19 @@ def aliases(self): @property def chunk(self): """ - The :doc:`uproot4.source.chunk.Chunk` from which this ``TTree`` was + The :py:class:`~uproot4.source.chunk.Chunk` from which this ``TTree`` was read (as a strong, not weak, reference). The reason the chunk is retained is to read - :doc:`uproot4.behaviors.TBranch.TBranch.embedded_baskets` only if + :py:attr:`~uproot4.behaviors.TBranch.TBranch.embedded_baskets` only if necessary (if the file was opened with ``options["minimal_ttree_metadata"]=True``, the reading of these ``TBaskets`` is deferred until they are accessed). Holding a strong reference to a chunk holds a strong reference to - its :doc:`uproot4.source.chunk.Source`, preventing open file handles + its :py:class:`~uproot4.source.chunk.Source`, preventing open file handles from going out of scope, but so does the - :doc:`uproot4.reading.ReadOnlyFile` that ``TTree`` needs to read data + :py:class:`~uproot4.reading.ReadOnlyFile` that ``TTree`` needs to read data on demand. """ return self._chunk diff --git a/uproot4/behaviors/__init__.py b/uproot4/behaviors/__init__.py index c73ec905a..dfac8ae44 100644 --- a/uproot4/behaviors/__init__.py +++ b/uproot4/behaviors/__init__.py @@ -10,7 +10,7 @@ To add a behavior for a ROOT class: 1. Translate the ROOT class name from C++ to Python with - :doc:`uproot4.model.classname_encode`. For example, + :py:func:`~uproot4.model.classname_encode`. For example, ``"ROOT::RThing"`` becomes ``"Model_ROOT_3a3a_RThing"``. 2. Create a submodule of ``uproot4.behaviors`` without the ``"Model_"`` prefix. For example, ``"ROOT_3a3a_RThing"``. @@ -22,7 +22,7 @@ appropriate name exist, the new class will inherit from the behavior, giving the newly created object specialized methods and properties. -See also :doc:`uproot4.models`. +See also :py:mod:`uproot4.models`. """ from __future__ import absolute_import diff --git a/uproot4/cache.py b/uproot4/cache.py index b5f443646..93c570664 100644 --- a/uproot4/cache.py +++ b/uproot4/cache.py @@ -3,11 +3,11 @@ """ Simple, thread-safe cache classes satisfying the ``MutableMapping`` protocol. -The :doc:`uproot4.cache.LRUCache` implements a least-recently used eviction +The :py:class:`~uproot4.cache.LRUCache` implements a least-recently used eviction policy that limits the number of items in the cache (used as an ``object_cache``). -The :doc:`uproot4.cache.LRUArrayCache` implements the same policy, limiting the +The :py:class:`~uproot4.cache.LRUArrayCache` implements the same policy, limiting the total number of bytes, as reported by ``nbytes``. """ diff --git a/uproot4/compression.py b/uproot4/compression.py index 5dfc6785b..3f53ecd73 100644 --- a/uproot4/compression.py +++ b/uproot4/compression.py @@ -2,7 +2,7 @@ """ Defines an interface to compression algorithms used by ROOT, as well as functions -for compressing and decompressing a :doc:`uproot4.source.chunk.Chunk`. +for compressing and decompressing a :py:class:`~uproot4.source.chunk.Chunk`. """ from __future__ import absolute_import @@ -31,7 +31,7 @@ def __repr__(self): @classmethod def from_code(cls, code): """ - Constructs a :doc:`uproot4.compression.Compression` from a raw + Constructs a :py:class:`~uproot4.compression.Compression` from a raw ``fCompress`` integer. """ return cls.from_code_pair(code // 100, code % 100) @@ -39,7 +39,7 @@ def from_code(cls, code): @classmethod def from_code_pair(cls, algorithm, level): """ - Constructs a :doc:`uproot4.compression.Compression` from a pair of + Constructs a :py:class:`~uproot4.compression.Compression` from a pair of integers representing ``algorithm`` and ``level``. """ if algorithm == 0 or level == 0: @@ -54,7 +54,7 @@ def from_code_pair(cls, algorithm, level): @property def code(self): """ - This :doc:`uproot4.compression.Compression` as a raw ``fCompress`` + This :py:class:`~uproot4.compression.Compression` as a raw ``fCompress`` integer. """ algorithm, level = self.code_pair @@ -63,7 +63,7 @@ def code(self): @property def code_pair(self): """ - This :doc:`uproot4.compression.Compression` as a 2-tuple of integers + This :py:class:`~uproot4.compression.Compression` as a 2-tuple of integers representing algorithm and level. """ for const, cls in algorithm_codes.items(): @@ -180,21 +180,21 @@ def decompress(cls, data, uncompressed_bytes=None): def decompress(chunk, cursor, context, compressed_bytes, uncompressed_bytes): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. - cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. + cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in that ``chunk``. context (dict): Auxiliary data used in deserialization. compressed_bytes (int): Number of compressed bytes to decompress. uncompressed_bytes (int): Number of uncompressed bytes to expect after decompression. - Decompresses ``compressed_bytes`` of a :doc:`uproot4.source.chunk.Chunk` + Decompresses ``compressed_bytes`` of a :py:class:`~uproot4.source.chunk.Chunk` of data, starting at the ``cursor``. This function parses ROOT's 9-byte compression headers (17 bytes for LZ4 because it includes a checksum), combining blocks if there are more than - one, returning the result as a new :doc:`uproot4.source.chunk.Chunk`. + one, returning the result as a new :py:class:`~uproot4.source.chunk.Chunk`. """ assert compressed_bytes >= 0 assert uncompressed_bytes >= 0 diff --git a/uproot4/containers.py b/uproot4/containers.py index fdb4720f2..25458ac8b 100644 --- a/uproot4/containers.py +++ b/uproot4/containers.py @@ -4,7 +4,7 @@ Interpretations and models for standard containers, such as ``std::vector`` and simple arrays. -See :doc:`uproot4.interpretation` and :doc:`uproot4.model`. +See :py:mod:`uproot4.interpretation` and :py:mod:`uproot4.model`. """ from __future__ import absolute_import @@ -132,13 +132,13 @@ class AsContainer(object): Abstract class for all descriptions of data as containers, such as ``std::vector``. - Note that these are not :doc:`uproot4.interpretation.Interpretation` + Note that these are not :py:class:`~uproot4.interpretation.Interpretation` objects, since they are recursively nestable and have a ``read`` - instance method like :doc:`uproot4.model.Model`'s ``read`` classmethod. + instance method like :py:class:`~uproot4.model.Model`'s ``read`` classmethod. - A nested tree of :doc:`uproot4.containers.AsContainer` instances and - :doc:`uproot4.model.Model` class objects may be the ``model`` argument - of a :doc:`uproot4.interpretation.objects.AsObjects`. + A nested tree of :py:class:`~uproot4.containers.AsContainer` instances and + :py:class:`~uproot4.model.Model` class objects may be the ``model`` argument + of a :py:class:`~uproot4.interpretation.objects.AsObjects`. """ @property @@ -162,7 +162,7 @@ def typename(self): def awkward_form(self, file, index_format="i64", header=False, tobject_header=True): """ Args: - file (:doc:`uproot4.reading.CommonFileMethods`): The file associated + file (:py:class:`~uproot4.reading.CommonFileMethods`): The file associated with this interpretation's ``TBranch``. index_format (str): Format to use for indexes of the ``awkward1.forms.Form``; may be ``"i32"``, ``"u32"``, or @@ -182,17 +182,17 @@ def strided_interpretation( ): """ Args: - file (:doc:`uproot4.reading.ReadOnlyFile`): File to use to generate - :doc:`uproot4.model.Model` classes from its - :doc:`uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` + file (:py:class:`~uproot4.reading.ReadOnlyFile`): File to use to generate + :py:class:`~uproot4.model.Model` classes from its + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` for error messages. header (bool): If True, assume the outermost object has a header. tobject_header (bool): If True, assume that ``TObjects`` have headers. - original (None, :doc:`uproot4.model.Model`, or :doc:`uproot4.containers.Container`): The + original (None, :py:class:`~uproot4.model.Model`, or :py:class:`~uproot4.containers.Container`): The original, non-strided model or container. Returns a list of (str, ``numpy.dtype``) pairs to build a - :doc:`uproot4.interpretation.objects.AsStridedObjects` interpretation. + :py:class:`~uproot4.interpretation.objects.AsStridedObjects` interpretation. """ raise uproot4.interpretation.objects.CannotBeStrided(self.typename) @@ -215,20 +215,20 @@ def header(self, value): def read(self, chunk, cursor, context, file, selffile, parent, header=True): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. - cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. + cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in that ``chunk``. context (dict): Auxiliary data used in deserialization. - file (:doc:`uproot4.reading.ReadOnlyFile`): An open file object, - capable of generating new :doc:`uproot4.model.Model` classes - from its :doc:`uproot4.reading.ReadOnlyFile.streamers`. - selffile (:doc:`uproot4.reading.CommonFileMethods`): A possibly - :doc:`uproot4.reading.DetachedFile` associated with this object. + file (:py:class:`~uproot4.reading.ReadOnlyFile`): An open file object, + capable of generating new :py:class:`~uproot4.model.Model` classes + from its :py:class:`~uproot4.reading.ReadOnlyFile.streamers`. + selffile (:py:class:`~uproot4.reading.CommonFileMethods`): A possibly + :py:class:`~uproot4.reading.DetachedFile` associated with this object. parent (None or calling object): The previous ``read`` in the recursive descent. header (bool): If True, enable the container's - :doc:`uproot4.containers.AsContainer.header`. + :py:attr:`~uproot4.containers.AsContainer.header`. Read one object as part of a recursive descent. """ @@ -244,12 +244,12 @@ def __ne__(self, other): class AsDynamic(AsContainer): """ Args: - model (None, :doc:`uproot4.model.Model`, or :doc:`uproot4.containers.Container`): Optional + model (None, :py:class:`~uproot4.model.Model`, or :py:class:`~uproot4.containers.Container`): Optional description of the data, used in - :doc:`uproot4.containers.AsDynamic.awkward_form` but ignored in - :doc:`uproot4.containers.AsDynamic.read`. + :py:meth:`~uproot4.containers.AsDynamic.awkward_form` but ignored in + :py:meth:`~uproot4.containers.AsDynamic.read`. - A :doc:`uproot4.containers.AsContainer` for one object whose class may + A :py:class:`~uproot4.containers.AsContainer` for one object whose class may not be known before reading. The byte-stream consists of a class name followed by instance data. Only @@ -263,8 +263,8 @@ def __init__(self, model=None): def model(self): """ Optional description of the data, used in - :doc:`uproot4.containers.AsDynamic.awkward_form` but ignored in - :doc:`uproot4.containers.AsDynamic.read`. + :py:meth:`~uproot4.containers.AsDynamic.awkward_form` but ignored in + :py:meth:`~uproot4.containers.AsDynamic.read`. """ return self._model @@ -317,12 +317,12 @@ class AsFIXME(AsContainer): Args: message (str): Required string, prefixes the error message. - A :doc:`uproot4.containers.AsContainer` for types that are known to be + A :py:class:`~uproot4.containers.AsContainer` for types that are known to be unimplemented. The name is intended to be conspicuous, so that such cases may be more easily fixed. - :doc:`uproot4.containers.AsFIXME.read` raises a - :doc:`uproot4.deserialization.DeserializationError` asking for a bug-report. + :py:meth:`~uproot4.containers.AsFIXME.read` raises a + :py:exc:`~uproot4.deserialization.DeserializationError` asking for a bug-report. """ def __init__(self, message): @@ -360,7 +360,7 @@ def __eq__(self, other): class AsString(AsContainer): """ Args: - header (bool): Sets the :doc:`uproot4.containers.AsContainer.header`. + header (bool): Sets the :py:attr:`~uproot4.containers.AsContainer.header`. length_bytes ("1-5" or "4"): Method used to determine the length of a string: "1-5" means one byte if the length is less than 256, otherwise the true length is in the next four bytes; "4" means @@ -368,19 +368,19 @@ class AsString(AsContainer): typename (None or str): If None, construct a plausible C++ typename. Otherwise, take the suggestion as given. - A :doc:`uproot4.containers.AsContainer` for strings nested withing other + A :py:class:`~uproot4.containers.AsContainer` for strings nested withing other objects. - This is not an :doc:`uproot4.interpretation.Interpretation`; it *must* be - nested, at least within :doc:`uproot4.interpretation.objects.AsObjects`. + This is not an :py:class:`~uproot4.interpretation.Interpretation`; it *must* be + nested, at least within :py:class:`~uproot4.interpretation.objects.AsObjects`. - Note that the :doc:`uproot4.interpretation.strings.AsStrings` class is + Note that the :py:class:`~uproot4.interpretation.strings.AsStrings` class is for a ``TBranch`` that contains only strings. - (:doc:`uproot4.interpretation.objects.AsObjects.simplify` converts an - :doc:`uproot4.interpretation.objects.AsObjects` of - :doc:`uproot4.containers.AsString` into a - :doc:`uproot4.interpretation.strings.AsStrings`.) + (:py:meth:`~uproot4.interpretation.objects.AsObjects.simplify` converts an + :py:class:`~uproot4.interpretation.objects.AsObjects` of + :py:class:`~uproot4.containers.AsString` into a + :py:class:`~uproot4.interpretation.strings.AsStrings`.) """ def __init__(self, header, length_bytes="1-5", typename=None): @@ -477,17 +477,17 @@ def __eq__(self, other): class AsPointer(AsContainer): """ Args: - pointee (None, :doc:`uproot4.model.Model`, or :doc:`uproot4.containers.Container`): Optional + pointee (None, :py:class:`~uproot4.model.Model`, or :py:class:`~uproot4.containers.Container`): Optional description of the data, used in - :doc:`uproot4.containers.AsPointer.awkward_form` but ignored in - :doc:`uproot4.containers.AsPointer.read`. + :py:meth:`~uproot4.containers.AsPointer.awkward_form` but ignored in + :py:meth:`~uproot4.containers.AsPointer.read`. - A :doc:`uproot4.containers.AsContainer` for an object referred to by + A :py:class:`~uproot4.containers.AsContainer` for an object referred to by pointer, meaning that it could be None (``nullptr``) or identical to an already-read object. The deserialization procedure calls - :doc:`uproot4.deserialization.read_object_any`. + :py:func:`~uproot4.deserialization.read_object_any`. """ def __init__(self, pointee=None): @@ -497,8 +497,8 @@ def __init__(self, pointee=None): def pointee(self): """ Optional description of the data, used in - :doc:`uproot4.containers.AsPointer.awkward_form` but ignored in - :doc:`uproot4.containers.AsPointer.read`. + :py:meth:`~uproot4.containers.AsPointer.awkward_form` but ignored in + :py:meth:`~uproot4.containers.AsPointer.read`. """ return self._pointee @@ -546,13 +546,13 @@ def __eq__(self, other): class AsArray(AsContainer): """ Args: - header (bool): Sets the :doc:`uproot4.containers.AsContainer.header`. + header (bool): Sets the :py:attr:`~uproot4.containers.AsContainer.header`. speedbump (bool): If True, one byte must be skipped before reading the data. - values (:doc:`uproot4.model.Model`, :doc:`uproot4.containers.Container`, or ``numpy.dtype``): Data + values (:py:class:`~uproot4.model.Model`, :py:class:`~uproot4.containers.Container`, or ``numpy.dtype``): Data type for data nested in the array. - A :doc:`uproot4.containers.AsContainer` for simple arrays (not + A :py:class:`~uproot4.containers.AsContainer` for simple arrays (not ``std::vector``). """ @@ -572,7 +572,7 @@ def speedbump(self): def values(self): """ Data type for data nested in the array. May be a - :doc:`uproot4.model.Model`, :doc:`uproot4.containers.Container`, or + :py:class:`~uproot4.model.Model`, :py:class:`~uproot4.containers.Container`, or ``numpy.dtype``. """ return self._values @@ -677,11 +677,11 @@ def read(self, chunk, cursor, context, file, selffile, parent, header=True): class AsVector(AsContainer): """ Args: - header (bool): Sets the :doc:`uproot4.containers.AsContainer.header`. - values (:doc:`uproot4.model.Model` or :doc:`uproot4.containers.Container`): Data + header (bool): Sets the :py:attr:`~uproot4.containers.AsContainer.header`. + values (:py:class:`~uproot4.model.Model` or :py:class:`~uproot4.containers.Container`): Data type for data nested in the container. - A :doc:`uproot4.containers.AsContainer` for ``std::vector``. + A :py:class:`~uproot4.containers.AsContainer` for ``std::vector``. """ def __init__(self, header, values): @@ -794,11 +794,11 @@ def __eq__(self, other): class AsSet(AsContainer): """ Args: - header (bool): Sets the :doc:`uproot4.containers.AsContainer.header`. - keys (:doc:`uproot4.model.Model` or :doc:`uproot4.containers.Container`): Data + header (bool): Sets the :py:attr:`~uproot4.containers.AsContainer.header`. + keys (:py:class:`~uproot4.model.Model` or :py:class:`~uproot4.containers.Container`): Data type for data nested in the container. - A :doc:`uproot4.containers.AsContainer` for ``std::set``. + A :py:class:`~uproot4.containers.AsContainer` for ``std::set``. """ def __init__(self, header, keys): @@ -917,13 +917,13 @@ def _has_nested_header(obj): class AsMap(AsContainer): """ Args: - header (bool): Sets the :doc:`uproot4.containers.AsContainer.header`. - keys (:doc:`uproot4.model.Model` or :doc:`uproot4.containers.Container`): Data + header (bool): Sets the :py:attr:`~uproot4.containers.AsContainer.header`. + keys (:py:class:`~uproot4.model.Model` or :py:class:`~uproot4.containers.Container`): Data type for the map's keys. - values (:doc:`uproot4.model.Model` or :doc:`uproot4.containers.Container`): Data + values (:py:class:`~uproot4.model.Model` or :py:class:`~uproot4.containers.Container`): Data type for the map's values. - A :doc:`uproot4.containers.AsContainer` for ``std::map``. + A :py:class:`~uproot4.containers.AsContainer` for ``std::map``. """ def __init__(self, header, keys, values): @@ -1260,7 +1260,7 @@ class STLMap(Container, Mapping): @classmethod def from_mapping(cls, mapping): """ - Construct a :doc:`uproot4.containers.STLMap` from a Python object with + Construct a :py:class:`~uproot4.containers.STLMap` from a Python object with ``keys()`` and ``values()``. """ return STLMap(mapping.keys(), mapping.values()) diff --git a/uproot4/deserialization.py b/uproot4/deserialization.py index 5df82b5f7..a73805acb 100644 --- a/uproot4/deserialization.py +++ b/uproot4/deserialization.py @@ -2,9 +2,9 @@ """ Defines low-level routines for deserialization, including -:doc:`uproot4.deserialization.compile_class`, which creates class objects from +:py:func:`~uproot4.deserialization.compile_class`, which creates class objects from ``TStreamerInfo``-derived code, and -:doc:`uproot4.deserialization.read_object_any`, which manages references to +:py:func:`~uproot4.deserialization.read_object_any`, which manages references to previously read objects. """ @@ -44,15 +44,15 @@ def _yield_all_behaviors(cls, c): def compile_class(file, classes, class_code, class_name): """ Args: - file (:doc:`uproot4.reading.ReadOnlyFile`): File to use to generate - :doc:`uproot4.model.Model` classes as needed from its - :doc:`uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` + file (:py:class:`~uproot4.reading.ReadOnlyFile`): File to use to generate + :py:class:`~uproot4.model.Model` classes as needed from its + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` for error messages. classes (dict): MutableMapping in which to add the finished class. class_code (str): Python code string defining the new class. class_name (str): Python (encoded) name of the new class. See - :doc:`uproot4.model.classname_decode` and - :doc:`uproot4.model.classname_encode`. + :py:func:`~uproot4.model.classname_decode` and + :py:func:`~uproot4.model.classname_encode`. Compile a new class from Python code and insert it in the dict of classes. """ @@ -97,9 +97,9 @@ def c(name, version=None): def numbytes_version(chunk, cursor, context, move=True): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. - cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. + cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in that ``chunk``. context (dict): Auxiliary data used in deserialization. move (bool): If True, move the ``cursor`` to a position just past the @@ -145,11 +145,11 @@ def numbytes_check( ): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. - start_cursor (:doc:`uproot4.source.cursor.Cursor`): Initial position in + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. + start_cursor (:py:class:`~uproot4.source.cursor.Cursor`): Initial position in that ``chunk``. - stop_cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in + stop_cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in that ``chunk``. num_bytes (int or None): If an integer, the number of bytes to compare with the difference between ``start_cursor`` and ``stop_cursor``; @@ -161,7 +161,7 @@ def numbytes_check( Verifies that the number of bytes matches the change in position of the cursor (if ``num_bytes`` is not None). - Raises a :doc:`uproot4.deserialization.DeserializationError` on failure. + Raises a :py:exc:`~uproot4.deserialization.DeserializationError` on failure. """ if num_bytes is not None: observed = stop_cursor.displacement(start_cursor) @@ -183,33 +183,33 @@ def numbytes_check( def read_object_any(chunk, cursor, context, file, selffile, parent, as_class=None): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. - cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. + cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in that ``chunk``. context (dict): Auxiliary data used in deserialization. - file (:doc:`uproot4.reading.ReadOnlyFile`): File to use to generate - :doc:`uproot4.model.Model` classes as needed from its - :doc:`uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` + file (:py:class:`~uproot4.reading.ReadOnlyFile`): File to use to generate + :py:class:`~uproot4.model.Model` classes as needed from its + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` for error messages. - selffile (:doc:`uproot4.reading.CommonFileMethods`): A possibly - :doc:`uproot4.reading.DetachedFile` associated with the ``parent``. + selffile (:py:class:`~uproot4.reading.CommonFileMethods`): A possibly + :py:class:`~uproot4.reading.DetachedFile` associated with the ``parent``. parent (None or calling object): The previous ``read`` in the recursive descent. - as_class (None or :doc:`uproot4.model.Model`): If None, use the class + as_class (None or :py:class:`~uproot4.model.Model`): If None, use the class indicated in the byte stream; otherwise, use this class. Generic read function, which may deliver an instance of any class and may reference previously read objects. - This function is the reason why :doc:`uproot4.source.cursor.Cursor` has a - :doc:`uproot4.source.cursor.Cursor.refs`; that dictionary holds previously + This function is the reason why :py:class:`~uproot4.source.cursor.Cursor` has a + :py:attr:`~uproot4.source.cursor.Cursor.refs`; that dictionary holds previously read objects that might need to be accessed later. - The :doc:`uproot4.source.cursor.Cursor` has an - :doc:`uproot4.source.cursor.Cursor.origin` to account for the fact that + The :py:class:`~uproot4.source.cursor.Cursor` has an + :py:attr:`~uproot4.source.cursor.Cursor.origin` to account for the fact that seek positions for keys in the reference dict are relative to the start of - the :doc:`uproot4.source.chunk.Chunk`, rather than the start of the file + the :py:class:`~uproot4.source.chunk.Chunk`, rather than the start of the file (as it would have to be for decompressed chunks). """ # TBufferFile::ReadObjectAny() @@ -317,20 +317,20 @@ class DeserializationError(Exception): """ Error raised when a ROOT file cannot be deserialized. - If the first attempt in :doc:`uproot4.reading.ReadOnlyKey.get` failed with - predefined :doc:`uproot4.model.Model` classes, this exception is caught + If the first attempt in :py:meth:`~uproot4.reading.ReadOnlyKey.get` failed with + predefined :py:class:`~uproot4.model.Model` classes, this exception is caught and retried with ``TStreamerInfo``-derived classes, so - :doc:`uproot4.deserialization.DeserializationError` sometimes appears in an + :py:exc:`~uproot4.deserialization.DeserializationError` sometimes appears in an exception chain two levels deep. (Some ROOT files do have classes that don't match the standard ``TStreamerInfo``; they may have been produced from private builds of ROOT between official releases.) - If a :doc:`uproot4.deserialization.DeserializationError` is caught, the byte + If a :py:exc:`~uproot4.deserialization.DeserializationError` is caught, the byte stream at the position where it failed can be inspected with - * :doc:`uproot4.deserialization.DeserializationError.debug` - * :doc:`uproot4.deserialization.DeserializationError.debug_array` - * :doc:`uproot4.deserialization.DeserializationError.partial_object` + * :py:meth:`~uproot4.deserialization.DeserializationError.debug` + * :py:meth:`~uproot4.deserialization.DeserializationError.debug_array` + * :py:attr:`~uproot4.deserialization.DeserializationError.partial_object` """ def __init__(self, message, chunk, cursor, context, file_path): @@ -426,13 +426,13 @@ def debug( """ Args: skip_bytes (int): Number of bytes to skip before presenting the - remainder of the :doc:`uproot4.source.chunk.Chunk`. May be + remainder of the :py:class:`~uproot4.source.chunk.Chunk`. May be negative, to examine the byte stream leading up to the attempted deserialization. limit_bytes (None or int): Number of bytes to limit the output to. A line of debugging output (without any ``offset``) is 20 bytes, so multiples of 20 show full lines. If None, everything is - shown to the end of the :doc:`uproot4.source.chunk.Chunk`, + shown to the end of the :py:class:`~uproot4.source.chunk.Chunk`, which might be large. dtype (None, ``numpy.dtype``, or its constructor argument): If None, present only the bytes as decimal values (0-255). Otherwise, @@ -450,7 +450,7 @@ def debug( Example output with ``dtype=">f4"`` and ``offset=3``. - .. code-block:: raw + .. code-block:: --+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+- 123 123 123 63 140 204 205 64 12 204 205 64 83 51 51 64 140 204 205 64 @@ -480,14 +480,14 @@ def debug_array(self, skip_bytes=0, dtype=numpy.dtype("u1")): """ Args: skip_bytes (int): Number of bytes to skip before presenting the - remainder of the :doc:`uproot4.source.chunk.Chunk`. May be + remainder of the :py:class:`~uproot4.source.chunk.Chunk`. May be negative, to examine the byte stream leading up to the attempted deserialization. dtype (``numpy.dtype`` or its constructor argument): Data type in which to interpret the data. (The size of the array returned is truncated to this ``dtype.itemsize``.) - Like :doc:`uproot4.deserialization.DeserializationError.debug`, but + Like :py:meth:`~uproot4.deserialization.DeserializationError.debug`, but returns a NumPy array for further inspection. """ dtype = numpy.dtype(dtype) diff --git a/uproot4/dynamic.py b/uproot4/dynamic.py index af1f59155..7e6cf39b7 100644 --- a/uproot4/dynamic.py +++ b/uproot4/dynamic.py @@ -3,14 +3,14 @@ """ Initially empty submodule into which new classes are dynamically added. -The purpose of this namespace is to allow :doc:`uproot4.model.VersionedModel` +The purpose of this namespace is to allow :py:class:`~uproot4.model.VersionedModel` classes that were automatically generated from ROOT ``TStreamerInfo`` to be -pickled, with the help of :doc:`uproot4.model.DynamicModel`. +pickled, with the help of :py:class:`~uproot4.model.DynamicModel`. In `Python 3.7 and later `__, attempts -to extract items from this namespace generate new :doc:`uproot4.model.DynamicModel` +to extract items from this namespace generate new :py:class:`~uproot4.model.DynamicModel` classes, which are used as a container in which data from pickled -:doc:`uproot4.model.VersionedModel` instances are filled. +:py:class:`~uproot4.model.VersionedModel` instances are filled. """ diff --git a/uproot4/extras.py b/uproot4/extras.py index bca575e92..f02d90cea 100644 --- a/uproot4/extras.py +++ b/uproot4/extras.py @@ -23,7 +23,10 @@ def awkward1(): raise ImportError( """install the 'awkward1' package with: - pip install awkward1""" + pip install awkward1 + +or use library="np" to output as NumPy arrays, rather than Awkward arrays. +""" ) else: return awkward1 diff --git a/uproot4/interpretation/__init__.py b/uproot4/interpretation/__init__.py index a8d7e2eca..e4bc0cb22 100644 --- a/uproot4/interpretation/__init__.py +++ b/uproot4/interpretation/__init__.py @@ -4,11 +4,11 @@ Defines procedures for interpreting data in ``TTrees`` as arrays. All interpretations must be subclasses of -:doc:`uproot4.interpretation.Interpretation`. +:py:class:`~uproot4.interpretation.Interpretation`. -See :doc:`uproot4.interpretation.identify.interpretation_of` for heuristics +See :py:func:`~uproot4.interpretation.identify.interpretation_of` for heuristics that determine the default interpretation of a -:doc:`uproot4.behavior.TBranch.TBranch`. +:py:class:`~uproot4.behavior.TBranch.TBranch`. """ from __future__ import absolute_import @@ -23,13 +23,13 @@ class Interpretation(object): 1. Producing temporary arrays from each uncompressed ``TBasket``. 2. Combining those temporary arrays for the whole range of entries requested between ``entry_start`` and ``entry_stop`` in - :doc:`uproot4.behaviors.TBranch.HasBranches.arrays` or - :doc:`uproot4.behaviors.TBranch.TBranch.array`, or by ``entry_step`` - in :doc:`uproot4.behaviors.TBranch.TBranch.iterate`. + :py:meth:`~uproot4.behaviors.TBranch.HasBranches.arrays` or + :py:meth:`~uproot4.behaviors.TBranch.TBranch.array`, or by ``entry_step`` + in :py:meth:`~uproot4.behaviors.TBranch.TBranch.iterate`. 3. Trimming the combined array to the exact entry range requested. (``TBasket`` boundaries might not align with the requested entry range.) 4. Passing the combined, trimmed temporary array to a selected - :doc:`uproot4.interpretation.library.Library` for finalization + :py:class:`~uproot4.interpretation.library.Library` for finalization and possibly grouping. """ @@ -61,9 +61,9 @@ def numpy_dtype(self): def awkward_form(self, file, index_format="i64", header=False, tobject_header=True): """ Args: - file (:doc:`uproot4.reading.ReadOnlyFile`): File to use to generate - :doc:`uproot4.model.Model` classes from its - :doc:`uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` + file (:py:class:`~uproot4.reading.ReadOnlyFile`): File to use to generate + :py:class:`~uproot4.model.Model` classes from its + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` for error messages. index_format (str): Format to use for indexes of the ``awkward1.forms.Form``; may be ``"i32"``, ``"u32"``, or @@ -90,13 +90,13 @@ def basket_array( the ``TBasket`` starts and stops. The header is not included (i.e. the first offset is ``0``), and the length of this array is one greater than the number of entries in the ``TBasket``. - basket (:doc:`uproot4.models.TBasket`): The ``TBasket`` object. + basket (:py:class:`~uproot4.models.TBasket.Model_TBasket`): The ``TBasket`` object. context (dict): Auxiliary data used in deserialization. cursor_offset (int): Correction to the integer keys used in - :doc:`uproot4.source.cursor.Cursor.refs` for objects + :py:attr:`~uproot4.source.cursor.Cursor.refs` for objects deserialized by reference - (:doc:`uproot4.deserialization.read_object_any`). - library (:doc:`uproot4.interpretation.library.Library`): The + (:py:func:`~uproot4.deserialization.read_object_any`). + library (:py:class:`~uproot4.interpretation.library.Library`): The requested library for output. Performs the first step of interpretation, from uncompressed ``TBasket`` @@ -111,18 +111,18 @@ def final_array( Args: basket_arrays (dict of int \u2192 array): Mapping from ``TBasket`` number to the temporary array returned by - :doc:`uproot4.interpretation.Interpretation.basket_array`. + :py:meth:`~uproot4.interpretation.Interpretation.basket_array`. entry_start (int): First entry to include when trimming any excess entries from the first ``TBasket``. entry_stop (int): FIrst entry to exclude (one greater than the last entry to include) when trimming any excess entries from the last ``TBasket``. entry_offsets (list of int): The - :doc:`uproot4.behaviors.TBranch.TBranch.entry_offsets` for this + :py:attr:`~uproot4.behaviors.TBranch.TBranch.entry_offsets` for this ``TBranch``. - library (:doc:`uproot4.interpretation.library.Library`): The + library (:py:class:`~uproot4.interpretation.library.Library`): The requested library for output. - branch (:doc:`uproot4.behaviors.TBranch.TBranch`): The ``TBranch`` + branch (:py:class:`~uproot4.behaviors.TBranch.TBranch`): The ``TBranch`` that is being interpreted. Performs the last steps of interpretation, from a collection of @@ -139,48 +139,48 @@ def __ne__(self, other): def hook_before_basket_array(self, *args, **kwargs): """ - Called in :doc:`uproot4.interpretation.Interpretation.basket_array`, + Called in :py:meth:`~uproot4.interpretation.Interpretation.basket_array`, before any interpretation. This is the first hook called in - :doc:`uproot4.interpretation.Interpretation.basket_array`. + :py:meth:`~uproot4.interpretation.Interpretation.basket_array`. """ pass def hook_after_basket_array(self, *args, **kwargs): """ - Called in :doc:`uproot4.interpretation.Interpretation.basket_array`, + Called in :py:meth:`~uproot4.interpretation.Interpretation.basket_array`, after all interpretation. This is the last hook called in - :doc:`uproot4.interpretation.Interpretation.basket_array`. + :py:meth:`~uproot4.interpretation.Interpretation.basket_array`. """ pass def hook_before_final_array(self, *args, **kwargs): """ - Called in :doc:`uproot4.interpretation.Interpretation.final_array`, + Called in :py:meth:`~uproot4.interpretation.Interpretation.final_array`, before any trimming, finalization, or grouping. This is the first hook called in - :doc:`uproot4.interpretation.Interpretation.final_array`. + :py:meth:`~uproot4.interpretation.Interpretation.final_array`. """ pass def hook_before_library_finalize(self, *args, **kwargs): """ - Called in :doc:`uproot4.interpretation.Interpretation.final_array`, + Called in :py:meth:`~uproot4.interpretation.Interpretation.final_array`, after trimming but before calling the - :doc:`uproot4.interpretation.library.Library.finalize` routine. + :py:meth:`~uproot4.interpretation.library.Library.finalize` routine. """ pass def hook_after_final_array(self, *args, **kwargs): """ - Called in :doc:`uproot4.interpretation.Interpretation.final_array`, + Called in :py:meth:`~uproot4.interpretation.Interpretation.final_array`, after all trimming, finalization, and grouping. This is the last hook called in - :doc:`uproot4.interpretation.Interpretation.final_array`. + :py:meth:`~uproot4.interpretation.Interpretation.final_array`. """ pass diff --git a/uproot4/interpretation/grouped.py b/uproot4/interpretation/grouped.py index 6f6419e83..22b7a6374 100644 --- a/uproot4/interpretation/grouped.py +++ b/uproot4/interpretation/grouped.py @@ -1,7 +1,7 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/master/LICENSE """ -Defines an :doc:`uproot4.interpretation.Interpretation` and temporary array +Defines an :py:class:`~uproot4.interpretation.Interpretation` and temporary array for grouped data; usually applied to a ``TBranch`` that does not contain data but has subbranches that do. """ @@ -15,20 +15,20 @@ class AsGrouped(uproot4.interpretation.Interpretation): """ Args: - branch (:doc:`uproot4.behavior.TBranch.TBranch`): The ``TBranch`` that + branch (:py:class:`~uproot4.behavior.TBranch.TBranch`): The ``TBranch`` that represents the group. - subbranches (list of :doc:`uproot4.behavior.TBranch.TBranch`): The + subbranches (list of :py:class:`~uproot4.behavior.TBranch.TBranch`): The ``TBranches`` that contain the actual data. typename (None or str): If None, construct a plausible C++ typename. Otherwise, take the suggestion as given. Interpretation for a group of arrays, usually because they are all - subbranches of the same :doc:`uproot4.behavior.TBranch.TBranch`. + subbranches of the same :py:class:`~uproot4.behavior.TBranch.TBranch`. - Each :doc:`uproot4.interpretation.library.Library` presents a group - differently: :doc:`uproot4.interpretation.library.NumPy` puts arrays - in a dict, :doc:`uproot4.interpretation.library.Awkward` makes an - array of records, :doc:`uproot4.interpretation.library.Pandas` makes + Each :py:class:`~uproot4.interpretation.library.Library` presents a group + differently: :py:class:`~uproot4.interpretation.library.NumPy` puts arrays + in a dict, :py:class:`~uproot4.interpretation.library.Awkward` makes an + array of records, :py:class:`~uproot4.interpretation.library.Pandas` makes a ``pandas.DataFrame``, etc. """ diff --git a/uproot4/interpretation/identify.py b/uproot4/interpretation/identify.py index 01d3f8f2c..cee84d35f 100644 --- a/uproot4/interpretation/identify.py +++ b/uproot4/interpretation/identify.py @@ -2,11 +2,11 @@ """ Defines utilities for identifying the -:doc:`uproot4.interpretation.Interpretation` of a -:doc:`uproot4.behavior.TBranch.TBranch`. +:py:class:`~uproot4.interpretation.Interpretation` of a +:py:class:`~uproot4.behavior.TBranch.TBranch`. This includes a tokenizer/parser for C++ types and heuristics encoded in -:doc:`uproot4.interpretation.identify.interpretation_of`. The latter will +:py:func:`~uproot4.interpretation.identify.interpretation_of`. The latter will need to be tweaked by new types, type combinations, and serialization methods observed in ROOT files (perhaps forever), unless a systematic study can be performed to exhaustively discover all cases. @@ -284,19 +284,19 @@ def _float16_or_double32(branch, context, leaf, is_float16, dims): def interpretation_of(branch, context, simplify=True): """ Args: - branch (:doc:`uproot4.behavior.TBranch.TBranch`): The ``TBranch`` to + branch (:py:class:`~uproot4.behavior.TBranch.TBranch`): The ``TBranch`` to interpret as an array. context (dict): Auxiliary data used in deserialization. simplify (bool): If True, call - :doc:`uproot4.interpretation.objects.AsObjects.simplify` on any - :doc:`uproot4.interpretation.objects.AsObjects` to try to get a + :py:meth:`~uproot4.interpretation.objects.AsObjects.simplify` on any + :py:class:`~uproot4.interpretation.objects.AsObjects` to try to get a more efficient interpretation. - Attempts to derive an :doc:`uproot4.interpretation.Interpretation` of the + Attempts to derive an :py:class:`~uproot4.interpretation.Interpretation` of the ``branch`` (within some ``context``). If no interpretation can be found, it raises - :doc:`uproot4.interpretation.identify.UnknownInterpretation`. + :py:exc:`~uproot4.interpretation.identify.UnknownInterpretation`. """ if len(branch.branches) != 0: if branch.top_level and branch.has_member("fClassName"): @@ -1052,19 +1052,19 @@ def parse_typename( """ Args: typename (str): The C++ type to parse. - file (None or :doc:`uproot4.reading.CommonFileMethods`): Used to provide + file (None or :py:class:`~uproot4.reading.CommonFileMethods`): Used to provide error messages with the ``file_path``. quote (bool): If True, return the output as a string to evaluate. This - is used to build code for a :doc:`uproot4.model.Model`, rather than - the :doc:`uproot4.model.Model` itself. + is used to build code for a :py:class:`~uproot4.model.Model`, rather than + the :py:class:`~uproot4.model.Model` itself. outer_header (bool): If True, set the ``header`` flag for the outermost - :doc:`uproot4.containers.AsContainer` to True. + :py:class:`~uproot4.containers.AsContainer` to True. inner_header (bool): If True, set the ``header`` flag for inner - :doc:`uproot4.containers.AsContainer` objects to True. + :py:class:`~uproot4.containers.AsContainer` objects to True. string_header (bool): If True, set the ``header`` flag for - :doc:`uproot4.containers.AsString` objects to True. + :py:class:`~uproot4.containers.AsString` objects to True. - Return a :doc:`uproot4.model.Model` or :doc:`uproot4.containers.AsContainer` + Return a :py:class:`~uproot4.model.Model` or :py:class:`~uproot4.containers.AsContainer` for the C++ ``typename``. """ tokens = list(_tokenize_typename_pattern.finditer(typename)) @@ -1093,7 +1093,7 @@ def parse_typename( class NotNumerical(Exception): """ Exception used to stop searches for a numerical interpretation in - :doc:`uproot4.interpretation.identify.interpretation_of` as soon as a + :py:func:`~uproot4.interpretation.identify.interpretation_of` as soon as a non-conforming type is found. """ @@ -1102,14 +1102,14 @@ class NotNumerical(Exception): class UnknownInterpretation(Exception): """ - Exception raised by :doc:`uproot4.interpretation.identify.interpretation_of` - if an :doc:`uproot4.interpretation.Interpretation` cannot be found. + Exception raised by :py:func:`~uproot4.interpretation.identify.interpretation_of` + if an :py:class:`~uproot4.interpretation.Interpretation` cannot be found. - The :doc:`uproot4.behavior.TBranch.TBranch.interpretation` property may have - :doc:`uproot4.interpretation.identify.UnknownInterpretation` as a value. + The :py:attr:`~uproot4.behavior.TBranch.TBranch.interpretation` property may have + :py:exc:`~uproot4.interpretation.identify.UnknownInterpretation` as a value. Any attempts to use this class as a - :doc:`uproot4.interpretation.Interpretation` causes it to raise itself. + :py:class:`~uproot4.interpretation.Interpretation` causes it to raise itself. Thus, failing to find an interpretation for a ``TBranch`` is not a fatal error, but attempting to use it to deserialize arrays is a fatal error. """ diff --git a/uproot4/interpretation/jagged.py b/uproot4/interpretation/jagged.py index 14b85815c..54635906b 100644 --- a/uproot4/interpretation/jagged.py +++ b/uproot4/interpretation/jagged.py @@ -1,12 +1,12 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/master/LICENSE """ -Defines an :doc:`uproot4.interpretation.Interpretation` and temporary array for +Defines an :py:class:`~uproot4.interpretation.Interpretation` and temporary array for jagged (variable-length list) data. -The :doc:`uproot4.interpretation.jagged.JaggedArray` class only holds data while +The :py:class:`~uproot4.interpretation.jagged.JaggedArray` class only holds data while an array is being built from ``TBaskets``. Its final form is determined by -:doc:`uproot4.interpretation.library`. +:py:mod:`uproot4.interpretation.library`. """ from __future__ import absolute_import @@ -36,20 +36,20 @@ def fast_divide(array, divisor): class AsJagged(uproot4.interpretation.Interpretation): """ Args: - content (:doc:`uproot4.interpretation.numerical.AsDtype` or :doc:`uproot4.interpretation.objects.AsStridedObjects`): Interpretation + content (:py:class:`~uproot4.interpretation.numerical.AsDtype` or :py:class:`~uproot4.interpretation.objects.AsStridedObjects`): Interpretation for data in the nested, variable-length lists. header_bytes (int): Number of bytes to skip at the beginning of each entry. typename (None or str): If None, construct a plausible C++ typename. Otherwise, take the suggestion as given. - original (None, :doc:`uproot4.model.Model`, or :doc:`uproot4.containers.Container`): If + original (None, :py:class:`~uproot4.model.Model`, or :py:class:`~uproot4.containers.Container`): If this interpretation is derived from - :doc:`uproot4.interpretation.objects.AsObjects.simplify`, this is a + :py:meth:`~uproot4.interpretation.objects.AsObjects.simplify`, this is a reminder of the original - :doc:`uproot4.interpretation.objects.AsObjects.model`. + :py:attr:`~uproot4.interpretation.objects.AsObjects.model`. Interpretation for any array that can be described as variable-length lists - of :doc:`uproot4.interpretation.numerical.AsDtype`. + of :py:class:`~uproot4.interpretation.numerical.AsDtype`. """ def __init__(self, content, header_bytes=0, typename=None, original=None): @@ -63,8 +63,8 @@ def __init__(self, content, header_bytes=0, typename=None, original=None): @property def content(self): """ - The :doc:`uproot4.interpretation.numerical.AsDtype` or - :doc:`uproot4.interpretation.objects.AsStridedObjects` that interprets + The :py:class:`~uproot4.interpretation.numerical.AsDtype` or + :py:class:`~uproot4.interpretation.objects.AsStridedObjects` that interprets data in the nested, variable-length lists. """ return self._content @@ -80,9 +80,9 @@ def header_bytes(self): def original(self): """ If not None, this was the original - :doc:`uproot4.interpretation.objects.AsObjects.model` from an - :doc:`uproot4.interpretation.objects.AsObjects` that was simplified - into this :doc:`uproot4.interpretation.jagged.AsJagged`. + :py:attr:`~uproot4.interpretation.objects.AsObjects.model` from an + :py:class:`~uproot4.interpretation.objects.AsObjects` that was simplified + into this :py:class:`~uproot4.interpretation.jagged.AsJagged`. """ return self._original @@ -337,9 +337,9 @@ class JaggedArray(object): jagged array. Temporary array filled by - :doc:`uproot4.interpretation.jagged.AsJagged.basket_array`, which will be + :py:meth:`~uproot4.interpretation.jagged.AsJagged.basket_array`, which will be turned into a NumPy, Awkward, or other array, depending on the specified - :doc:`uproot4.interpretation.library.Library`. + :py:class:`~uproot4.interpretation.library.Library`. """ def __init__(self, offsets, content): @@ -388,7 +388,7 @@ def parents_localindex(self, entry_start, entry_stop): Awkward 0 terminology. The "parents" is an array of integers with the same length as - :doc:`uproot4.interpretation.jagged.JaggedArray.content` that indicates + :py:attr:`~uproot4.interpretation.jagged.JaggedArray.content` that indicates which list each item belongs to. The "localindex" is an array of integers with the same length that diff --git a/uproot4/interpretation/library.py b/uproot4/interpretation/library.py index 59d412b33..fb847a520 100644 --- a/uproot4/interpretation/library.py +++ b/uproot4/interpretation/library.py @@ -4,26 +4,26 @@ Represents external libraries that define "array-like" types so that users can choose an output format. -The :doc:`uproot4.interpretation.library.NumPy` library always works (NumPy is +The :py:class:`~uproot4.interpretation.library.NumPy` library always works (NumPy is Uproot's only strict dependency) and outputs NumPy arrays for single arrays and dict/tuple/list as groups. Objects and jagged arrays are not efficiently represented, but it provides a zero-dependency least common denominator. -The :doc:`uproot4.interpretation.library.Awkward` library is the default and +The :py:class:`~uproot4.interpretation.library.Awkward` library is the default and depends on Awkward Array (``awkward1``). It is usually the best option, as it was designed for Uproot. -The :doc:`uproot4.interpretation.library.Pandas` library outputs +The :py:class:`~uproot4.interpretation.library.Pandas` library outputs ``pandas.Series`` for single arrays and ``pandas.DataFrame`` as groups. Objects are not efficiently represented, but some jagged arrays are encoded as ``pandas.MultiIndex``. -The :doc:`uproot4.interpretation.library.CuPy` library outputs arrays on a +The :py:class:`~uproot4.interpretation.library.CuPy` library outputs arrays on a GPU, but the types that it supports are limited. Note that Awkward Arrays can be GPU-resident as well. -Lazy arrays (:doc:`uproot4.behavior.TBranch.TBranch.lazy`) can only use the -:doc:`uproot4.interpretation.library.Awkward` library. +Lazy arrays (:py:func:`~uproot4.behavior.TBranch.lazy`) can only use the +:py:class:`~uproot4.interpretation.library.Awkward` library. """ from __future__ import absolute_import @@ -47,14 +47,14 @@ class Library(object): A library is used in the finalization and grouping stages of producing an array, converting it from internal representations like - :doc:`uproot4.interpretation.jagged.JaggedArray`, - :doc:`uproot4.interpretation.strings.StringArray`, and - :doc:`uproot4.interpretation.objects.ObjectArray` into the library's + :py:class:`~uproot4.interpretation.jagged.JaggedArray`, + :py:class:`~uproot4.interpretation.strings.StringArray`, and + :py:class:`~uproot4.interpretation.objects.ObjectArray` into the library's equivalents. It can also be required for concatenation and other late-stage operations on the output arrays. Libraries are usually selected by a string name. These names are held in a - private registry in the :doc:`uproot4.interpretation.library` module. + private registry in the :py:mod:`uproot4.interpretation.library` module. """ @property @@ -81,9 +81,9 @@ def finalize(self, array, branch, interpretation, entry_start, entry_stop): Args: array (array): Internal, temporary, trimmed array. If this is a NumPy array, it may be identical to the output array. - branch (:doc:`uproot4.behavior.TBranch.TBranch`): The ``TBranch`` + branch (:py:class:`~uproot4.behavior.TBranch.TBranch`): The ``TBranch`` that is represented by this array. - interpretation (:doc:`uproot4.interpretation.Interpretation`): The + interpretation (:py:class:`~uproot4.interpretation.Interpretation`): The interpretation that produced the ``array``. entry_start (int): First entry that is included in the output. entry_stop (int): FIrst entry that is excluded (one greater than @@ -122,16 +122,16 @@ def group(self, arrays, expression_context, how): "dict)".format(self.name) ) - def global_index(self, array, global_start): + def global_index(self, array, global_offset): """ Args: array (array): The library-appropriate array whose global index needs adjustment. - global_start (int): A number to add to the global index of + global_offset (int): A number to add to the global index of ``array`` to correct it. Apply *in-place* corrections to the global index of ``array`` by adding - ``global_start``. + ``global_offset``. Even though the operation is performed *in-place*, this method returns the ``array``. @@ -157,7 +157,7 @@ def __eq__(self, other): class NumPy(Library): u""" - A :doc:`uproot4.interpetation.library.Library` that presents ``TBranch`` + A :py:class:`~uproot4.interpetation.library.Library` that presents ``TBranch`` data as NumPy arrays. The standard name for this library is ``"np"``. The single-``TBranch`` form for this library is a ``numpy.ndarray``. If @@ -363,14 +363,14 @@ def _awkward_json_to_array(awkward1, form, array): class Awkward(Library): u""" - A :doc:`uproot4.interpetation.library.Library` that presents ``TBranch`` + A :py:class:`~uproot4.interpetation.library.Library` that presents ``TBranch`` data as Awkward Arrays. The standard name for this library is ``"ak"``. This is the default for all functions that require a - :doc:`uproot4.interpetation.library.Library`, though Uproot does not + :py:class:`~uproot4.interpetation.library.Library`, though Uproot does not explicitly depend on Awkward Array. If you are confronted with a message that Awkward Array is not installed, either install ``awkward1`` or - select another library (likely :doc:`uproot4.interpretation.library.NumPy`). + select another library (likely :py:class:`~uproot4.interpretation.library.NumPy`). Both the single-``TBranch`` and "group" forms for this library are ``ak.Array``, though groups are always arrays of records. Awkward Array @@ -631,7 +631,7 @@ def _pandas_basic_index(pandas, entry_start, entry_stop): class Pandas(Library): u""" - A :doc:`uproot4.interpetation.library.Library` that presents ``TBranch`` + A :py:class:`~uproot4.interpetation.library.Library` that presents ``TBranch`` data as Pandas Series and DataFrames. The standard name for this library is ``"pd"``. @@ -911,13 +911,13 @@ def group(self, arrays, expression_context, how): "DataFrames without merging)".format(self.name) ) - def global_index(self, arrays, global_start): + def global_index(self, arrays, global_offset): if type(arrays.index).__name__ == "MultiIndex": if hasattr(arrays.index.levels[0], "arrays"): index = arrays.index.levels[0].arrays # pandas>=0.24.0 else: index = arrays.index.levels[0].values # pandas<0.24.0 - numpy.add(index, global_start, out=index) + numpy.add(index, global_offset, out=index) elif type(arrays.index).__name__ == "RangeIndex": if hasattr(arrays.index, "start") and hasattr(arrays.index, "stop"): @@ -927,7 +927,7 @@ def global_index(self, arrays, global_start): index_start = arrays.index._start # pandas<0.25.0 index_stop = arrays.index._stop arrays.index = type(arrays.index)( - index_start + global_start, index_stop + global_start + index_start + global_offset, index_stop + global_offset ) else: @@ -935,7 +935,7 @@ def global_index(self, arrays, global_start): index = arrays.index.arrays # pandas>=0.24.0 else: index = arrays.index.values # pandas<0.24.0 - numpy.add(index, global_start, out=index) + numpy.add(index, global_offset, out=index) return arrays @@ -969,7 +969,7 @@ def concatenate(self, all_arrays): class CuPy(Library): u""" - A :doc:`uproot4.interpetation.library.Library` that presents ``TBranch`` + A :py:class:`~uproot4.interpetation.library.Library` that presents ``TBranch`` data as CuPy arrays on a GPU. The standard name for this library is ``"cp"``. The single-``TBranch`` form for this library is a ``cupy.ndarray``. diff --git a/uproot4/interpretation/numerical.py b/uproot4/interpretation/numerical.py index 8b1e3287f..4705e699f 100644 --- a/uproot4/interpretation/numerical.py +++ b/uproot4/interpretation/numerical.py @@ -1,18 +1,18 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/master/LICENSE """ -Defines an :doc:`uproot4.interpretation.Interpretation` for several numerical +Defines an :py:class:`~uproot4.interpretation.Interpretation` for several numerical types: -* :doc:`uproot4.interpretation.numerical.AsDtype`: numbers, which can simply be +* :py:class:`~uproot4.interpretation.numerical.AsDtype`: numbers, which can simply be described as a ``numpy.dtype``. -* :doc:`uproot4.interpretation.numerical.AsDtypeInPlace`: a predefined array +* :py:class:`~uproot4.interpretation.numerical.AsDtypeInPlace`: a predefined array into which data may be overwritten. -* :doc:`uproot4.interpretation.numerical.AsDouble32`: ROOT's ``Double32_t`` +* :py:class:`~uproot4.interpretation.numerical.AsDouble32`: ROOT's ``Double32_t`` packed data type. -* :doc:`uproot4.interpretation.numerical.AsFloat16`: ROOT's ``Float16_t`` +* :py:class:`~uproot4.interpretation.numerical.AsFloat16`: ROOT's ``Float16_t`` packed data type. -* :doc:`uproot4.interpretation.numerical.AsSTLBits`: an ``std::bitset`` +* :py:class:`~uproot4.interpretation.numerical.AsSTLBits`: an ``std::bitset`` for some ``N``. """ @@ -35,9 +35,9 @@ class Numerical(uproot4.interpretation.Interpretation): """ Abstract superclass of numerical interpretations, including - * :doc:`uproot4.interpretation.numerical.AsDtype` - * :doc:`uproot4.interpretation.numerical.AsSTLBits` - * :doc:`uproot4.interpretation.numerical.TruncatedNumerical` + * :py:class:`~uproot4.interpretation.numerical.AsDtype` + * :py:class:`~uproot4.interpretation.numerical.AsSTLBits` + * :py:class:`~uproot4.interpretation.numerical.TruncatedNumerical` """ def _wrap_almost_finalized(self, array): @@ -199,7 +199,7 @@ def from_dtype(self): A shape (``dtype.shape``) can be used to construct a fixed-size array for each entry. (Not applicable to variable-length lists! See - :doc:`uproot4.interpretation.jagged.AsJagged`.) The finalized array's + :py:class:`~uproot4.interpretation.jagged.AsJagged`.) The finalized array's ``array.shape[1:] == dtype.shape``. """ return self._from_dtype @@ -208,7 +208,7 @@ def from_dtype(self): def to_dtype(self): """ Data type to convert the data into. Usually the native-endian - equivalent of :doc:`uproot4.interpretation.numerical.AsDtype.from_dtype`; + equivalent of :py:meth:`~uproot4.interpretation.numerical.AsDtype.from_dtype`; may include named fields and a shape. Named fields (``dtype.names``) can be used to construct a NumPy @@ -216,7 +216,7 @@ def to_dtype(self): A shape (``dtype.shape``) can be used to construct a fixed-size array for each entry. (Not applicable to variable-length lists! See - :doc:`uproot4.interpretation.jagged.AsJagged`.) The finalized array's + :py:class:`~uproot4.interpretation.jagged.AsJagged`.) The finalized array's ``array.shape[1:] == dtype.shape``. """ return self._to_dtype @@ -225,7 +225,7 @@ def to_dtype(self): def itemsize(self): """ Number of bytes per item of - :doc:`uproot4.interpretation.numerical.AsDtype.from_dtype`. + :py:meth:`~uproot4.interpretation.numerical.AsDtype.from_dtype`. This number of bytes includes the fields and shape, like ``dtype.itemsize`` in NumPy. @@ -347,7 +347,7 @@ def basket_array( class AsDtypeInPlace(AsDtype): """ - Like :doc:`uproot4.interpretation.numerical.AsDtype`, but a given array is + Like :py:class:`~uproot4.interpretation.numerical.AsDtype`, but a given array is filled in-place, rather than creating a new output array. """ @@ -375,8 +375,8 @@ class TruncatedNumerical(Numerical): Subclasses are - * :doc:`uproot4.interpretation.numerical.AsDouble32` - * :doc:`uproot4.interpretation.numerical.AsFloat16` + * :py:class:`~uproot4.interpretation.numerical.AsDouble32` + * :py:class:`~uproot4.interpretation.numerical.AsFloat16` """ @property @@ -418,7 +418,7 @@ def from_dtype(self): def itemsize(self): """ Number of bytes in - :doc:`uproot4.interpretation.numerical.TruncatedNumerical.from_dtype`. + :py:meth:`~uproot4.interpretation.numerical.TruncatedNumerical.from_dtype`. """ return self.from_dtype.itemsize @@ -432,8 +432,8 @@ def to_dims(self): @property def is_truncated(self): """ - If True (:doc:`uproot4.interpretation.numerical.TruncatedNumerical.low` - and :doc:`uproot4.interpretation.numerical.TruncatedNumerical.high` are + If True (:py:attr:`~uproot4.interpretation.numerical.TruncatedNumerical.low` + and :py:attr:`~uproot4.interpretation.numerical.TruncatedNumerical.high` are both ``0``), the data are truly truncated. """ return self._low == 0.0 and self._high == 0.0 @@ -537,7 +537,7 @@ class AsDouble32(TruncatedNumerical): high (float): Upper bound on the range of expressible values. num_bits (int): Number of bits in the representation. to_dims (tuple of ints): Shape of - :doc:`uproot4.interpretation.numerical.AsDouble32.to_dtype`. + :py:meth:`~uproot4.interpretation.numerical.AsDouble32.to_dtype`. Interpretation for ROOT's ``Double32_t`` type. """ @@ -562,7 +562,7 @@ def to_dtype(self): A shape (``dtype.shape``) can be used to construct a fixed-size array for each entry. (Not applicable to variable-length lists! See - :doc:`uproot4.interpretation.jagged.AsJagged`.) The finalized array's + :py:class:`~uproot4.interpretation.jagged.AsJagged`.) The finalized array's ``array.shape[1:] == dtype.shape``. """ return numpy.dtype((numpy.float64, self.to_dims)) @@ -599,7 +599,7 @@ class AsFloat16(TruncatedNumerical): high (float): Upper bound on the range of expressible values. num_bits (int): Number of bits in the representation. to_dims (tuple of ints): Shape of - :doc:`uproot4.interpretation.numerical.AsFloat16.to_dtype`. + :py:attr:`~uproot4.interpretation.numerical.AsFloat16.to_dtype`. Interpretation for ROOT's ``Float16_t`` type. """ @@ -624,7 +624,7 @@ def to_dtype(self): A shape (``dtype.shape``) can be used to construct a fixed-size array for each entry. (Not applicable to variable-length lists! See - :doc:`uproot4.interpretation.jagged.AsJagged`.) The finalized array's + :py:class:`~uproot4.interpretation.jagged.AsJagged`.) The finalized array's ``array.shape[1:] == dtype.shape``. """ return numpy.dtype((numpy.float32, self.to_dims)) diff --git a/uproot4/interpretation/objects.py b/uproot4/interpretation/objects.py index 43cb4f9d0..fed17a4ec 100644 --- a/uproot4/interpretation/objects.py +++ b/uproot4/interpretation/objects.py @@ -1,23 +1,23 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/master/LICENSE """ -Defines an :doc:`uproot4.interpretation.Interpretation` and temporary array for +Defines an :py:class:`~uproot4.interpretation.Interpretation` and temporary array for object data (Python objects or Awkward Array data structures). -The :doc:`uproot4.interpretation.objects.AsObjects` describes fully generic -objects using a :doc:`uproot4.interpretation.model.Model` (or -:doc:`uproot4.interpretation.containers`). These objects require a +The :py:class:`~uproot4.interpretation.objects.AsObjects` describes fully generic +objects using a :py:class:`~uproot4.interpretation.model.Model` (or a +:py:class:`~uproot4.interpretation.containers.AsContainer`). These objects require a non-vectorized loop to deserialize. -The :doc:`uproot4.interpretation.objects.AsStridedObjects` describes fixed-width +The :py:class:`~uproot4.interpretation.objects.AsStridedObjects` describes fixed-width objects that can be described as a ``numpy.dtype``. These objects can be interpreted as a single, vectorized cast, and are therefore much faster to deserialize. -The :doc:`uproot4.interpretation.object.ObjectArray` and -:doc:`uproot4.interpretation.object.StridedObjectArray` classes only hold data +The :py:class:`~uproot4.interpretation.object.ObjectArray` and +:py:class:`~uproot4.interpretation.object.StridedObjectArray` classes only hold data while an array is being built from ``TBaskets``. Its final form is determined -by :doc:`uproot4.interpretation.library`. +by the :py:class:`~uproot4.interpretation.library.Library`. """ from __future__ import absolute_import @@ -38,7 +38,7 @@ def awkward_can_optimize(interpretation, form): """ If True, the Awkward Array library can convert data of a given - :doc:`uproot4.interpretation.Interpretation` and ``ak.forms.Form`` into + :py:class:`~uproot4.interpretation.Interpretation` and ``ak.forms.Form`` into arrays without resorting to ``ak.from_iter`` (i.e. rapidly). If ``awkward1._connect._uproot`` cannot be imported, this function always @@ -55,16 +55,16 @@ def awkward_can_optimize(interpretation, form): class AsObjects(uproot4.interpretation.Interpretation): """ Args: - model (:doc:`uproot4.model.Model` or :doc:`uproot4.containers.Container`): The + model (:py:class:`~uproot4.model.Model` or :py:class:`~uproot4.containers.AsContainer`): The full Uproot deserialization model for the data. - branch (None or :doc:`uproot4.behavior.TBranch.TBranch`): The ``TBranch`` + branch (None or :py:class:`~uproot4.behavior.TBranch.TBranch`): The ``TBranch`` from which the data are drawn. Integerpretation for arrays of any kind of data that might reside in a ROOT ``TTree``. This interpretation prescribes the full (slow) deserialization process. - :doc:`uproot4.interpretation.objects.AsObjects.simplify` attempts to + :py:meth:`~uproot4.interpretation.objects.AsObjects.simplify` attempts to replace this interpretation with a faster-to-read equivalent, but not all data types can be simplified. """ @@ -77,7 +77,7 @@ def __init__(self, model, branch=None): def model(self): """ The full Uproot deserialization model for the data - (:doc:`uproot4.model.Model` or :doc:`uproot4.containers.Container`). + (:py:class:`~uproot4.model.Model` or :py:class:`~uproot4.containers.AsContainer`). """ return self._model @@ -208,7 +208,9 @@ def final_array( start = stop - if all(type(x).__module__.startswith("awkward1") for x in basket_arrays.values()): + if all( + type(x).__module__.startswith("awkward1") for x in basket_arrays.values() + ): assert isinstance(library, uproot4.interpretation.library.Awkward) awkward1 = library.imported output = awkward1.concatenate(trimmed, mergebool=False, highlevel=False) @@ -241,7 +243,7 @@ def final_array( def simplify(self): """ - Attempts to replace this :doc:`uproot4.interpretation.objects.AsObjects` + Attempts to replace this :py:class:`~uproot4.interpretation.objects.AsObjects` with an interpretation that can be executed more quickly. If there isn't a simpler interpretation, then this method returns @@ -347,30 +349,30 @@ def _strided_awkward_form( class AsStridedObjects(uproot4.interpretation.numerical.AsDtype): """ Args: - model (:doc:`uproot4.model.Model` or :doc:`uproot4.containers.Container`): The + model (:py:class:`~uproot4.model.Model` or :py:class:`~uproot4.containers.AsContainer`): The full Uproot deserialization model for the data. - members (list of (str, :doc:`uproot4.interpretation.Interpretation`) tuples): The + members (list of (str, :py:class:`~uproot4.interpretation.Interpretation`) tuples): The name and fixed-width interpretation for each member of the objects. - original (None, :doc:`uproot4.model.Model`, or :doc:`uproot4.containers.Container`): If + original (None, :py:class:`~uproot4.model.Model`, or :py:class:`~uproot4.containers.AsContainer`): If this interpretation is derived from - :doc:`uproot4.interpretation.objects.AsObjects.simplify`, this is a + :py:meth:`~uproot4.interpretation.objects.AsObjects.simplify`, this is a reminder of the original - :doc:`uproot4.interpretation.objects.AsObjects.model`. + :py:attr:`~uproot4.interpretation.objects.AsObjects.model`. Interpretation for an array (possibly - :doc:`uproot4.interpretation.jagged.AsJagged`) of fixed-size objects. Since + :py:class:`~uproot4.interpretation.jagged.AsJagged`) of fixed-size objects. Since the objects have a fixed number of fields with a fixed number of bytes each, - the whole array (or :doc:`uproot4.interpretation.jagged.AsJagged.content`) + the whole array (or :py:attr:`~uproot4.interpretation.jagged.AsJagged.content`) can be interpreted in one vectorized array-cast. Therefore, this - interpretation is faster than :doc:`uproot4.interpretation.objects.AsObjects` + interpretation is faster than :py:class:`~uproot4.interpretation.objects.AsObjects` *when it is possible*. - Unlike :doc:`uproot4.interpretation.numerical.AsDtype` with a + Unlike :py:class:`~uproot4.interpretation.numerical.AsDtype` with a `structured array `__, the objects in the final array have the methods required by its ``model``. - If the ``library`` is :doc:`uproot4.interpretation.library.NumPy`, these + If the ``library`` is :py:class:`~uproot4.interpretation.library.NumPy`, these are instantiated as Python objects (slow); if - :doc:`uproot4.interpretation.library.Awkward`, they are behaviors passed to + :py:class:`~uproot4.interpretation.library.Awkward`, they are behaviors passed to the Awkward Array's local `behavior `__. """ @@ -385,7 +387,7 @@ def __init__(self, model, members, original=None): def model(self): """ The full Uproot deserialization model for the data - (:doc:`uproot4.model.Model` or :doc:`uproot4.containers.Container`). + (:py:class:`~uproot4.model.Model` or :py:class:`~uproot4.containers.AsContainer`). """ return self._model @@ -393,7 +395,7 @@ def model(self): def members(self): """ The name (str) and fixed-width - :doc:`uproot4.interpretation.Interpretation` for each member of the + :py:class:`~uproot4.interpretation.Interpretation` for each member of the objects as a list of 2-tuple pairs. """ return self._members @@ -402,9 +404,9 @@ def members(self): def original(self): """ If not None, this was the original - :doc:`uproot4.interpretation.objects.AsObjects.model` from an - :doc:`uproot4.interpretation.objects.AsObjects` that was simplified - into this :doc:`uproot4.interpretation.objects.AsStridedObjects`. + :py:attr:`~uproot4.interpretation.objects.AsObjects.model` from an + :py:class:`~uproot4.interpretation.objects.AsObjects` that was simplified + into this :py:class:`~uproot4.interpretation.objects.AsStridedObjects`. """ return self._original @@ -441,8 +443,8 @@ def _wrap_almost_finalized(self, array): class CannotBeStrided(Exception): """ Exception used to stop recursion over - :doc:`uproot4.model.Model.strided_interpretation` and - :doc:`uproot4.containers.AsContainer.strided_interpretation` as soon as a + :py:meth:`~uproot4.model.Model.strided_interpretation` and + :py:meth:`~uproot4.containers.AsContainer.strided_interpretation` as soon as a non-conforming type is found. """ @@ -452,9 +454,9 @@ class CannotBeStrided(Exception): class CannotBeAwkward(Exception): """ Exception used to stop recursion over - :doc:`uproot4.interpretation.Interpretation.awkward_form`, - :doc:`uproot4.model.Model.awkward_form` and - :doc:`uproot4.containers.AsContainer.awkward_form` as soon as a + :py:meth:`~uproot4.interpretation.Interpretation.awkward_form`, + :py:meth:`~uproot4.model.Model.awkward_form` and + :py:meth:`~uproot4.containers.AsContainer.awkward_form` as soon as a non-conforming type is found. """ @@ -465,24 +467,24 @@ def __init__(self, because): class ObjectArray(object): """ Args: - model (:doc:`uproot4.model.Model` or :doc:`uproot4.containers.Container`): The + model (:py:class:`~uproot4.model.Model` or :py:class:`~uproot4.containers.AsContainer`): The full Uproot deserialization model for the data. - branch (:doc:`uproot4.behavior.TBranch.TBranch`): The ``TBranch`` from + branch (:py:class:`~uproot4.behavior.TBranch.TBranch`): The ``TBranch`` from which the data are drawn. context (dict): Auxiliary data used in deserialization. byte_offsets (array of ``numpy.int32``): Index where each entry of the ``byte_content`` starts and stops. byte_content (array of ``numpy.uint8``): Raw but uncompressed data, directly from - :doc:`uproot4.interpretation.Interpretation.basket_array`. + :py:meth:`~uproot4.interpretation.Interpretation.basket_array`. cursor_offset (int): Correction to the integer keys used in - :doc:`uproot4.source.cursor.Cursor.refs` for objects deserialized - by reference (:doc:`uproot4.deserialization.read_object_any`). + :py:attr:`~uproot4.source.cursor.Cursor.refs` for objects deserialized + by reference (:py:func:`~uproot4.deserialization.read_object_any`). Temporary array filled by - :doc:`uproot4.interpretation.objects.AsObjects.basket_array`, which will be + :py:meth:`~uproot4.interpretation.objects.AsObjects.basket_array`, which will be turned into a NumPy, Awkward, or other array, depending on the specified - :doc:`uproot4.interpretation.library.Library`. + :py:class:`~uproot4.interpretation.library.Library`. """ def __init__( @@ -510,7 +512,7 @@ def __repr__(self): def model(self): """ The full Uproot deserialization model for the data - (:doc:`uproot4.model.Model` or :doc:`uproot4.containers.Container`). + (:py:class:`~uproot4.model.Model` or :py:class:`~uproot4.containers.AsContainer`). """ return self._model @@ -539,7 +541,7 @@ def byte_offsets(self): def byte_content(self): """ Raw but uncompressed data, directly from - :doc:`uproot4.interpretation.Interpretation.basket_array`. + :py:meth:`~uproot4.interpretation.Interpretation.basket_array`. """ return self._byte_content @@ -547,8 +549,8 @@ def byte_content(self): def cursor_offset(self): """ Correction to the integer keys used in - :doc:`uproot4.source.cursor.Cursor.refs` for objects deserialized by - reference (:doc:`uproot4.deserialization.read_object_any`). + :py:attr:`~uproot4.source.cursor.Cursor.refs` for objects deserialized by + reference (:py:func:`~uproot4.deserialization.read_object_any`). """ return self._cursor_offset @@ -626,15 +628,15 @@ def _strided_object(path, interpretation, data): class StridedObjectArray(object): """ Args: - interpretation (:doc:`uproot4.interpretation.objects.AsStridedObjects`): The + interpretation (:py:class:`~uproot4.interpretation.objects.AsStridedObjects`): The interpretation that produced this array. array (array): Underlying array object, which may be NumPy or another temporary array. Temporary array filled by - :doc:`uproot4.interpretation.objects.AsStridedObjects.basket_array`, which + :py:meth:`~uproot4.interpretation.objects.AsStridedObjects.basket_array`, which will be turned into a NumPy, Awkward, or other array, depending on the - specified :doc:`uproot4.interpretation.library.Library`. + specified :py:class:`~uproot4.interpretation.library.Library`. """ def __init__(self, interpretation, array): diff --git a/uproot4/interpretation/strings.py b/uproot4/interpretation/strings.py index b4828d168..7f2cd4de6 100644 --- a/uproot4/interpretation/strings.py +++ b/uproot4/interpretation/strings.py @@ -1,16 +1,16 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/master/LICENSE """ -Defines an :doc:`uproot4.interpretation.Interpretation` and temporary array for +Defines an :py:class:`~uproot4.interpretation.Interpretation` and temporary array for string data. -Note that :doc:`uproot4.interpretation.strings.AsStrings` is an interpretation for -top-level strings, but :doc:`uproot4.containers.AsString` can be nested within -other :doc:`uproot4.containers`. +Note that :py:class:`~uproot4.interpretation.strings.AsStrings` is an interpretation for +top-level strings, but :py:class:`~uproot4.containers.AsString` can be nested within any +other :py:class:`~uproot4.containers.AsContainer`. -The :doc:`uproot4.interpretation.strings.StringArray` class only holds data while -an array is being built from ``TBaskets``. Its final form is determined by -:doc:`uproot4.interpretation.library`. +The :py:class:`~uproot4.interpretation.strings.StringArray` class only holds data while +an array is being built from ``TBaskets``. Its final form is determined by the +:py:class:`~uproot4.interpretation.library.Library`. """ from __future__ import absolute_import @@ -36,26 +36,26 @@ class AsStrings(uproot4.interpretation.Interpretation): always four bytes. typename (None or str): If None, construct a plausible C++ typename. Otherwise, take the suggestion as given. - original (None, :doc:`uproot4.model.Model`, or :doc:`uproot4.containers.Container`): If + original (None, :py:class:`~uproot4.model.Model`, or :py:class:`~uproot4.containers.Container`): If this interpretation is derived from - :doc:`uproot4.interpretation.objects.AsObjects.simplify`, this is a + :py:meth:`~uproot4.interpretation.objects.AsObjects.simplify`, this is a reminder of the original - :doc:`uproot4.interpretation.objects.AsObjects.model`. + :py:attr:`~uproot4.interpretation.objects.AsObjects.model`. - An :doc:`uproot4.interpretation.Interpretation` for an array of strings. + An :py:class:`~uproot4.interpretation.Interpretation` for an array of strings. This cannot be nested within other - :doc:`uproot4.interpretation.Interpretation` objects; it can only represent + :py:class:`~uproot4.interpretation.Interpretation` objects; it can only represent a ``TBranch`` that only contains strings (not strings within ``std::vector``, for instance). - Note that the :doc:`uproot4.containers.AsString` class is for strings nested + Note that the :py:class:`~uproot4.containers.AsString` class is for strings nested within other objects. - (:doc:`uproot4.interpretation.objects.AsObjects.simplify` converts an - :doc:`uproot4.interpretation.objects.AsObjects` of - :doc:`uproot4.containers.AsString` into a - :doc:`uproot4.interpretation.strings.AsStrings`.) + (:py:meth:`~uproot4.interpretation.objects.AsObjects.simplify` converts an + :py:class:`~uproot4.interpretation.objects.AsObjects` of + :py:class:`~uproot4.containers.AsString` into a + :py:class:`~uproot4.interpretation.strings.AsStrings`.) """ def __init__( @@ -89,9 +89,9 @@ def length_bytes(self): def original(self): """ If not None, this was the original - :doc:`uproot4.interpretation.objects.AsObjects.model` from an - :doc:`uproot4.interpretation.objects.AsObjects` that was simplified - into this :doc:`uproot4.interpretation.jagged.AsJagged`. + :py:attr:`~uproot4.interpretation.objects.AsObjects.model` from an + :py:class:`~uproot4.interpretation.objects.AsObjects` that was simplified + into this :py:class:`~uproot4.interpretation.jagged.AsJagged`. """ return self._original @@ -359,9 +359,9 @@ class StringArray(object): the array. Temporary array filled by - :doc:`uproot4.interpretation.strings.AsStrings.basket_array`, which will be + :py:meth:`~uproot4.interpretation.strings.AsStrings.basket_array`, which will be turned into a NumPy, Awkward, or other array, depending on the specified - :doc:`uproot4.interpretation.library.Library`. + :py:class:`~uproot4.interpretation.library.Library`. """ def __init__(self, offsets, content): diff --git a/uproot4/language/__init__.py b/uproot4/language/__init__.py index 97ad3ecac..67e3e38c1 100644 --- a/uproot4/language/__init__.py +++ b/uproot4/language/__init__.py @@ -2,11 +2,11 @@ """ Defines languages for expressions passed to -:doc:`uproot4.behavior.TBranch.HasBranches.arrays` (and similar). +:py:meth:`~uproot4.behavior.TBranch.HasBranches.arrays` (and similar). -The default is :doc:`uproot4.language.python.PythonLanguage`. +The default is :py:class:`~uproot4.language.python.PythonLanguage`. -All languages must be subclasses of :doc:`uproot4.language.Language`. +All languages must be subclasses of :py:class:`~uproot4.language.Language`. """ from __future__ import absolute_import @@ -15,10 +15,10 @@ class Language(object): """ Abstract class for all languages, which are used to compute the expressions - that are passed to :doc:`uproot4.behavior.TBranch.HasBranches.arrays` (and + that are passed to :py:meth:`~uproot4.behavior.TBranch.HasBranches.arrays` (and similar). - The default is :doc:`uproot4.language.python.PythonLanguage`. + The default is :py:class:`~uproot4.language.python.PythonLanguage`. """ pass diff --git a/uproot4/language/python.py b/uproot4/language/python.py index f5695fa4c..89d601bb6 100644 --- a/uproot4/language/python.py +++ b/uproot4/language/python.py @@ -1,10 +1,10 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/master/LICENSE """ -Defines a :doc:`uproot4.language.Language` for expressions passed to -:doc:`uproot4.behavior.TBranch.HasBranches.arrays` (and similar). +Defines a :py:class:`~uproot4.language.Language` for expressions passed to +:py:meth:`~uproot4.behavior.TBranch.HasBranches.arrays` (and similar). -The :doc:`uproot4.language.python.PythonLanguage` evaluates Python code. It is +The :py:class:`~uproot4.language.python.PythonLanguage` evaluates Python code. It is the default language. """ @@ -243,9 +243,9 @@ class PythonLanguage(uproot4.language.Language): needed for branches whose names are not valid Python symbols. Default is "get". - PythonLanguage is the default :doc:`uproot4.language.Language` for + PythonLanguage is the default :py:class:`~uproot4.language.Language` for interpreting expressions passed to - :doc:`uproot4.behavior.TBranch.HasBranches.arrays` (and similar). This + :py:meth:`~uproot4.behavior.TBranch.HasBranches.arrays` (and similar). This interpretation assumes that the expressions have Python syntax and semantics, with math functions loaded into the namespace. diff --git a/uproot4/model.py b/uproot4/model.py index 36d59ec59..1be0387de 100644 --- a/uproot4/model.py +++ b/uproot4/model.py @@ -2,17 +2,17 @@ """ Defines utilities for modeling C++ objects as Python objects and the -:doc:`uproot4.model.Model` class, which is the superclass of all objects that +:py:class:`~uproot4.model.Model` class, which is the superclass of all objects that are read from ROOT files. -The :doc:`uproot4.model.VersionedModel` class is the superclass of all models +The :py:class:`~uproot4.model.VersionedModel` class is the superclass of all models whose deserialization routines are specialized by ROOT class version. -A :doc:`uproot4.model.DispatchByVersion` subclass selects a versioned model +A :py:class:`~uproot4.model.DispatchByVersion` subclass selects a versioned model after reading its version bytes. -The :doc:`uproot4.model.UnknownClass` and -:doc:`uproot4.model.UnknownClassVersion` are placeholders for data that could +The :py:exc:`~uproot4.model.UnknownClass` and +:py:exc:`~uproot4.model.UnknownClassVersion` are placeholders for data that could not be modeled, either because the class has no streamer or no streamer for its version. """ @@ -212,14 +212,14 @@ def class_named(classname, version=None, custom_classes=None): If ``version`` is None, no attempt is made to find a specific version. - * If the class is a :doc:`uproot4.model.DispatchByVersion`, then this is + * If the class is a :py:class:`~uproot4.model.DispatchByVersion`, then this is object returned. * If the class is a versionless model, then this is the object returned. If ``version`` is an integer, an attempt is made to find the specific version. - * If the class is a :doc:`uproot4.model.DispatchByVersion`, then it is + * If the class is a :py:class:`~uproot4.model.DispatchByVersion`, then it is queried for a versioned model. * If the class is a versionless model, then this is the object returned. @@ -256,7 +256,7 @@ def class_named(classname, version=None, custom_classes=None): def has_class_named(classname, version=None, custom_classes=None): """ - Returns True if :doc:`uproot4.model.class_named` would find a class, + Returns True if :py:func:`~uproot4.model.class_named` would find a class, False if it would raise an exception. """ cls = maybe_custom_classes(custom_classes).get(classname) @@ -283,23 +283,23 @@ def maybe_custom_classes(custom_classes): class Model(object): """ Abstract class for all objects extracted from ROOT files (except for - :doc:`uproot4.reading.ReadOnlyFile`, :doc:`uproot4.reading.ReadOnlyDirectory`, - and :doc:`uproot4.reading.ReadOnlyKey`). + :py:class:`~uproot4.reading.ReadOnlyFile`, :py:class:`~uproot4.reading.ReadOnlyDirectory`, + and :py:class:`~uproot4.reading.ReadOnlyKey`). - A model is instantiated from a file using the :doc:`uproot4.model.Model.read` - classmethod or synthetically using the :doc:`uproot4.model.Model.empty` + A model is instantiated from a file using the :py:meth:`~uproot4.model.Model.read` + classmethod or synthetically using the :py:meth:`~uproot4.model.Model.empty` classmethod, not through a normal constructor. Models point back to the file from which they were created, though only a few classes (named in ``uproot4.reading.must_be_attached``) have an open, - readable file attached; the rest have a :doc:`uproot4.reading.DetachedFile` + readable file attached; the rest have a :py:class:`~uproot4.reading.DetachedFile` with information about the file, while not holding the file open. Uproot recognizes *some* of ROOT's thousands of classes, by way of methods - and properties defined in :doc:`uproot4.behaviors`. Examples include + and properties defined in :py:mod:`uproot4.behaviors`. Examples include - * :doc:`uproot4.behaviors.TTree.TTree` - * :doc:`uproot4.behaviors.TH1.TH1` + * :py:class:`~uproot4.behaviors.TTree.TTree` + * :py:class:`~uproot4.behaviors.TH1.TH1` These classes are the most convenient to work with and have specialized documentation. @@ -307,13 +307,13 @@ class Model(object): Classes that don't have any predefined behaviors are still usable through their member data. - * :doc:`uproot4.model.Model.members`: a dict of C++ member names and values + * :py:attr:`~uproot4.model.Model.members`: a dict of C++ member names and values directly in this class. - * :doc:`uproot4.model.Model.all_members`: a dict of C++ member names and + * :py:attr:`~uproot4.model.Model.all_members`: a dict of C++ member names and values in this class or any superclasses. - * :doc:`uproot4.model.Model.member`: method that takes a C++ member name + * :py:meth:`~uproot4.model.Model.member`: method that takes a C++ member name and returns its value (from this or any superclass). - * :doc:`uproot4.model.Model.has_member`: method that takes a C++ member + * :py:meth:`~uproot4.model.Model.has_member`: method that takes a C++ member name and returns True if it exists (in this or any superclass), False otherwise. @@ -324,11 +324,11 @@ class Model(object): Pythonic models don't follow the same class inheritance tree as their C++ counterparts: most of them are direct subclasses of - :doc:`uproot4.model.Model`, :doc:`uproot4.model.DispatchByVersion`, or - :doc:`uproot4.model.VersionedModel`. To separate an object's members + :py:class:`~uproot4.model.Model`, :py:class:`~uproot4.model.DispatchByVersion`, or + :py:class:`~uproot4.model.VersionedModel`. To separate an object's members from its superclass members, a model instance is created for each and the superclass parts are included in a list called - :doc:`uproot4.model.Model.bases`. + :py:attr:`~uproot4.model.Model.bases`. """ class_streamer = None @@ -355,9 +355,9 @@ def classname(self): """ The C++ (decoded) classname of the modeled class. - See :doc:`uproot4.model.classname_decode`, - :doc:`uproot4.model.classname_encode`, and - :doc:`uproot4.model.classname_version`. + See :py:func:`~uproot4.model.classname_decode`, + :py:func:`~uproot4.model.classname_encode`, and + :py:func:`~uproot4.model.classname_version`. """ return classname_decode(self.encoded_classname)[0] @@ -367,9 +367,9 @@ def encoded_classname(self): The Python (encoded) classname of the modeled class. May or may not include version. - See :doc:`uproot4.model.classname_decode`, - :doc:`uproot4.model.classname_encode`, and - :doc:`uproot4.model.classname_version`. + See :py:func:`~uproot4.model.classname_decode`, + :py:func:`~uproot4.model.classname_encode`, and + :py:func:`~uproot4.model.classname_version`. """ return type(self).__name__ @@ -378,9 +378,9 @@ def class_version(self): """ The version number of the modeled class (int) if any; None otherwise. - See :doc:`uproot4.model.classname_decode`, - :doc:`uproot4.model.classname_encode`, and - :doc:`uproot4.model.classname_version`. + See :py:func:`~uproot4.model.classname_decode`, + :py:func:`~uproot4.model.classname_encode`, and + :py:func:`~uproot4.model.classname_version`. """ return classname_decode(self.encoded_classname)[1] @@ -388,15 +388,15 @@ def class_version(self): def cursor(self): """ A cursor pointing to the start of this instance in the byte stream - (before :doc:`uproot4.model.Model.read_numbytes_version`). + (before :py:meth:`~uproot4.model.Model.read_numbytes_version`). """ return self._cursor @property def file(self): """ - A :doc:`uproot4.reading.ReadOnlyFile`, which may be open and readable, - or a :doc:`uproot4.reading.DetachedFile`, which only contains + A :py:class:`~uproot4.reading.ReadOnlyFile`, which may be open and readable, + or a :py:class:`~uproot4.reading.DetachedFile`, which only contains information about the original file (not an open file handle). """ return self._file @@ -404,7 +404,7 @@ def file(self): def close(self): """ Closes the file from which this object is derived, if such a file is - still attached (i.e. not :doc:`uproot4.reading.DetachedFile`). + still attached (i.e. not :py:class:`~uproot4.reading.DetachedFile`). """ if isinstance(self._file, uproot4.reading.ReadOnlyFile): self._file.close() @@ -414,7 +414,7 @@ def closed(self): """ True if the associated file is known to be closed; False if it is known to be open. If the associated file is detached - (:doc:`uproot4.reading.DetachedFile`), then the value is None. + (:py:class:`~uproot4.reading.DetachedFile`), then the value is None. """ if isinstance(self._file, uproot4.reading.ReadOnlyFile): return self._file.closed @@ -436,7 +436,7 @@ def concrete(self): in C++, which is ``self`` if this is the concrete class or another object if this is actually a holder of superclass members for that other object (i.e. if this object is in the other's - :doc:`uproot4.model.Model.bases`). + :py:attr:`~uproot4.model.Model.bases`). """ return self._concrete @@ -445,7 +445,7 @@ def members(self): """ A dict of C++ member data directly associated with this class (i.e. not its superclasses). For all members, see - :doc:`uproot4.model.Model.all_members`. + :py:attr:`~uproot4.model.Model.all_members`. """ return self._members @@ -453,7 +453,7 @@ def members(self): def all_members(self): """ A dict of C++ member data for this class and its superclasses. For only - direct members, see :doc:`uproot4.model.Model.members`. + direct members, see :py:attr:`~uproot4.model.Model.members`. """ out = {} for base in self._bases: @@ -463,7 +463,7 @@ def all_members(self): def has_member(self, name, all=True): """ - Returns True if calling :doc:`uproot4.model.Model.member` with the same + Returns True if calling :py:meth:`~uproot4.model.Model.member` with the same arguments would return a value; False if the member is missing. """ if name in self._members: @@ -479,7 +479,7 @@ def member(self, name, all=True, none_if_missing=False): Args: name (str): The name of the member datum to retrieve. all (bool): If True, recursively search all superclasses in - :doc:`uproot4.model.Model.bases`. Otherwise, search the + :py:attr:`~uproot4.model.Model.bases`. Otherwise, search the direct class only. none_if_missing (bool): If a member datum doesn't exist in the search path, ``none_if_missing=True`` has this function return @@ -515,7 +515,7 @@ def member(self, name, all=True, none_if_missing=False): @property def bases(self): """ - List of :doc:`uproot4.model.Model` objects representing superclass data + List of :py:class:`~uproot4.model.Model` objects representing superclass data for this object in the order given in C++ (opposite method resolution order). @@ -534,7 +534,7 @@ def bases(self): def base(self, *cls): """ - Extracts instances from :doc:`uproot4.model.Model.bases` by Python class + Extracts instances from :py:attr:`~uproot4.model.Model.bases` by Python class type. The ``cls`` may be a single class or a (varargs) list of classes to match. """ @@ -555,7 +555,7 @@ def num_bytes(self): This value may be None (unknown before reading) or an integer. If the value is an integer and the object exists (no exceptions in - :doc:`uproot4.model.Model.read`), then the expected number of bytes + :py:meth:`~uproot4.model.Model.read`), then the expected number of bytes agreed with the actual number of bytes, and this numer is reliable. If this object is re-serialized, it won't necessarily occupy the same @@ -568,9 +568,9 @@ def instance_version(self): """ Version of this instance as read from the byte stream. - If this model is versioned (:doc:`uproot4.model.VersionedModel`), the + If this model is versioned (:py:class:`~uproot4.model.VersionedModel`), the ``instance_version`` ought to be equal to the - :doc:`uproot4.model.class_version`. + :py:func:`~uproot4.model.class_version`. If this model is versionless, the ``instance_version`` contains new information about the actual version deserialized. @@ -589,10 +589,10 @@ def is_memberwise(self): def awkward_form(cls, file, index_format="i64", header=False, tobject_header=True): """ Args: - cls (subclass of :doc:`uproot4.model.Model`): This class. - file (:doc:`uproot4.reading.ReadOnlyFile`): File to use to generate - :doc:`uproot4.model.Model` classes from its - :doc:`uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` + cls (subclass of :py:class:`~uproot4.model.Model`): This class. + file (:py:class:`~uproot4.reading.ReadOnlyFile`): File to use to generate + :py:class:`~uproot4.model.Model` classes from its + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` for error messages. index_format (str): Format to use for indexes of the ``awkward1.forms.Form``; may be ``"i32"``, ``"u32"``, or @@ -615,18 +615,18 @@ def strided_interpretation( ): """ Args: - cls (subclass of :doc:`uproot4.model.Model`): This class. - file (:doc:`uproot4.reading.ReadOnlyFile`): File to use to generate - :doc:`uproot4.model.Model` classes from its - :doc:`uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` + cls (subclass of :py:class:`~uproot4.model.Model`): This class. + file (:py:class:`~uproot4.reading.ReadOnlyFile`): File to use to generate + :py:class:`~uproot4.model.Model` classes from its + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` for error messages. header (bool): If True, assume the outermost object has a header. tobject_header (bool): If True, assume that ``TObjects`` have headers. - original (None, :doc:`uproot4.model.Model`, or :doc:`uproot4.containers.Container`): The + original (None, :py:class:`~uproot4.model.Model`, or :py:class:`~uproot4.containers.Container`): The original, non-strided model or container. Returns a list of (str, ``numpy.dtype``) pairs to build a - :doc:`uproot4.interpretation.objects.AsStridedObjects` interpretation. + :py:class:`~uproot4.interpretation.objects.AsStridedObjects` interpretation. """ raise uproot4.interpretation.objects.CannotBeStrided( classname_decode(cls.__name__)[0] @@ -673,20 +673,20 @@ def empty(cls): def read(cls, chunk, cursor, context, file, selffile, parent, concrete=None): """ Args: - cls (subclass of :doc:`uproot4.model.Model`): Class to instantiate. - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. - cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in + cls (subclass of :py:class:`~uproot4.model.Model`): Class to instantiate. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. + cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in that ``chunk``. context (dict): Auxiliary data used in deserialization. - file (:doc:`uproot4.reading.ReadOnlyFile`): An open file object, - capable of generating new :doc:`uproot4.model.Model` classes - from its :doc:`uproot4.reading.ReadOnlyFile.streamers`. - selffile (:doc:`uproot4.reading.CommonFileMethods`): A possibly - :doc:`uproot4.reading.DetachedFile` associated with this object. + file (:py:class:`~uproot4.reading.ReadOnlyFile`): An open file object, + capable of generating new :py:class:`~uproot4.model.Model` classes + from its :py:attr:`~uproot4.reading.ReadOnlyFile.streamers`. + selffile (:py:class:`~uproot4.reading.CommonFileMethods`): A possibly + :py:class:`~uproot4.reading.DetachedFile` associated with this object. parent (None or calling object): The previous ``read`` in the recursive descent. - concrete (None or :doc:`uproot4.model.Model` instance): If None, + concrete (None or :py:class:`~uproot4.model.Model` instance): If None, this model corresponds to the concrete (instantiated) class in C++. Otherwise, this model represents a superclass part of the object, and ``concrete`` points to the concrete instance. @@ -748,9 +748,9 @@ def read(cls, chunk, cursor, context, file, selffile, parent, concrete=None): def read_numbytes_version(self, chunk, cursor, context): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. - cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. + cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in that ``chunk``. context (dict): Auxiliary data used in deserialization. @@ -772,17 +772,17 @@ def read_numbytes_version(self, chunk, cursor, context): def read_members(self, chunk, cursor, context, file): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. - cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. + cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in that ``chunk``. context (dict): Auxiliary data used in deserialization. - file (:doc:`uproot4.reading.ReadOnlyFile`): An open file object, - capable of generating new :doc:`uproot4.model.Model` classes - from its :doc:`uproot4.reading.ReadOnlyFile.streamers`. + file (:py:class:`~uproot4.reading.ReadOnlyFile`): An open file object, + capable of generating new :py:class:`~uproot4.model.Model` classes + from its :py:attr:`~uproot4.reading.ReadOnlyFile.streamers`. Reads the member data for this class. The abstract class - :doc:`uproot4.model.Model` has an empty ``read_members`` method; this + :py:class:`~uproot4.model.Model` has an empty ``read_members`` method; this *must* be overridden by subclasses. """ pass @@ -790,17 +790,17 @@ def read_members(self, chunk, cursor, context, file): def check_numbytes(self, chunk, cursor, context): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. - cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. + cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in that ``chunk``. context (dict): Auxiliary data used in deserialization. Reads nothing; checks the expected number of bytes against the actual movement of the ``cursor`` at the end of the object, possibly raising - a :doc:`uproot4.deserialization.DeserializationError` exception. + a :py:exc:`~uproot4.deserialization.DeserializationError` exception. - If :doc:`uproot4.model.Model.num_bytes` is None, this method does + If :py:attr:`~uproot4.model.Model.num_bytes` is None, this method does nothing. It is *possible* that a subclass would override this method, but not @@ -821,59 +821,59 @@ def check_numbytes(self, chunk, cursor, context): def postprocess(self, chunk, cursor, context, file): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. - cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. + cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in that ``chunk``. context (dict): Auxiliary data used in deserialization. - file (:doc:`uproot4.reading.ReadOnlyFile`): An open file object, - capable of generating new :doc:`uproot4.model.Model` classes - from its :doc:`uproot4.reading.ReadOnlyFile.streamers`. + file (:py:class:`~uproot4.reading.ReadOnlyFile`): An open file object, + capable of generating new :py:class:`~uproot4.model.Model` classes + from its :py:attr:`~uproot4.reading.ReadOnlyFile.streamers`. Called for any additional processing after the object has been fully read. The return value from this method is the object that actually represents the ROOT data, which might be a different instance or even a different - type from this class. The default in :doc:`uproot4.model.Model` is to + type from this class. The default in :py:class:`~uproot4.model.Model` is to return ``self``. Note that for versioned models, - :doc:`uproot4.model.VersionedModel.postprocess` is called first, then - :doc:`uproot4.model.DispatchByVersion.postprocess` is called on its - output, allowing a :doc:`uproot4.model.DispatchByVersion` to refine all + :py:meth:`~uproot4.model.VersionedModel.postprocess` is called first, then + :py:meth:`~uproot4.model.DispatchByVersion.postprocess` is called on its + output, allowing a :py:class:`~uproot4.model.DispatchByVersion` to refine all data of its type, regardless of version. """ return self def hook_before_read(self, **kwargs): """ - Called in :doc:`uproot4.model.Model.read`, before any data have been + Called in :py:meth:`~uproot4.model.Model.read`, before any data have been read. """ pass def hook_before_read_members(self, **kwargs): """ - Called in :doc:`uproot4.model.Model.read`, after - :doc:`uproot4.model.Model.read_numbytes_version` and before - :doc:`uproot4.model.Model.read_members`. + Called in :py:meth:`~uproot4.model.Model.read`, after + :py:meth:`~uproot4.model.Model.read_numbytes_version` and before + :py:meth:`~uproot4.model.Model.read_members`. """ pass def hook_after_read_members(self, **kwargs): """ - Called in :doc:`uproot4.model.Model.read`, after - :doc:`uproot4.model.Model.read_members` and before - :doc:`uproot4.model.Model.check_numbytes`. + Called in :py:meth:`~uproot4.model.Model.read`, after + :py:meth:`~uproot4.model.Model.read_members` and before + :py:meth:`~uproot4.model.Model.check_numbytes`. """ pass def hook_before_postprocess(self, **kwargs): """ - Called in :doc:`uproot4.model.Model.read`, after - :doc:`uproot4.model.Model.check_numbytes` and before - :doc:`uproot4.model.Model.postprocess`. + Called in :py:meth:`~uproot4.model.Model.read`, after + :py:meth:`~uproot4.model.Model.check_numbytes` and before + :py:meth:`~uproot4.model.Model.postprocess`. """ pass @@ -882,16 +882,16 @@ class VersionedModel(Model): """ A Python class that models a specific version of a ROOT C++ class. - Classes that inherit directly from :doc:`uproot4.model.Model` are versionless, - classes that inherit from :doc:`uproot4.model.VersionedModel` depend on + Classes that inherit directly from :py:class:`~uproot4.model.Model` are versionless, + classes that inherit from :py:class:`~uproot4.model.VersionedModel` depend on version. - Note that automatically generated :doc:`uproot4.model.VersionedModel` classes + Note that automatically generated :py:class:`~uproot4.model.VersionedModel` classes are placed in the ``uproot4.dynamic`` namespace. This namespace can generate - :doc:`uproot4.model.DynamicModel` classes on demand in Python 3.7 and above, - which automatically generated :doc:`uproot4.model.VersionedModel` classes + :py:class:`~uproot4.model.DynamicModel` classes on demand in Python 3.7 and above, + which automatically generated :py:class:`~uproot4.model.VersionedModel` classes rely upon to be pickleable. Therefore, ROOT object types without predefined - :doc:`uproot4.model.Model` classes cannot be pickled in Python versions + :py:class:`~uproot4.model.Model` classes cannot be pickled in Python versions before 3.7. """ @@ -916,20 +916,20 @@ def __setstate__(self, state): class DispatchByVersion(object): """ A Python class that models all versions of a ROOT C++ class by maintaining - a dict of :doc:`uproot4.model.VersionedModel` classes. + a dict of :py:class:`~uproot4.model.VersionedModel` classes. - The :doc:`uproot4.model.DispatchByVersion.read` classmethod reads the + The :py:meth:`~uproot4.model.DispatchByVersion.read` classmethod reads the instance version number from the byte stream, backs up the - :doc:`uproot4.source.cursor.Cursor` to the starting position, and invokes - the appropriate :doc:`uproot4.model.VersionedModel`'s ``read`` classmethod. + :py:class:`~uproot4.source.cursor.Cursor` to the starting position, and invokes + the appropriate :py:class:`~uproot4.model.VersionedModel`'s ``read`` classmethod. - If a :doc:`uproot4.model.VersionedModel` does not exist for the specified + If a :py:class:`~uproot4.model.VersionedModel` does not exist for the specified version, the ``file``'s ``TStreamerInfo`` is queried to attempt to create - one, and failing that, an :doc:`uproot4.model.UnknownClassVersion` is + one, and failing that, an :py:exc:`~uproot4.model.UnknownClassVersion` is created instead. - Note that :doc:`uproot4.model.DispatchByVersion` is not a subclass of - :doc:`uproot4.model.Model`. Instances of this class are not usable as + Note that :py:class:`~uproot4.model.DispatchByVersion` is not a subclass of + :py:class:`~uproot4.model.Model`. Instances of this class are not usable as stand-ins for ROOT data. """ @@ -937,10 +937,10 @@ class DispatchByVersion(object): def awkward_form(cls, file, index_format="i64", header=False, tobject_header=True): """ Args: - cls (subclass of :doc:`uproot4.model.DispatchByVersion`): This class. - file (:doc:`uproot4.reading.ReadOnlyFile`): File to use to generate - :doc:`uproot4.model.Model` classes from its - :doc:`uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` + cls (subclass of :py:class:`~uproot4.model.DispatchByVersion`): This class. + file (:py:class:`~uproot4.reading.ReadOnlyFile`): File to use to generate + :py:class:`~uproot4.model.Model` classes from its + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` for error messages. index_format (str): Format to use for indexes of the ``awkward1.forms.Form``; may be ``"i32"``, ``"u32"``, or @@ -962,18 +962,18 @@ def strided_interpretation( ): """ Args: - cls (subclass of :doc:`uproot4.model.DispatchByVersion`): This class. - file (:doc:`uproot4.reading.ReadOnlyFile`): File to use to generate - :doc:`uproot4.model.Model` classes from its - :doc:`uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` + cls (subclass of :py:class:`~uproot4.model.DispatchByVersion`): This class. + file (:py:class:`~uproot4.reading.ReadOnlyFile`): File to use to generate + :py:class:`~uproot4.model.Model` classes from its + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` for error messages. header (bool): If True, assume the outermost object has a header. tobject_header (bool): If True, assume that ``TObjects`` have headers. - original (None, :doc:`uproot4.model.Model`, or :doc:`uproot4.containers.Container`): The + original (None, :py:class:`~uproot4.model.Model`, or :py:class:`~uproot4.containers.Container`): The original, non-strided model or container. Returns a list of (str, ``numpy.dtype``) pairs to build a - :doc:`uproot4.interpretation.objects.AsStridedObjects` interpretation. + :py:class:`~uproot4.interpretation.objects.AsStridedObjects` interpretation. """ versioned_cls = file.class_named(classname_decode(cls.__name__)[0], "max") return versioned_cls.strided_interpretation( @@ -1004,11 +1004,11 @@ def new_class(cls, file, version): Uses ``file`` to create a new class for a specified ``version``. As a side-effect, this new class is added to ``cls.known_versions`` - (for :doc:`uproot4.model.class_of_version` and - :doc:`uproot4.model.has_version`). + (for :py:func:`~uproot4.model.class_of_version` and + :py:func:`~uproot4.model.has_version`). If the ``file`` lacks a ``TStreamerInfo`` for the class, this function - returns a :doc:`uproot4.model.UnknownClassVersion` (adding it to + returns a :py:exc:`~uproot4.model.UnknownClassVersion` (adding it to ``uproo4.unknown_classes`` if it's not already there). """ classname, _ = classname_decode(cls.__name__) @@ -1038,33 +1038,33 @@ def new_class(cls, file, version): def read(cls, chunk, cursor, context, file, selffile, parent, concrete=None): """ Args: - cls (subclass of :doc:`uproot4.model.DispatchByVersion`): This class. - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. - cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in + cls (subclass of :py:class:`~uproot4.model.DispatchByVersion`): This class. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. + cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in that ``chunk``. context (dict): Auxiliary data used in deserialization. - file (:doc:`uproot4.reading.ReadOnlyFile`): An open file object, - capable of generating new :doc:`uproot4.model.Model` classes - from its :doc:`uproot4.reading.ReadOnlyFile.streamers`. - selffile (:doc:`uproot4.reading.CommonFileMethods`): A possibly - :doc:`uproot4.reading.DetachedFile` associated with this object. + file (:py:class:`~uproot4.reading.ReadOnlyFile`): An open file object, + capable of generating new :py:class:`~uproot4.model.Model` classes + from its :py:attr:`~uproot4.reading.ReadOnlyFile.streamers`. + selffile (:py:class:`~uproot4.reading.CommonFileMethods`): A possibly + :py:class:`~uproot4.reading.DetachedFile` associated with this object. parent (None or calling object): The previous ``read`` in the recursive descent. - concrete (None or :doc:`uproot4.model.Model` instance): If None, + concrete (None or :py:class:`~uproot4.model.Model` instance): If None, this model corresponds to the concrete (instantiated) class in C++. Otherwise, this model represents a superclass part of the object, and ``concrete`` points to the concrete instance. Reads the instance version number from the byte stream, backs up the - :doc:`uproot4.source.cursor.Cursor` to the starting position, and - invokes the appropriate :doc:`uproot4.model.VersionedModel`'s ``read`` + :py:class:`~uproot4.source.cursor.Cursor` to the starting position, and + invokes the appropriate :py:class:`~uproot4.model.VersionedModel`'s ``read`` classmethod. - If a :doc:`uproot4.model.VersionedModel` does not exist for the + If a :py:class:`~uproot4.model.VersionedModel` does not exist for the specified version, the ``file``'s ``TStreamerInfo`` is queried to attempt to create one, and failing that, an - :doc:`uproot4.model.UnknownClassVersion` is created instead. + :py:class:`~uproot4.model.UnknownClassVersion` is created instead. """ import uproot4.deserialization @@ -1108,28 +1108,28 @@ def read(cls, chunk, cursor, context, file, selffile, parent, concrete=None): def postprocess(cls, self, chunk, cursor, context, file): """ Args: - cls (subclass of :doc:`uproot4.model.DispatchByVersion`): This class. - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. - cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in + cls (subclass of :py:class:`~uproot4.model.DispatchByVersion`): This class. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. + cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in that ``chunk``. context (dict): Auxiliary data used in deserialization. - file (:doc:`uproot4.reading.ReadOnlyFile`): An open file object, - capable of generating new :doc:`uproot4.model.Model` classes - from its :doc:`uproot4.reading.ReadOnlyFile.streamers`. + file (:py:class:`~uproot4.reading.ReadOnlyFile`): An open file object, + capable of generating new :py:class:`~uproot4.model.Model` classes + from its :py:attr:`~uproot4.reading.ReadOnlyFile.streamers`. Called for any additional processing after the object has been fully read. The return value from this method is the object that actually represents the ROOT data, which might be a different instance or even a different - type from this class. The default in :doc:`uproot4.model.Model` is to + type from this class. The default in :py:class:`~uproot4.model.Model` is to return ``self``. Note that for versioned models, - :doc:`uproot4.model.VersionedModel.postprocess` is called first, then - :doc:`uproot4.model.DispatchByVersion.postprocess` is called on its - output, allowing a :doc:`uproot4.model.DispatchByVersion` to refine all + :py:meth:`~uproot4.model.VersionedModel.postprocess` is called first, then + :py:meth:`~uproot4.model.DispatchByVersion.postprocess` is called on its + output, allowing a :py:class:`~uproot4.model.DispatchByVersion` to refine all data of its type, regardless of version. """ return self @@ -1138,8 +1138,8 @@ def postprocess(cls, self, chunk, cursor, context, file): class UnknownClass(Model): """ Placeholder for a C++ class instance that has no - :doc:`uproot4.model.DispatchByVersion` and no ``TStreamerInfo`` in the - current :doc:`uproot4.reading.ReadOnlyFile` to produce one. + :py:class:`~uproot4.model.DispatchByVersion` and no ``TStreamerInfo`` in the + current :py:class:`~uproot4.reading.ReadOnlyFile` to produce one. """ @property @@ -1147,10 +1147,10 @@ def chunk(self): """ The ``chunk`` of data associated with the unknown class, referred to by a weak reference (to avoid memory leaks in - :doc:`uproot4.model.UnknownClass` objects). If the original ``chunk`` + :py:exc:`~uproot4.model.UnknownClass` objects). If the original ``chunk`` has been garbage-collected, this raises ``RuntimeError``. - Primarily useful in the :doc:`uproot4.model.UnknownClass.debug` method. + Primarily useful in the :py:meth:`~uproot4.model.UnknownClass.debug` method. """ chunk = self._chunk() if chunk is None: @@ -1165,7 +1165,7 @@ def context(self): """ The auxiliary data used in deserialization. - Primarily useful in the :doc:`uproot4.model.UnknownClass.debug` method. + Primarily useful in the :py:meth:`~uproot4.model.UnknownClass.debug` method. """ return self._context @@ -1178,15 +1178,15 @@ def debug( """ Args: skip_bytes (int): Number of bytes to skip before presenting the - remainder of the :doc:`uproot4.source.chunk.Chunk`. May be + remainder of the :py:class:`~uproot4.source.chunk.Chunk`. May be negative, to examine the byte stream leading up to the attempted instantiation. The default, ``0``, starts where the number of bytes and version number would be (just before - :doc:`uproot4.model.Model.read_numbytes_version`). + :py:meth:`~uproot4.model.Model.read_numbytes_version`). limit_bytes (None or int): Number of bytes to limit the output to. A line of debugging output (without any ``offset``) is 20 bytes, so multiples of 20 show full lines. If None, everything is - shown to the end of the :doc:`uproot4.source.chunk.Chunk`, + shown to the end of the :py:class:`~uproot4.source.chunk.Chunk`, which might be large. dtype (None, ``numpy.dtype``, or its constructor argument): If None, present only the bytes as decimal values (0-255). Otherwise, @@ -1205,7 +1205,7 @@ def debug( Example output with ``dtype=">f4"`` and ``offset=3``. - .. code-block:: raw + .. code-block:: --+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+- 123 123 123 63 140 204 205 64 12 204 205 64 83 51 51 64 140 204 205 64 @@ -1235,16 +1235,16 @@ def debug_array(self, skip_bytes=0, dtype=numpy.dtype("u1")): """ Args: skip_bytes (int): Number of bytes to skip before presenting the - remainder of the :doc:`uproot4.source.chunk.Chunk`. May be + remainder of the :py:class:`~uproot4.source.chunk.Chunk`. May be negative, to examine the byte stream leading up to the attempted instantiation. The default, ``0``, starts where the number of bytes and version number would be (just before - :doc:`uproot4.model.Model.read_numbytes_version`). + :py:meth:`~uproot4.model.Model.read_numbytes_version`). dtype (``numpy.dtype`` or its constructor argument): Data type in which to interpret the data. (The size of the array returned is truncated to this ``dtype.itemsize``.) - Like :doc:`uproot4.model.UnknownClass.debug`, but returns a NumPy array + Like :py:meth:`~uproot4.model.UnknownClass.debug`, but returns a NumPy array for further inspection. """ dtype = numpy.dtype(dtype) @@ -1273,7 +1273,7 @@ def read_members(self, chunk, cursor, context, file): class UnknownClassVersion(VersionedModel): """ Placeholder for a C++ class instance that has no ``TStreamerInfo`` in the - current :doc:`uproot4.reading.ReadOnlyFile` to produce one. + current :py:class:`~uproot4.reading.ReadOnlyFile` to produce one. """ @property @@ -1281,10 +1281,10 @@ def chunk(self): """ The ``chunk`` of data associated with the class of unknown version, referred to by a weak reference (to avoid memory leaks in - :doc:`uproot4.model.UnknownClassVersion` objects). If the original + :py:class:`~uproot4.model.UnknownClassVersion` objects). If the original ``chunk`` has been garbage-collected, this raises ``RuntimeError``. - Primarily useful in the :doc:`uproot4.model.UnknownClassVersion.debug` + Primarily useful in the :py:meth:`~uproot4.model.UnknownClassVersion.debug` method. """ chunk = self._chunk() @@ -1301,7 +1301,7 @@ def context(self): """ The auxiliary data used in deserialization. - Primarily useful in the :doc:`uproot4.model.UnknownClass.debug` method. + Primarily useful in the :py:meth:`~uproot4.model.UnknownClass.debug` method. """ return self._context @@ -1311,15 +1311,15 @@ def debug( """ Args: skip_bytes (int): Number of bytes to skip before presenting the - remainder of the :doc:`uproot4.source.chunk.Chunk`. May be + remainder of the :py:class:`~uproot4.source.chunk.Chunk`. May be negative, to examine the byte stream leading up to the attempted instantiation. The default, ``0``, starts where the number of bytes and version number would be (just before - :doc:`uproot4.model.Model.read_numbytes_version`). + :py:meth:`~uproot4.model.Model.read_numbytes_version`). limit_bytes (None or int): Number of bytes to limit the output to. A line of debugging output (without any ``offset``) is 20 bytes, so multiples of 20 show full lines. If None, everything is - shown to the end of the :doc:`uproot4.source.chunk.Chunk`, + shown to the end of the :py:class:`~uproot4.source.chunk.Chunk`, which might be large. dtype (None, ``numpy.dtype``, or its constructor argument): If None, present only the bytes as decimal values (0-255). Otherwise, @@ -1338,7 +1338,7 @@ def debug( Example output with ``dtype=">f4"`` and ``offset=3``. - .. code-block:: raw + .. code-block:: --+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+- 123 123 123 63 140 204 205 64 12 204 205 64 83 51 51 64 140 204 205 64 @@ -1368,16 +1368,16 @@ def debug_array(self, skip_bytes=0, dtype=numpy.dtype("u1")): """ Args: skip_bytes (int): Number of bytes to skip before presenting the - remainder of the :doc:`uproot4.source.chunk.Chunk`. May be + remainder of the :py:class:`~uproot4.source.chunk.Chunk`. May be negative, to examine the byte stream leading up to the attempted instantiation. The default, ``0``, starts where the number of bytes and version number would be (just before - :doc:`uproot4.model.Model.read_numbytes_version`). + :py:meth:`~uproot4.model.Model.read_numbytes_version`). dtype (``numpy.dtype`` or its constructor argument): Data type in which to interpret the data. (The size of the array returned is truncated to this ``dtype.itemsize``.) - Like :doc:`uproot4.model.UnknownClassVersion.debug`, but returns a + Like :py:meth:`~uproot4.model.UnknownClassVersion.debug`, but returns a NumPy array for further inspection. """ dtype = numpy.dtype(dtype) @@ -1410,11 +1410,11 @@ def __repr__(self): class DynamicModel(VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` subclass generated by any attempt to + A :py:class:`~uproot4.model.VersionedModel` subclass generated by any attempt to extract it from the ``uproot4.dynamic`` namespace in Python 3.7 and later. This dynamically generated model allows ROOT object types without predefined - :doc:`uproot4.model.Model` classes to be pickled in Python 3.7 and later. + :py:class:`~uproot4.model.Model` classes to be pickled in Python 3.7 and later. """ def __setstate__(self, state): diff --git a/uproot4/models/RNTuple.py b/uproot4/models/RNTuple.py index 527aa82f5..beaf199f5 100644 --- a/uproot4/models/RNTuple.py +++ b/uproot4/models/RNTuple.py @@ -17,7 +17,7 @@ class Model_ROOT_3a3a_Experimental_3a3a_RNTuple(uproot4.model.Model): """ - A versionless :doc:`uproot4.model.Model` for ``ROOT::Experimental::RNTuple``. + A versionless :py:class:`~uproot4.model.Model` for ``ROOT::Experimental::RNTuple``. """ def read_members(self, chunk, cursor, context, file): diff --git a/uproot4/models/TArray.py b/uproot4/models/TArray.py index 431a0545d..471db2052 100644 --- a/uproot4/models/TArray.py +++ b/uproot4/models/TArray.py @@ -24,7 +24,7 @@ class Model_TArray(uproot4.model.Model, Sequence): """ - A versionless :doc:`uproot4.model.Model` for ``TArray`` and its subclasses. + A versionless :py:class:`~uproot4.model.Model` for ``TArray`` and its subclasses. These also satisfy Python's abstract ``Sequence`` protocol. """ @@ -95,7 +95,7 @@ def awkward_form(cls, file, index_format="i64", header=False, tobject_header=Tru class Model_TArrayC(Model_TArray): """ - A versionless :doc:`uproot4.model.Model` for ``TArrayC`` + A versionless :py:class:`~uproot4.model.Model` for ``TArrayC`` (``dtype(">i1")``). It also satisfies Python's abstract ``Sequence`` protocol. @@ -106,7 +106,7 @@ class Model_TArrayC(Model_TArray): class Model_TArrayS(Model_TArray): """ - A versionless :doc:`uproot4.model.Model` for ``TArrayS`` + A versionless :py:class:`~uproot4.model.Model` for ``TArrayS`` (``dtype(">i2")``). It also satisfies Python's abstract ``Sequence`` protocol. @@ -117,7 +117,7 @@ class Model_TArrayS(Model_TArray): class Model_TArrayI(Model_TArray): """ - A versionless :doc:`uproot4.model.Model` for ``TArrayI`` + A versionless :py:class:`~uproot4.model.Model` for ``TArrayI`` (``dtype(">i4")``). It also satisfies Python's abstract ``Sequence`` protocol. @@ -128,7 +128,7 @@ class Model_TArrayI(Model_TArray): class Model_TArrayL(Model_TArray): """ - A versionless :doc:`uproot4.model.Model` for ``TArrayL`` + A versionless :py:class:`~uproot4.model.Model` for ``TArrayL`` (``dtype(">i8")``). It also satisfies Python's abstract ``Sequence`` protocol. @@ -139,7 +139,7 @@ class Model_TArrayL(Model_TArray): class Model_TArrayL64(Model_TArray): """ - A versionless :doc:`uproot4.model.Model` for ``TArrayL64`` + A versionless :py:class:`~uproot4.model.Model` for ``TArrayL64`` (``dtype(">i8")``). It also satisfies Python's abstract ``Sequence`` protocol. @@ -150,7 +150,7 @@ class Model_TArrayL64(Model_TArray): class Model_TArrayF(Model_TArray): """ - A versionless :doc:`uproot4.model.Model` for ``TArrayF`` + A versionless :py:class:`~uproot4.model.Model` for ``TArrayF`` (``dtype(">f4")``). It also satisfies Python's abstract ``Sequence`` protocol. @@ -161,7 +161,7 @@ class Model_TArrayF(Model_TArray): class Model_TArrayD(Model_TArray): """ - A versionless :doc:`uproot4.model.Model` for ``TArrayD`` + A versionless :py:class:`~uproot4.model.Model` for ``TArrayD`` (``dtype(">f8")``). It also satisfies Python's abstract ``Sequence`` protocol. diff --git a/uproot4/models/TAtt.py b/uproot4/models/TAtt.py index 42c6b944d..9efb026cf 100644 --- a/uproot4/models/TAtt.py +++ b/uproot4/models/TAtt.py @@ -19,7 +19,7 @@ class Model_TAttLine_v1(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TAttLine`` version 1. + A :py:class:`~uproot4.model.VersionedModel` for ``TAttLine`` version 1. """ def read_members(self, chunk, cursor, context, file): @@ -84,7 +84,7 @@ def awkward_form(cls, file, index_format="i64", header=False, tobject_header=Tru class Model_TAttLine_v2(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TAttLine`` version 2. + A :py:class:`~uproot4.model.VersionedModel` for ``TAttLine`` version 2. """ def read_members(self, chunk, cursor, context, file): @@ -149,7 +149,7 @@ def awkward_form(cls, file, index_format="i64", header=False, tobject_header=Tru class Model_TAttLine(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TAttLine``. + A :py:class:`~uproot4.model.DispatchByVersion` for ``TAttLine``. """ known_versions = {1: Model_TAttLine_v1, 2: Model_TAttLine_v2} @@ -161,7 +161,7 @@ class Model_TAttLine(uproot4.model.DispatchByVersion): class Model_TAttFill_v1(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TAttFill`` version 1. + A :py:class:`~uproot4.model.VersionedModel` for ``TAttFill`` version 1. """ def read_members(self, chunk, cursor, context, file): @@ -220,7 +220,7 @@ def awkward_form(cls, file, index_format="i64", header=False, tobject_header=Tru class Model_TAttFill_v2(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TAttFill`` version 2. + A :py:class:`~uproot4.model.VersionedModel` for ``TAttFill`` version 2. """ def read_members(self, chunk, cursor, context, file): @@ -279,7 +279,7 @@ def awkward_form(cls, file, index_format="i64", header=False, tobject_header=Tru class Model_TAttFill(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TAttFill``. + A :py:class:`~uproot4.model.DispatchByVersion` for ``TAttFill``. """ known_versions = {1: Model_TAttFill_v1, 2: Model_TAttFill_v2} @@ -290,7 +290,7 @@ class Model_TAttFill(uproot4.model.DispatchByVersion): class Model_TAttMarker_v2(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TAttMarker`` version 2. + A :py:class:`~uproot4.model.VersionedModel` for ``TAttMarker`` version 2. """ def read_members(self, chunk, cursor, context, file): @@ -355,7 +355,7 @@ def awkward_form(cls, file, index_format="i64", header=False, tobject_header=Tru class Model_TAttMarker(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TAttMarker``. + A :py:class:`~uproot4.model.DispatchByVersion` for ``TAttMarker``. """ known_versions = {2: Model_TAttMarker_v2} diff --git a/uproot4/models/TBasket.py b/uproot4/models/TBasket.py index b2a243b07..80024dee5 100644 --- a/uproot4/models/TBasket.py +++ b/uproot4/models/TBasket.py @@ -28,7 +28,7 @@ class Model_TBasket(uproot4.model.Model): """ - A versionless :doc:`uproot4.model.Model` for ``TBasket``. + A versionless :py:class:`~uproot4.model.Model` for ``TBasket``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -48,7 +48,7 @@ def raw_data(self): content with entry offsets, if the latter exists. If there are no entry offsets, this is identical to - :doc:`uproot4.models.TBasket.TBasket.data`. + :py:attr:`~uproot4.models.TBasket.TBasket.data`. """ return self._raw_data @@ -59,7 +59,7 @@ def data(self): entry offsets, if they exist. If there are no entry offsets, this is identical to - :doc:`uproot4.models.TBasket.TBasket.raw_data`. + :py:attr:`~uproot4.models.TBasket.TBasket.raw_data`. """ return self._data @@ -67,19 +67,19 @@ def data(self): def byte_offsets(self): """ The index where each entry starts and stops in the - :doc:`uproot4.models.TBasket.TBasket.data`, not including header. + :py:attr:`~uproot4.models.TBasket.TBasket.data`, not including header. The first offset is ``0`` and the number of offsets is one greater than the number of entries, such that the last offset is the length of - :doc:`uproot4.models.TBasket.TBasket.data`. + :py:attr:`~uproot4.models.TBasket.TBasket.data`. """ return self._byte_offsets def array(self, interpretation=None, library="ak"): """ The ``TBasket`` data and entry offsets as an array, given an - :doc:`uproot4.interpretation.Interpretation` (or the ``TBranch`` parent's - :doc:`uproot4.behaviors.TBranch.TBranch.interpretation`) and a + :py:class:`~uproot4.interpretation.Interpretation` (or the ``TBranch`` parent's + :py:class:`~uproot4.behaviors.TBranch.TBranch.interpretation`) and a ``library``. """ if interpretation is None: @@ -109,9 +109,10 @@ def array(self, interpretation=None, library="ak"): def counts(self): """ The number of items in each entry as a NumPy array, derived from the - parent ``TBranch``'s :doc:`uproot4.behavior.TBranch.TBranch.count_branch`. - If there is no such branch (e.g. the data are ``std::vector``), then - this method returns None. + parent ``TBranch``'s + :py:attr:`~uproot4.behavior.TBranch.TBranch.count_branch`. If there is + no such branch (e.g. the data are ``std::vector``), then this method + returns None. """ count_branch = self._parent.count_branch if count_branch is not None: @@ -163,7 +164,7 @@ def uncompressed_bytes(self): The number of bytes for the uncompressed data, not including the header. If the ``TBasket`` is uncompressed, this is equal to - :doc:`uproot4.models.TBasket.TBasket.compressed_bytes`. + :py:attr:`~uproot4.models.TBasket.TBasket.compressed_bytes`. """ if self.is_embedded: if self._byte_offsets is None: @@ -180,7 +181,7 @@ def compressed_bytes(self): (which is always uncompressed). If the ``TBasket`` is uncompressed, this is equal to - :doc:`uproot4.models.TBasket.TBasket.uncompressed_bytes`. + :py:attr:`~uproot4.models.TBasket.TBasket.uncompressed_bytes`. """ if self.is_embedded: if self._byte_offsets is None: diff --git a/uproot4/models/TBranch.py b/uproot4/models/TBranch.py index f13c56850..5eb851884 100644 --- a/uproot4/models/TBranch.py +++ b/uproot4/models/TBranch.py @@ -3,7 +3,7 @@ """ Defines versioned models for ``TBranch`` and its subclasses. -See :doc:`uproot4.behaviors.TBranch` for definitions of ``TTree``-reading +See :py:class:`~uproot4.behaviors.TBranch` for definitions of ``TTree``-reading functions. """ @@ -28,7 +28,7 @@ class Model_TBranch_v10( uproot4.behaviors.TBranch.TBranch, uproot4.model.VersionedModel ): """ - A :doc:`uproot4.model.VersionedModel` for ``TBranch`` version 10. + A :py:class:`~uproot4.model.VersionedModel` for ``TBranch`` version 10. """ def read_members(self, chunk, cursor, context, file): @@ -158,7 +158,7 @@ class Model_TBranch_v11( uproot4.behaviors.TBranch.TBranch, uproot4.model.VersionedModel ): """ - A :doc:`uproot4.model.VersionedModel` for ``TBranch`` version 11. + A :py:class:`~uproot4.model.VersionedModel` for ``TBranch`` version 11. """ def read_members(self, chunk, cursor, context, file): @@ -290,7 +290,7 @@ class Model_TBranch_v12( uproot4.behaviors.TBranch.TBranch, uproot4.model.VersionedModel ): """ - A :doc:`uproot4.model.VersionedModel` for ``TBranch`` version 12. + A :py:class:`~uproot4.model.VersionedModel` for ``TBranch`` version 12. """ def read_members(self, chunk, cursor, context, file): @@ -423,7 +423,7 @@ class Model_TBranch_v13( uproot4.behaviors.TBranch.TBranch, uproot4.model.VersionedModel ): """ - A :doc:`uproot4.model.VersionedModel` for ``TBranch`` version 13. + A :py:class:`~uproot4.model.VersionedModel` for ``TBranch`` version 13. """ def read_members(self, chunk, cursor, context, file): @@ -553,7 +553,7 @@ def member_names(self): class Model_TBranch(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TBranch``. + A :py:class:`~uproot4.model.DispatchByVersion` for ``TBranch``. """ known_versions = { @@ -571,7 +571,7 @@ class Model_TBranchElement_v8( uproot4.behaviors.TBranch.TBranch, uproot4.model.VersionedModel ): """ - A :doc:`uproot4.model.VersionedModel` for ``TBranchElement`` version 8. + A :py:class:`~uproot4.model.VersionedModel` for ``TBranchElement`` version 8. """ def read_members(self, chunk, cursor, context, file): @@ -643,7 +643,7 @@ class Model_TBranchElement_v9( uproot4.behaviors.TBranch.TBranch, uproot4.model.VersionedModel ): """ - A :doc:`uproot4.model.VersionedModel` for ``TBranchElement`` version 9. + A :py:class:`~uproot4.model.VersionedModel` for ``TBranchElement`` version 9. """ def read_members(self, chunk, cursor, context, file): @@ -715,7 +715,7 @@ class Model_TBranchElement_v10( uproot4.behaviors.TBranch.TBranch, uproot4.model.VersionedModel ): """ - A :doc:`uproot4.model.VersionedModel` for ``TBranchElement`` version 10. + A :py:class:`~uproot4.model.VersionedModel` for ``TBranchElement`` version 10. """ def read_members(self, chunk, cursor, context, file): @@ -782,7 +782,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TBranchElement(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TBranchElement``. + A :py:class:`~uproot4.model.DispatchByVersion` for ``TBranchElement``. """ known_versions = { @@ -796,7 +796,7 @@ class Model_TBranchObject_v1( uproot4.behaviors.TBranch.TBranch, uproot4.model.VersionedModel ): """ - A :doc:`uproot4.model.VersionedModel` for ``TBranchObject`` version 1. + A :py:class:`~uproot4.model.VersionedModel` for ``TBranchObject`` version 1. """ def read_members(self, chunk, cursor, context, file): @@ -829,7 +829,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TBranchObject(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TBranchObject``. + A :py:class:`~uproot4.model.DispatchByVersion` for ``TBranchObject``. """ known_versions = { diff --git a/uproot4/models/THashList.py b/uproot4/models/THashList.py index 632fb367c..7b9a17227 100644 --- a/uproot4/models/THashList.py +++ b/uproot4/models/THashList.py @@ -11,7 +11,7 @@ class Model_THashList(uproot4.model.Model): """ - A versionless :doc:`uproot4.model.Model` for ``THashList``. + A versionless :py:class:`~uproot4.model.Model` for ``THashList``. """ def read_numbytes_version(self, chunk, cursor, context): diff --git a/uproot4/models/TLeaf.py b/uproot4/models/TLeaf.py index b2e942611..095591cb1 100644 --- a/uproot4/models/TLeaf.py +++ b/uproot4/models/TLeaf.py @@ -17,7 +17,7 @@ class Model_TLeaf_v2(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TLeaf`` version 2. + A :py:class:`~uproot4.model.VersionedModel` for ``TLeaf`` version 2. """ def read_members(self, chunk, cursor, context, file): @@ -65,7 +65,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TLeaf(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TLeaf``. + A :py:class:`~uproot4.model.DispatchByVersion` for ``TLeaf``. """ known_versions = {2: Model_TLeaf_v2} @@ -76,7 +76,7 @@ class Model_TLeaf(uproot4.model.DispatchByVersion): class Model_TLeafO_v1(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TLeafO`` version 1 + A :py:class:`~uproot4.model.VersionedModel` for ``TLeafO`` version 1 (``numpy.bool_``). """ @@ -111,7 +111,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TLeafO(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TLeafO`` (``numpy.bool_``). + A :py:class:`~uproot4.model.DispatchByVersion` for ``TLeafO`` (``numpy.bool_``). """ known_versions = {1: Model_TLeafO_v1} @@ -122,7 +122,7 @@ class Model_TLeafO(uproot4.model.DispatchByVersion): class Model_TLeafB_v1(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TLeafB`` version 1 + A :py:class:`~uproot4.model.VersionedModel` for ``TLeafB`` version 1 (``numpy.int8``). """ @@ -157,7 +157,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TLeafB(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TLeafB`` (``numpy.int8``). + A :py:class:`~uproot4.model.DispatchByVersion` for ``TLeafB`` (``numpy.int8``). """ known_versions = {1: Model_TLeafB_v1} @@ -168,7 +168,7 @@ class Model_TLeafB(uproot4.model.DispatchByVersion): class Model_TLeafS_v1(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TLeafS`` version 1 + A :py:class:`~uproot4.model.VersionedModel` for ``TLeafS`` version 1 (``numpy.int16``). """ @@ -203,7 +203,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TLeafS(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TLeafS`` (``numpy.int16``). + A :py:class:`~uproot4.model.DispatchByVersion` for ``TLeafS`` (``numpy.int16``). """ known_versions = {1: Model_TLeafS_v1} @@ -214,7 +214,7 @@ class Model_TLeafS(uproot4.model.DispatchByVersion): class Model_TLeafI_v1(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TLeafI`` version 1 + A :py:class:`~uproot4.model.VersionedModel` for ``TLeafI`` version 1 (``numpy.int32``). """ @@ -249,7 +249,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TLeafI(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TLeafI`` (``numpy.int32``). + A :py:class:`~uproot4.model.DispatchByVersion` for ``TLeafI`` (``numpy.int32``). """ known_versions = {1: Model_TLeafI_v1} @@ -260,7 +260,7 @@ class Model_TLeafI(uproot4.model.DispatchByVersion): class Model_TLeafL_v1(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TLeafL`` version 1 + A :py:class:`~uproot4.model.VersionedModel` for ``TLeafL`` version 1 (``numpy.int64``). """ @@ -295,7 +295,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TLeafL(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByversion` for ``TLeafL`` (``numpy.int64``). + A :py:class:`~uproot4.model.DispatchByversion` for ``TLeafL`` (``numpy.int64``). """ known_versions = {1: Model_TLeafL_v1} @@ -306,7 +306,7 @@ class Model_TLeafL(uproot4.model.DispatchByVersion): class Model_TLeafF_v1(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TLeafF`` version 1 + A :py:class:`~uproot4.model.VersionedModel` for ``TLeafF`` version 1 (``numpy.float32``). """ @@ -341,7 +341,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TLeafF(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TLeafF`` (``numpy.float32``). + A :py:class:`~uproot4.model.DispatchByVersion` for ``TLeafF`` (``numpy.float32``). """ known_versions = {1: Model_TLeafF_v1} @@ -352,7 +352,7 @@ class Model_TLeafF(uproot4.model.DispatchByVersion): class Model_TLeafD_v1(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TLeafD`` version 1 + A :py:class:`~uproot4.model.VersionedModel` for ``TLeafD`` version 1 (``numpy.float64``). """ @@ -387,7 +387,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TLeafD(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TLeafD`` (``numpy.float64``). + A :py:class:`~uproot4.model.DispatchByVersion` for ``TLeafD`` (``numpy.float64``). """ known_versions = {1: Model_TLeafD_v1} @@ -398,7 +398,7 @@ class Model_TLeafD(uproot4.model.DispatchByVersion): class Model_TLeafC_v1(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TLeafC`` version 1 + A :py:class:`~uproot4.model.VersionedModel` for ``TLeafC`` version 1 (variable-length strings). """ @@ -433,7 +433,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TLeafC(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TLeafC`` (variable-length + A :py:class:`~uproot4.model.DispatchByVersion` for ``TLeafC`` (variable-length strings). """ @@ -442,7 +442,7 @@ class Model_TLeafC(uproot4.model.DispatchByVersion): class Model_TLeafF16_v1(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TLeafF16`` version 1 + A :py:class:`~uproot4.model.VersionedModel` for ``TLeafF16`` version 1 (ROOT's ``Float16_t``). """ @@ -475,7 +475,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TLeafF16(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TLeafF16`` (ROOT's + A :py:class:`~uproot4.model.DispatchByVersion` for ``TLeafF16`` (ROOT's ``Float16_t``). """ @@ -484,7 +484,7 @@ class Model_TLeafF16(uproot4.model.DispatchByVersion): class Model_TLeafD32_v1(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TLeafD32`` version 1 + A :py:class:`~uproot4.model.VersionedModel` for ``TLeafD32`` version 1 (ROOT's ``Double32_t``). """ @@ -517,7 +517,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TLeafD32(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TLeafD32`` (ROOT's + A :py:class:`~uproot4.model.DispatchByVersion` for ``TLeafD32`` (ROOT's ``Double32_t``). """ @@ -529,7 +529,7 @@ class Model_TLeafD32(uproot4.model.DispatchByVersion): class Model_TLeafElement_v1(uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TLeafElement`` version 1 + A :py:class:`~uproot4.model.VersionedModel` for ``TLeafElement`` version 1 (arbitrary objects, associated with ``TBranchElement``). """ @@ -564,7 +564,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TLeafElement(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TLeafElement`` + A :py:class:`~uproot4.model.DispatchByVersion` for ``TLeafElement`` (arbitrary objects, associated with ``TBranchElement``). """ diff --git a/uproot4/models/TList.py b/uproot4/models/TList.py index ea29e926d..9cfc35636 100644 --- a/uproot4/models/TList.py +++ b/uproot4/models/TList.py @@ -24,7 +24,7 @@ class Model_TList(uproot4.model.Model, Sequence): """ - A versionless :doc:`uproot4.model.Model` for ``TList``. + A versionless :py:class:`~uproot4.model.Model` for ``TList``. """ def read_members(self, chunk, cursor, context, file): diff --git a/uproot4/models/TNamed.py b/uproot4/models/TNamed.py index 7316e48e6..7f3a7cc2f 100644 --- a/uproot4/models/TNamed.py +++ b/uproot4/models/TNamed.py @@ -15,7 +15,7 @@ class Model_TNamed(uproot4.model.Model): """ - A versionless :doc:`uproot4.model.Model` for ``TNamed``. + A versionless :py:class:`~uproot4.model.Model` for ``TNamed``. """ def read_members(self, chunk, cursor, context, file): diff --git a/uproot4/models/TObjArray.py b/uproot4/models/TObjArray.py index 7e53efac5..06130ce06 100644 --- a/uproot4/models/TObjArray.py +++ b/uproot4/models/TObjArray.py @@ -24,7 +24,7 @@ class Model_TObjArray(uproot4.model.Model, Sequence): """ - A versionless :doc:`uproot4.model.Model` for ``TObjArray``. + A versionless :py:class:`~uproot4.model.Model` for ``TObjArray``. This also satisfies Python's abstract ``Sequence`` protocol. """ @@ -88,7 +88,7 @@ def tojson(self): class Model_TObjArrayOfTBaskets(Model_TObjArray): """ - A specialized :doc:`uproot4.model.Model` for a ``TObjArray`` of ``TBaskets``. + A specialized :py:class:`~uproot4.model.Model` for a ``TObjArray`` of ``TBaskets``. """ def read_members(self, chunk, cursor, context, file): diff --git a/uproot4/models/TObjString.py b/uproot4/models/TObjString.py index 8db43be12..4d37fac2d 100644 --- a/uproot4/models/TObjString.py +++ b/uproot4/models/TObjString.py @@ -12,7 +12,7 @@ class Model_TObjString(uproot4.model.Model, str): """ - A versionless :doc:`uproot4.model.Model` for ``TObjString``. + A versionless :py:class:`~uproot4.model.Model` for ``TObjString``. This is also a Python ``str`` (string). """ diff --git a/uproot4/models/TObject.py b/uproot4/models/TObject.py index 995d5e2af..23cc2f5fb 100644 --- a/uproot4/models/TObject.py +++ b/uproot4/models/TObject.py @@ -20,7 +20,7 @@ class Model_TObject(uproot4.model.Model): """ - A versionless :doc:`uproot4.model.Model` for ``TObject``. + A versionless :py:class:`~uproot4.model.Model` for ``TObject``. """ def read_numbytes_version(self, chunk, cursor, context): diff --git a/uproot4/models/TRef.py b/uproot4/models/TRef.py index bc078f8f5..7768334a7 100644 --- a/uproot4/models/TRef.py +++ b/uproot4/models/TRef.py @@ -23,7 +23,7 @@ class Model_TRef(uproot4.model.Model): """ - A versionless :doc:`uproot4.model.Model` for ``TRef``. + A versionless :py:class:`~uproot4.model.Model` for ``TRef``. This model does not deserialize all fields, only the reference number. """ @@ -92,7 +92,7 @@ def awkward_form(cls, file, index_format="i64", header=False, tobject_header=Tru class Model_TRefArray(uproot4.model.Model, Sequence): """ - A versionless :doc:`uproot4.model.Model` for ``TRefArray``. + A versionless :py:class:`~uproot4.model.Model` for ``TRefArray``. This also satisfies Python's abstract ``Sequence`` protocol. """ @@ -107,7 +107,7 @@ def refs(self): @property def nbytes(self): """ - The number of bytes in :doc:`uproot4.models.TRef.TRefArray.nbytes`. + The number of bytes in :py:attr:`~uproot4.models.TRef.TRefArray.refs`. """ return self._data.nbytes diff --git a/uproot4/models/TString.py b/uproot4/models/TString.py index 654d917a6..89c570069 100644 --- a/uproot4/models/TString.py +++ b/uproot4/models/TString.py @@ -11,7 +11,7 @@ class Model_TString(uproot4.model.Model, str): """ - A versionless :doc:`uproot4.model.Model` for ``TString``. + A versionless :py:class:`~uproot4.model.Model` for ``TString``. This is also a Python ``str`` (string). """ diff --git a/uproot4/models/TTree.py b/uproot4/models/TTree.py index 67d048197..1fd8ba0b7 100644 --- a/uproot4/models/TTree.py +++ b/uproot4/models/TTree.py @@ -3,7 +3,7 @@ """ Defines versioned models for ``TTree``. -See :doc:`uproot4.behaviors.TBranch` for definitions of ``TTree``-reading +See :py:mod:`uproot4.behaviors.TBranch` for definitions of ``TTree``-reading functions. """ @@ -23,7 +23,7 @@ class Model_TTree_v16(uproot4.behaviors.TTree.TTree, uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TTree`` version 16. + A :py:class:`~uproot4.model.VersionedModel` for ``TTree`` version 16. """ def read_members(self, chunk, cursor, context, file): @@ -173,7 +173,7 @@ def member_names(self): class Model_TTree_v17(uproot4.behaviors.TTree.TTree, uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TTree`` version 17. + A :py:class:`~uproot4.model.VersionedModel` for ``TTree`` version 17. """ def read_members(self, chunk, cursor, context, file): @@ -324,7 +324,7 @@ def member_names(self): class Model_TTree_v18(uproot4.behaviors.TTree.TTree, uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TTree`` version 18. + A :py:class:`~uproot4.model.VersionedModel` for ``TTree`` version 18. """ def read_members(self, chunk, cursor, context, file): @@ -481,7 +481,7 @@ def member_values(self): class Model_TTree_v19(uproot4.behaviors.TTree.TTree, uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TTree`` version 19. + A :py:class:`~uproot4.model.VersionedModel` for ``TTree`` version 19. """ def read_members(self, chunk, cursor, context, file): @@ -654,7 +654,7 @@ def member_names(self): class Model_TTree_v20(uproot4.behaviors.TTree.TTree, uproot4.model.VersionedModel): """ - A :doc:`uproot4.model.VersionedModel` for ``TTree`` version 20. + A :py:class:`~uproot4.model.VersionedModel` for ``TTree`` version 20. """ def read_members(self, chunk, cursor, context, file): @@ -826,7 +826,7 @@ def member_names(self): class Model_TTree(uproot4.model.DispatchByVersion): """ - A :doc:`uproot4.model.DispatchByVersion` for ``TTree``. + A :py:class:`~uproot4.model.DispatchByVersion` for ``TTree``. """ known_versions = { @@ -843,7 +843,7 @@ class Model_TTree(uproot4.model.DispatchByVersion): class Model_ROOT_3a3a_TIOFeatures(uproot4.model.Model): """ - A versionless :doc:`uproot4.model.Model` for ``ROOT::TIOFeatures``. + A versionless :py:class:`~uproot4.model.Model` for ``ROOT::TIOFeatures``. """ def read_members(self, chunk, cursor, context, file): diff --git a/uproot4/models/__init__.py b/uproot4/models/__init__.py index a9dacbb10..69ea33679 100644 --- a/uproot4/models/__init__.py +++ b/uproot4/models/__init__.py @@ -3,9 +3,9 @@ """ Defines models, which are classes of objects read from ROOT files. -Models must be subclasses of :doc:`uproot4.model.Model`, and models for a +Models must be subclasses of :py:class:`~uproot4.model.Model`, and models for a specific version of a ROOT class must be subclasses of -:doc:`uproot4.model.VersionedModel`. +:py:class:`~uproot4.model.VersionedModel`. If a C++ class has no associated model, a new model class will be generated from the ROOT file's ``TStreamerInfo``. @@ -13,10 +13,10 @@ To add a versionless model for a ROOT class: 1. Translate the ROOT class name from C++ to Python with - :doc:`uproot4.model.classname_encode`. For example, + :py:func:`~uproot4.model.classname_encode`. For example, ``"ROOT::RThing"`` becomes ``"Model_ROOT_3a3a_RThing"``. 2. Define a class with that name. -3. Explicitly add it to :doc:`uproot4.classes`. +3. Explicitly add it to ``uproot4.classes``. A versionless model is instantiated for any ROOT object with a given class name, regardless of its version. The deserialization procedure may need to @@ -25,23 +25,23 @@ To add a versioned model for a ROOT class: 1. Translate the ROOT class name from C++ to Python with - :doc:`uproot4.model.classname_encode` with a specific ``version``. + :py:func:`~uproot4.model.classname_encode` with a specific ``version``. For example version ``2`` of ``"ROOT::RThing"`` becomes ``"Model_ROOT_3a3a_RThing_v2"``. 2. Define a class with that name. -3. Explicitly add it to a :doc:`uproot4.model.DispatchByVersion` for that - class. You might also need to add a :doc:`uproot4.model.DispatchByVersion` - to the :doc:`uproot4.classes`. +3. Explicitly add it to a :py:class:`~uproot4.model.DispatchByVersion` for that + class. You might also need to add a :py:class:`~uproot4.model.DispatchByVersion` + to the ``uproot4.classes``. A versioned model is only instantiated for a ROOT object with a given class -name and version. Uproot has common versions of :doc:`uproot4.models.TBranch` -and :doc:`uproot4.models.TTree` predefined so that it can usually avoid reading +name and version. Uproot has common versions of :py:class:`~uproot4.models.TBranch` +and :py:class:`~uproot4.models.TTree` predefined so that it can usually avoid reading a ROOT file's ``TStreamerInfo``. High-level methods and properties should not be defined on the model class; add them as behavior classes. -See also :doc:`uproot4.behaviors`. +See also :py:mod:`uproot4.behaviors`. """ from __future__ import absolute_import diff --git a/uproot4/reading.py b/uproot4/reading.py index ee43f4dd6..0a67af09a 100644 --- a/uproot4/reading.py +++ b/uproot4/reading.py @@ -1,11 +1,11 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/master/LICENSE """ -Defines the entry-point for opening a file, :doc:`uproot4.reading.open`, and +Defines the entry-point for opening a file, :py:func:`~uproot4.reading.open`, and the classes that are too fundamental to be models: -:doc:`uproot4.reading.ReadOnlyFile` (``TFile``), -:doc:`uproot4.reading.ReadOnlyDirectory` (``TDirectory`` or ``TDirectoryFile``), -and :doc:`uproot4.reading.ReadOnlyKey` (``TKey``). +:py:class:`~uproot4.reading.ReadOnlyFile` (``TFile``), +:py:class:`~uproot4.reading.ReadOnlyDirectory` (``TDirectory`` or ``TDirectoryFile``), +and :py:class:`~uproot4.reading.ReadOnlyKey` (``TKey``). """ from __future__ import absolute_import @@ -48,7 +48,7 @@ def open( and an object path within the ROOT file, to return an object, rather than a file. Path objects are interpreted strictly as filesystem paths or URLs. - Examples: ``"rel/file.root"``, ``"C:\abs\file.root"``, + Examples: ``"rel/file.root"``, ``"C:\\abs\\file.root"``, ``"http://where/what.root"``, ``"rel/file.root:tdirectory/ttree"``, ``Path("rel:/file.root")``, ``Path("/abs/path:stuff.root")`` object_cache (None, MutableMapping, or int): Cache of objects drawn @@ -67,20 +67,20 @@ def open( If an object path is given, the return type of this function can be anything that can be extracted from a ROOT file (subclass of - :doc:`uproot4.model.Model`). + :py:class:`~uproot4.model.Model`). If an object path is not given, the return type is a - :doc:`uproot4.reading.ReadOnlyDirectory` *and not* - :doc:`uproot4.reading.ReadOnlyFile`. ROOT objects can be extracted from a - :doc:`uproot4.reading.ReadOnlyDirectory` but not a - :doc:`uproot4.reading.ReadOnlyFile`. + :py:class:`~uproot4.reading.ReadOnlyDirectory` *and not* + :py:class:`~uproot4.reading.ReadOnlyFile`. ROOT objects can be extracted from a + :py:class:`~uproot4.reading.ReadOnlyDirectory` but not a + :py:class:`~uproot4.reading.ReadOnlyFile`. Options (type; default): - * file_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.file.MemmapSource`) - * xrootd_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.xrootd.XRootDSource`) - * http_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.http.HTTPSource`) - * object_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.object.ObjectSource`) + * file_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.file.MemmapSource`) + * xrootd_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.xrootd.XRootDSource`) + * http_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.http.HTTPSource`) + * object_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.object.ObjectSource`) * timeout (float for HTTP, int for XRootD; 30) * max_num_elements (None or int; None) * num_workers (int; 1) @@ -90,7 +90,7 @@ def open( Any object derived from a ROOT file is a context manager (works in Python's ``with`` statement) that closes the file when exiting the ``with`` block. - Therefore, the :doc:`uproot4.reading.open` function can and usually should + Therefore, the :py:func:`~uproot4.reading.open` function can and usually should be used in a ``with`` statement to clean up file handles and threads associated with open files: @@ -103,13 +103,13 @@ def open( Other file entry points: - * :doc:`uproot4.reading.open` (this function): opens one file to read any + * :py:func:`~uproot4.reading.open` (this function): opens one file to read any of its objects. - * :doc:`uproot4.behaviors.TBranch.iterate`: iterates through chunks of + * :py:func:`~uproot4.behaviors.TBranch.iterate`: iterates through chunks of contiguous entries in ``TTrees``. - * :doc:`uproot4.behaviors.TBranch.concatenate`: returns a single concatenated + * :py:func:`~uproot4.behaviors.TBranch.concatenate`: returns a single concatenated array from ``TTrees``. - * :doc:`uproot4.behaviors.TBranch.lazy`: returns a lazily read array from + * :py:func:`~uproot4.behaviors.TBranch.lazy`: returns a lazily read array from ``TTrees``. """ @@ -179,18 +179,18 @@ def open( class CommonFileMethods(object): """ - Abstract class for :doc:`uproot4.reading.ReadOnlyFile` and - :doc:`uproot4.reading.DetachedFile`. The latter is a placeholder for file - information, such as the :doc:`uproot4.reading.CommonFileMethods.file_path` + Abstract class for :py:class:`~uproot4.reading.ReadOnlyFile` and + :py:class:`~uproot4.reading.DetachedFile`. The latter is a placeholder for file + information, such as the :py:attr:`~uproot4.reading.CommonFileMethods.file_path` used in many error messages, without holding a reference to the active - :doc:`uproot4.source.chunk.Source`. + :py:class:`~uproot4.source.chunk.Source`. This allows the file to be closed and deleted while objects that were read from it still exist. Also, only objects that hold detached file references, rather than active ones, can be pickled. The (unpickleable) objects that must hold a reference to an active - :doc:`uproot4.reading.ReadOnlyFile` are listed by C++ (decoded) classname + :py:class:`~uproot4.reading.ReadOnlyFile` are listed by C++ (decoded) classname in ``uproot4.must_be_attached``. """ @@ -206,7 +206,7 @@ def file_path(self): def options(self): """ The dict of ``options`` originally passed to the - :doc:`uproot4.reading.ReadOnlyFile` constructor. + :py:class:`~uproot4.reading.ReadOnlyFile` constructor. """ return self._options @@ -215,8 +215,8 @@ def root_version(self): """ Version of ROOT used to write the file as a string. - See :doc:`uproot4.reading.CommonFileMethods.root_version_tuple` and - :doc:`uproot4.reading.CommonFileMethods.fVersion`. + See :py:attr:`~uproot4.reading.CommonFileMethods.root_version_tuple` and + :py:attr:`~uproot4.reading.CommonFileMethods.fVersion`. """ return "{0}.{1:02d}/{2:02d}".format(*self.root_version_tuple) @@ -225,8 +225,8 @@ def root_version_tuple(self): """ Version of ROOT used to write teh file as a tuple. - See :doc:`uproot4.reading.CommonFileMethods.root_version` and - :doc:`uproot4.reading.CommonFileMethods.fVersion`. + See :py:attr:`~uproot4.reading.CommonFileMethods.root_version` and + :py:attr:`~uproot4.reading.CommonFileMethods.fVersion`. """ version = self._fVersion if version >= 1000000: @@ -246,18 +246,18 @@ def is_64bit(self): A file that is larger than 4 GiB must be 64-bit ready, though any file might be. This refers to seek points like - :doc:`uproot4.reading.ReadOnlyFile.fSeekFree` being 64-bit integers, + :py:attr:`~uproot4.reading.ReadOnlyFile.fSeekFree` being 64-bit integers, rather than 32-bit. Note that a file being 64-bit is distinct from a ``TDirectory`` being - 64-bit; see :doc:`uproot4.reading.ReadOnlyDirectory.is_64bit`. + 64-bit; see :py:attr:`~uproot4.reading.ReadOnlyDirectory.is_64bit`. """ return self._fVersion >= 1000000 @property def compression(self): """ - A :doc:`uproot4.compression.Compression` object describing the + A :py:class:`~uproot4.compression.Compression` object describing the compression setting for the ROOT file. Note that different objects (even different ``TBranches`` within a @@ -266,10 +266,10 @@ def compression(self): be compressed. For some versions of ROOT ``TStreamerInfo`` is always compressed with - :doc:`uproot4.compression.ZLIB`, even if the compression is set to a + :py:class:`~uproot4.compression.ZLIB`, even if the compression is set to a different algorithm. - See :doc:`uproot4.reading.CommonFileMethods.fCompress`. + See :py:attr:`~uproot4.reading.CommonFileMethods.fCompress`. """ return uproot4.compression.Compression.from_code(self._fCompress) @@ -279,8 +279,8 @@ def hex_uuid(self): The unique identifier (UUID) of the ROOT file expressed as a hexadecimal string. - See :doc:`uproot4.reading.CommonFileMethods.uuid` and - :doc:`uproot4.reading.CommonFileMethods.fUUID`. + See :py:attr:`~uproot4.reading.CommonFileMethods.uuid` and + :py:attr:`~uproot4.reading.CommonFileMethods.fUUID`. """ if uproot4._util.py2: out = "".join("{0:02x}".format(ord(x)) for x in self._fUUID) @@ -294,8 +294,8 @@ def uuid(self): The unique identifier (UUID) of the ROOT file expressed as a Python ``uuid.UUID`` object. - See :doc:`uproot4.reading.CommonFileMethods.hex_uuid` and - :doc:`uproot4.reading.CommonFileMethods.fUUID`. + See :py:attr:`~uproot4.reading.CommonFileMethods.hex_uuid` and + :py:attr:`~uproot4.reading.CommonFileMethods.fUUID`. """ return uuid.UUID(self.hex_uuid.replace("-", "")) @@ -303,9 +303,9 @@ def uuid(self): def fVersion(self): """ Raw version information for the ROOT file; this number is used to derive - :doc:`uproot4.reading.CommonFileMethods.root_version`, - :doc:`uproot4.reading.CommonFileMethods.root_version_tuple`, and - :doc:`uproot4.reading.CommonFileMethods.is_64bit`. + :py:attr:`~uproot4.reading.CommonFileMethods.root_version`, + :py:attr:`~uproot4.reading.CommonFileMethods.root_version_tuple`, and + :py:attr:`~uproot4.reading.CommonFileMethods.is_64bit`. """ return self._fVersion @@ -336,7 +336,7 @@ def fSeekFree(self): @property def fNbytesFree(self): """ - The number of bytes in the ``TFree` data, for managing empty spaces + The number of bytes in the ``TFree`` data, for managing empty spaces in a ROOT file (filesystem-like fragmentation). """ return self._fNbytesFree @@ -377,10 +377,10 @@ def fCompress(self): be compressed. For some versions of ROOT ``TStreamerInfo`` is always compressed with - :doc:`uproot4.compression.ZLIB`, even if the compression is set to a + :py:class:`~uproot4.compression.ZLIB`, even if the compression is set to a different algorithm. - See :doc:`uproot4.reading.CommonFileMethods.compression`. + See :py:attr:`~uproot4.reading.CommonFileMethods.compression`. """ return self._fCompress @@ -388,7 +388,7 @@ def fCompress(self): def fSeekInfo(self): """ The seek point (int) to the ``TStreamerInfo`` data, where - :doc:`uproot4.reading.ReadOnlyFile.streamers` are located. + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` are located. """ return self._fSeekInfo @@ -396,7 +396,7 @@ def fSeekInfo(self): def fNbytesInfo(self): """ The number of bytes in the ``TStreamerInfo`` data, where - :doc:`uproot4.reading.ReadOnlyFile.streamers` are located. + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` are located. """ return self._fNbytesInfo @@ -406,8 +406,8 @@ def fUUID(self): The unique identifier (UUID) of the ROOT file as a raw bytestring (Python ``bytes``). - See :doc:`uproot4.reading.CommonFileMethods.hex_uuid` and - :doc:`uproot4.reading.CommonFileMethods.uuid`. + See :py:attr:`~uproot4.reading.CommonFileMethods.hex_uuid` and + :py:attr:`~uproot4.reading.CommonFileMethods.uuid`. """ return self._fUUID @@ -415,20 +415,20 @@ def fUUID(self): class DetachedFile(CommonFileMethods): """ Args: - file (:doc:`uproot4.reading.ReadOnlyFile`): The active file object to + file (:py:class:`~uproot4.reading.ReadOnlyFile`): The active file object to convert into a detached file. - A placeholder for a :doc:`uproot4.reading.ReadOnlyFile` with useful - information, such as the :doc:`uproot4.reading.CommonFileMethods.file_path` + A placeholder for a :py:class:`~uproot4.reading.ReadOnlyFile` with useful + information, such as the :py:attr:`~uproot4.reading.CommonFileMethods.file_path` used in many error messages, without holding a reference to the active - :doc:`uproot4.source.chunk.Source`. + :py:class:`~uproot4.source.chunk.Source`. This allows the file to be closed and deleted while objects that were read from it still exist. Also, only objects that hold detached file references, rather than active ones, can be pickled. The (unpickleable) objects that must hold a reference to an active - :doc:`uproot4.reading.ReadOnlyFile` are listed by C++ (decoded) classname + :py:class:`~uproot4.reading.ReadOnlyFile` are listed by C++ (decoded) classname in ``uproot4.must_be_attached``. """ @@ -458,7 +458,7 @@ class ReadOnlyFile(CommonFileMethods): """ Args: file_path (str or ``pathlib.Path``): The filesystem path or remote URL - of the file to open. Unlike :doc:`uproot4.reading.open`, it cannot + of the file to open. Unlike :py:func:`~uproot4.reading.open`, it cannot be followed by a colon (``:``) and an object path within the ROOT file. object_cache (None, MutableMapping, or int): Cache of objects drawn @@ -474,28 +474,28 @@ class ReadOnlyFile(CommonFileMethods): options: See below. Handle to an open ROOT file, the way to access data in ``TDirectories`` - (:doc:`uproot4.reading.ReadOnlyDirectory`) and create new classes from - ``TStreamerInfo`` (:doc:`uproot4.reading.ReadOnlyFile.streamers`). + (:py:class:`~uproot4.reading.ReadOnlyDirectory`) and create new classes from + ``TStreamerInfo`` (:py:attr:`~uproot4.reading.ReadOnlyFile.streamers`). All objects derived from ROOT files have a pointer back to the file, - though this is a :doc:`uproot4.reading.DetachedFile` (no active connection, - cannot read more data) if the object's :doc:`uproot4.model.Model.classname` + though this is a :py:class:`~uproot4.reading.DetachedFile` (no active connection, + cannot read more data) if the object's :py:attr:`~uproot4.model.Model.classname` is not in ``uproot4.reading.must_be_attached``: objects that can read more data and need to have an active connection (like ``TTree``, ``TBranch``, and ``TDirectory``). - Note that a :doc:`uproot4.reading.ReadOnlyFile` can't be directly used to - extract objects. To read data, use the :doc:`uproot4.reading.ReadOnlyDirectory` - returned by :doc:`uproot4.reading.ReadOnlyFile.root_directory`. This is why - :doc:`uproot4.reading.open` returns a :doc:`uproot4.reading.ReadOnlyDirectory` - and not a :doc:`uproot4.reading.ReadOnlyFile`. + Note that a :py:class:`~uproot4.reading.ReadOnlyFile` can't be directly used to + extract objects. To read data, use the :py:class:`~uproot4.reading.ReadOnlyDirectory` + returned by :py:attr:`~uproot4.reading.ReadOnlyFile.root_directory`. This is why + :py:func:`~uproot4.reading.open` returns a :py:class:`~uproot4.reading.ReadOnlyDirectory` + and not a :py:class:`~uproot4.reading.ReadOnlyFile`. Options (type; default): - * file_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.file.MemmapSource`) - * xrootd_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.xrootd.XRootDSource`) - * http_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.http.HTTPSource`) - * object_handler (:doc:`uproot4.source.chunk.Source` class; :doc:`uproot4.source.object.ObjectSource`) + * file_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.file.MemmapSource`) + * xrootd_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.xrootd.XRootDSource`) + * http_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.http.HTTPSource`) + * object_handler (:py:class:`~uproot4.source.chunk.Source` class; :py:class:`~uproot4.source.object.ObjectSource`) * timeout (float for HTTP, int for XRootD; 30) * max_num_elements (None or int; None) * num_workers (int; 1) @@ -607,7 +607,7 @@ def __repr__(self): @property def detached(self): """ - A :doc:`uproot4.reading.DetachedFile` version of this file. + A :py:class:`~uproot4.reading.DetachedFile` version of this file. """ return DetachedFile(self) @@ -619,9 +619,9 @@ def close(self): managers.) After closing, new objects and classes cannot be extracted from the file, - but objects with :doc:`uproot4.reading.DetachedFile` references instead - of :doc:`uproot4.reading.ReadOnlyFile` that are still in the - :doc:`uproot4.reading.ReadOnlyFile.object_cache` would still be + but objects with :py:class:`~uproot4.reading.DetachedFile` references instead + of :py:class:`~uproot4.reading.ReadOnlyFile` that are still in the + :py:attr:`~uproot4.reading.ReadOnlyFile.object_cache` would still be accessible. """ self._source.close() @@ -632,13 +632,13 @@ def closed(self): True if the file has been closed; False otherwise. The file may have been closed explicitly with - :doc:`uproot4.reading.ReadOnlyFile.close` or implicitly in the Python + :py:meth:`~uproot4.reading.ReadOnlyFile.close` or implicitly in the Python ``with`` statement, as a context manager. After closing, new objects and classes cannot be extracted from the file, - but objects with :doc:`uproot4.reading.DetachedFile` references instead - of :doc:`uproot4.reading.ReadOnlyFile` that are still in the - :doc:`uproot4.reading.ReadOnlyFile.object_cache` would still be + but objects with :py:class:`~uproot4.reading.DetachedFile` references instead + of :py:class:`~uproot4.reading.ReadOnlyFile` that are still in the + :py:attr:`~uproot4.reading.ReadOnlyFile.object_cache` would still be accessible. """ return self._source.closed @@ -653,7 +653,7 @@ def __exit__(self, exception_type, exception_value, traceback): @property def source(self): """ - The :doc:`uproot4.source.chunk.Source` associated with this file, which + The :py:class:`~uproot4.source.chunk.Source` associated with this file, which is the "physical layer" that knows how to communicate with local file systems or through remote protocols like HTTP(S) or XRootD, but does not know what the bytes mean. @@ -675,7 +675,7 @@ def object_cache(self): Any Python ``MutableMapping`` can be used as a cache (i.e. a Python dict would be a cache that never evicts old objects), though - :doc:`uproot4.cache.LRUCache` is a good choice because it is thread-safe + :py:class:`~uproot4.cache.LRUCache` is a good choice because it is thread-safe and evicts least-recently used objects when a maximum number of objects is reached. """ @@ -705,7 +705,7 @@ def array_cache(self): Any Python ``MutableMapping`` can be used as a cache (i.e. a Python dict would be a cache that never evicts old objects), though - :doc:`uproot4.cache.LRUArrayCache` is a good choice because it is + :py:class:`~uproot4.cache.LRUArrayCache` is a good choice because it is thread-safe and evicts least-recently used objects when a size limit is reached. """ @@ -726,7 +726,7 @@ def array_cache(self, value): def root_directory(self): """ The root ``TDirectory`` of the file - (:doc:`uproot4.reading.ReadOnlyDirectory`). + (:py:class:`~uproot4.reading.ReadOnlyDirectory`). """ return ReadOnlyDirectory( (), @@ -752,7 +752,7 @@ def show_streamers(self, classname=None, version="max", stream=sys.stdout): Example with ``classname="TLorentzVector"``: - .. code-block:: raw + .. code-block:: TVector3 (v3): TObject (v1) fX: double (TStreamerBasicType) @@ -786,7 +786,7 @@ def show_streamers(self, classname=None, version="max", stream=sys.stdout): @property def streamers(self): """ - A list of :doc:`uproot4.streamers.Model_TStreamerInfo` objects + A list of :py:class:`~uproot4.streamers.Model_TStreamerInfo` objects representing the ``TStreamerInfos`` in the ROOT file. A file's ``TStreamerInfos`` are only read the first time they are needed. @@ -794,7 +794,7 @@ def streamers(self): the probability that ``TStreamerInfos`` will need to be read (depending on the choice of classes or versions of the classes that are accessed). - See also :doc:`uproot4.reading.ReadOnlyFile.streamer_rules`, which are + See also :py:attr:`~uproot4.reading.ReadOnlyFile.streamer_rules`, which are read in the same pass with ``TStreamerInfos``. """ import uproot4.streamers @@ -886,7 +886,7 @@ def streamer_rules(self): Uproot does not have access to a C++ compiler. These rules are read in the same pass that produces - :doc:`uproot4.reading.ReadOnlyFile.streamers`. + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers`. """ if self._streamer_rules is None: self.streamers @@ -894,7 +894,7 @@ def streamer_rules(self): def streamers_named(self, classname): """ - Returns a list of :doc:`uproot4.streamers.Model_TStreamerInfo` objects + Returns a list of :py:class:`~uproot4.streamers.Model_TStreamerInfo` objects that match C++ (decoded) ``classname``. More that one streamer matching a given name is unlikely, but possible @@ -902,7 +902,7 @@ def streamers_named(self, classname): files can be created by merging data from different ROOT versions with hadd?) - See also :doc:`uproot4.reading.ReadOnlyFile.streamer_named` (singular). + See also :py:attr:`~uproot4.reading.ReadOnlyFile.streamer_named` (singular). """ streamer_versions = self.streamers.get(classname) if streamer_versions is None: @@ -912,14 +912,14 @@ def streamers_named(self, classname): def streamer_named(self, classname, version="max"): """ - Returns a single :doc:`uproot4.streamers.Model_TStreamerInfo` object + Returns a single :py:class:`~uproot4.streamers.Model_TStreamerInfo` object that matches C++ (decoded) ``classname`` and ``version``. The ``version`` can be an integer or ``"min"`` or ``"max"`` for the minimum and maximum version numbers available in the file. The default is ``"max"`` because there's usually only one. - See also :doc:`uproot4.reading.ReadOnlyFile.streamers_named` (plural). + See also :py:attr:`~uproot4.reading.ReadOnlyFile.streamers_named` (plural). """ streamer_versions = self.streamers.get(classname) if streamer_versions is None or len(streamer_versions) == 0: @@ -933,12 +933,12 @@ def streamer_named(self, classname, version="max"): def streamer_dependencies(self, classname, version="max"): """ - Returns a list of :doc:`uproot4.streamers.Model_TStreamerInfo` objects + Returns a list of :py:class:`~uproot4.streamers.Model_TStreamerInfo` objects that depend on the one that matches C++ (decoded) ``classname`` and ``version``. The ``classname`` and ``version`` are interpreted the same way as - :doc:`uproot4.reading.ReadOnlyFile.streamer_named`. + :py:attr:`~uproot4.reading.ReadOnlyFile.streamer_named`. """ streamer = self.streamer_named(classname, version=version) out = [] @@ -963,10 +963,10 @@ def custom_classes(self, value): def remove_class_definition(self, classname): """ Removes all versions of a class, specified by C++ (decoded) - ``classname``, from the :doc:`uproot4.reading.ReadOnlyFile.custom_classes`. + ``classname``, from the :py:attr:`~uproot4.reading.ReadOnlyFile.custom_classes`. If the file doesn't have a - :doc:`uproot4.reading.ReadOnlyFile.custom_classes`, this function adds + :py:attr:`~uproot4.reading.ReadOnlyFile.custom_classes`, this function adds one, so it does not remove the class from the common pool. If you want to remove a class from the common pool, you can do so with @@ -986,14 +986,14 @@ def class_named(self, classname, version=None): and possible ``version``. * If the ``version`` is None, this function may return a - :doc:`uproot4.model.DispatchByVersion`. + :py:class:`~uproot4.model.DispatchByVersion`. * If the ``version`` is an integer, ``"min"`` or ``"max"``, then it - returns a :doc:`uproot4.model.VersionedModel`. Using ``"min"`` or + returns a :py:class:`~uproot4.model.VersionedModel`. Using ``"min"`` or ``"max"`` specifies the minium or maximum version ``TStreamerInfo`` defined by the file; most files define only one so ``"max"`` is usually safe. - If this file has :doc:`uproot4.reading.ReadOnlyFile.custom_classes`, + If this file has :py:attr:`~uproot4.reading.ReadOnlyFile.custom_classes`, the new class is added to that dict; otherwise, it is added to the global ``uproot4.classes``. """ @@ -1054,12 +1054,12 @@ def class_named(self, classname, version=None): def chunk(self, start, stop): """ - Returns a :doc:`uproot4.source.chunk.Chunk` from the - :doc:`uproot4.source.chunk.Source` that is guaranteed to include bytes + Returns a :py:class:`~uproot4.source.chunk.Chunk` from the + :py:class:`~uproot4.source.chunk.Source` that is guaranteed to include bytes from ``start`` up to ``stop`` seek points in the file. If the desired range is satisfied by a previously saved chunk, such as - :doc:`uproot4.reading.ReadOnlyFile.begin_chunk`, then that is returned. + :py:attr:`~uproot4.reading.ReadOnlyFile.begin_chunk`, then that is returned. Hence, the returned chunk may include more data than the range from ``start`` up to ``stop``. """ @@ -1073,7 +1073,7 @@ def chunk(self, start, stop): @property def begin_chunk(self): """ - A special :doc:`uproot4.source.chunk.Chunk` corresponding to the + A special :py:class:`~uproot4.source.chunk.Chunk` corresponding to the beginning of the file, from seek point ``0`` up to ``options["begin_chunk_size"]``. """ @@ -1081,55 +1081,55 @@ def begin_chunk(self): def hook_before_create_source(self, **kwargs): """ - Called in the :doc:`uproot4.reading.ReadOnlyFile` constructor before the - :doc:`uproot4.source.chunk.Source` is created. + Called in the :py:class:`~uproot4.reading.ReadOnlyFile` constructor before the + :py:class:`~uproot4.source.chunk.Source` is created. - This is the first hook called in the :doc:`uproot4.reading.ReadOnlyFile` + This is the first hook called in the :py:class:`~uproot4.reading.ReadOnlyFile` constructor. """ pass def hook_before_get_chunks(self, **kwargs): """ - Called in the :doc:`uproot4.reading.ReadOnlyFile` constructor after the - :doc:`uproot4.source.chunk.Source` is created but before attempting to - get any :doc:`uproot4.source.chunk.Chunk`, specifically the - :doc:`uproot4.reading.ReadOnlyFile.begin_chunk`. + Called in the :py:class:`~uproot4.reading.ReadOnlyFile` constructor after the + :py:class:`~uproot4.source.chunk.Source` is created but before attempting to + get any :py:class:`~uproot4.source.chunk.Chunk`, specifically the + :py:attr:`~uproot4.reading.ReadOnlyFile.begin_chunk`. """ pass def hook_before_interpret(self, **kwargs): """ - Called in the :doc:`uproot4.reading.ReadOnlyFile` constructor after - loading the :doc:`uproot4.reading.ReadOnlyFile.begin_chunk` and before + Called in the :py:class:`~uproot4.reading.ReadOnlyFile` constructor after + loading the :py:attr:`~uproot4.reading.ReadOnlyFile.begin_chunk` and before interpreting its ``TFile`` header. """ pass def hook_after_interpret(self, **kwargs): """ - Called in the :doc:`uproot4.reading.ReadOnlyFile` constructor after + Called in the :py:class:`~uproot4.reading.ReadOnlyFile` constructor after interpreting the ``TFile`` header and before raising an error if the first four bytes are not ``b"root"``. - This is the last hook called in the :doc:`uproot4.reading.ReadOnlyFile` + This is the last hook called in the :py:class:`~uproot4.reading.ReadOnlyFile` constructor. """ pass def hook_before_read_streamer_key(self, **kwargs): """ - Called in :doc:`uproot4.reading.ReadOnlyFile.streamers` before reading + Called in :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` before reading the ``TKey`` associated with the ``TStreamerInfo``. This is the first hook called in - :doc:`uproot4.reading.ReadOnlyFile.streamers`. + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers`. """ pass def hook_before_read_decompress_streamers(self, **kwargs): """ - Called in :doc:`uproot4.reading.ReadOnlyFile.streamers` after reading + Called in :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` after reading the ``TKey`` associated with the ``TStreamerInfo`` and before reading and decompressing the ``TStreamerInfo`` data. """ @@ -1137,7 +1137,7 @@ def hook_before_read_decompress_streamers(self, **kwargs): def hook_before_interpret_streamers(self, **kwargs): """ - Called in :doc:`uproot4.reading.ReadOnlyFile.streamers` after reading + Called in :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` after reading and decompressing the ``TStreamerInfo`` data, but before interpreting it. """ @@ -1145,11 +1145,11 @@ def hook_before_interpret_streamers(self, **kwargs): def hook_after_interpret_streamers(self, **kwargs): """ - Called in :doc:`uproot4.reading.ReadOnlyFile.streamers` after + Called in :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` after interpreting the ``TStreamerInfo`` data. This is the last hook called in - :doc:`uproot4.reading.ReadOnlyFile.streamers`. + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers`. """ pass @@ -1164,22 +1164,22 @@ class ReadOnlyDirectory(Mapping): Args: path (tuple of str): Object path of the ``TDirectory`` as a tuple of nested ``TDirectory`` names. - cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in - the :doc:`uproot4.reading.ReadOnlyFile`. + cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in + the :py:class:`~uproot4.reading.ReadOnlyFile`. context (dict): Auxiliary data used in deserialization. - file (:doc:`uproot4.reading.ReadOnlyFile`): The open file object. + file (:py:class:`~uproot4.reading.ReadOnlyFile`): The open file object. parent (None or calling object): The previous ``read`` in the recursive descent. Represents a ``TDirectory`` from a ROOT file, most notably, the root - directory (:doc:`uproot4.reading.ReadOnlyFile.root_directory`). + directory (:py:attr:`~uproot4.reading.ReadOnlyFile.root_directory`). - Be careful not to confuse :doc:`uproot4.reading.ReadOnlyFile` and - :doc:`uproot4.reading.ReadOnlyDirectory`: files are for accessing global - information such as :doc:`uproot4.reading.ReadOnlyFile.streamers` and + Be careful not to confuse :py:class:`~uproot4.reading.ReadOnlyFile` and + :py:class:`~uproot4.reading.ReadOnlyDirectory`: files are for accessing global + information such as :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` and directories are for data in local hierarchies. - A :doc:`uproot4.reading.ReadOnlyDirectory` is a Python ``Mapping``, which + A :py:class:`~uproot4.reading.ReadOnlyDirectory` is a Python ``Mapping``, which uses square bracket syntax to extract objects: .. code-block:: python @@ -1209,20 +1209,20 @@ class ReadOnlyDirectory(Mapping): my_directory["/directory/another_tree/branch_in_tree"] # absolute my_directory["/directory////another_tree/branch_in_tree"] # extra /// - As a Python ``Mapping``, :doc:`uproot4.reading.ReadOnlyDirectory` also has + As a Python ``Mapping``, :py:class:`~uproot4.reading.ReadOnlyDirectory` also has - * :doc:`uproot4.reading.ReadOnlyDirectory.keys`: names of objects in the + * :py:meth:`~uproot4.reading.ReadOnlyDirectory.keys`: names of objects in the ``TDirectory`` - * :doc:`uproot4.reading.ReadOnlyDirectory.values`: objects in the + * :py:meth:`~uproot4.reading.ReadOnlyDirectory.values`: objects in the ``TDirectory`` - * :doc:`uproot4.reading.ReadOnlyDirectory.items`: 2-tuple (name, object) + * :py:meth:`~uproot4.reading.ReadOnlyDirectory.items`: 2-tuple (name, object) pairs. - However, the :doc:`uproot4.reading.ReadOnlyDirectory` versions of these + However, the :py:class:`~uproot4.reading.ReadOnlyDirectory` versions of these methods have extra parameters for navigating a complex ROOT file. In addition, there is a - * :doc:`uproot4.reading.ReadOnlyDirectory.classnames`: returns a dict of + * :py:attr:`~uproot4.reading.ReadOnlyDirectory.classnames`: returns a dict of (name, classname) pairs. with the same parameters. @@ -1337,7 +1337,7 @@ def path(self): Object path of the ``TDirectory`` as a tuple of nested ``TDirectory`` names. The root directory is an empty tuple, ``()``. - See :doc:`uproot4.reading.ReadOnlyDirectory.object_path` for the path + See :py:attr:`~uproot4.reading.ReadOnlyDirectory.object_path` for the path as a string. """ return self._path @@ -1348,7 +1348,7 @@ def object_path(self): Object path of the ``TDirectory`` as a single string, beginning and ending with ``/``. The root directory is a single slash, ``"/"``. - See :doc:`uproot4.reading.ReadOnlyDirectory.path` for the path as a + See :py:attr:`~uproot4.reading.ReadOnlyDirectory.path` for the path as a tuple of strings. """ return "/".join(("",) + self._path + ("",)).replace("//", "/") @@ -1356,7 +1356,7 @@ def object_path(self): @property def file(self): """ - The :doc:`uproot4.reading.ReadOnlyFile` in which this ``TDirectory`` + The :py:class:`~uproot4.reading.ReadOnlyFile` in which this ``TDirectory`` resides. This property is useful for getting global information, in idioms like @@ -1370,7 +1370,7 @@ def file(self): def close(self): """ - Close the :doc:`uproot4.reading.ReadOnlyFile` in which this ``TDirectory`` + Close the :py:class:`~uproot4.reading.ReadOnlyFile` in which this ``TDirectory`` resides. """ self._file.close() @@ -1378,7 +1378,7 @@ def close(self): @property def closed(self): """ - True if the :doc:`uproot4.reading.ReadOnlyDirectory.file` is closed; + True if the :py:attr:`~uproot4.reading.ReadOnlyDirectory.file` is closed; False otherwise. """ return self._file.closed @@ -1393,7 +1393,7 @@ def __exit__(self, exception_type, exception_value, traceback): @property def cursor(self): """ - A :doc:`uproot4.source.cursor.Cursor` pointing to the seek point in the + A :py:class:`~uproot4.source.cursor.Cursor` pointing to the seek point in the file where this ``TDirectory`` is defined (at the start of the ``TDirectory`` header). """ @@ -1413,11 +1413,11 @@ def is_64bit(self): True if the ``TDirectory`` is 64-bit ready; False otherwise. This refers to seek points like - :doc:`uproot4.reading.ReadOnlyDirectory.fSeekDir` being 64-bit integers, + :py:attr:`~uproot4.reading.ReadOnlyDirectory.fSeekDir` being 64-bit integers, rather than 32-bit. Note that a file being 64-bit is distinct from a ``TDirectory`` being - 64-bit; see :doc:`uproot4.reading.ReadOnlyFile.is_64bit`. + 64-bit; see :py:attr:`~uproot4.reading.ReadOnlyFile.is_64bit`. """ return self._fVersion > 1000 @@ -1475,7 +1475,7 @@ def values( filter to select keys by C++ (decoded) classname. Returns objects in this ``TDirectory`` as a list of - :doc:`uproot4.model.Model`. + :py:class:`~uproot4.model.Model`. Note that this reads all objects that are selected by ``filter_name`` and ``filter_classname``. @@ -1507,7 +1507,7 @@ def items( filter to select keys by C++ (decoded) classname. Returns (name, object) pairs for objects in this ``TDirectory`` as a - list of 2-tuples of (str, :doc:`uproot4.model.Model`). + list of 2-tuples of (str, :py:class:`~uproot4.model.Model`). Note that this reads all objects that are selected by ``filter_name`` and ``filter_classname``. @@ -1610,7 +1610,7 @@ def itervalues( filter to select keys by C++ (decoded) classname. Returns objects in this ``TDirectory`` as an iterator over - :doc:`uproot4.model.Model`. + :py:class:`~uproot4.model.Model`. Note that this reads all objects that are selected by ``filter_name`` and ``filter_classname``. @@ -1642,7 +1642,7 @@ def iteritems( filter to select keys by C++ (decoded) classname. Returns (name, object) pairs for objects in this ``TDirectory`` as an - iterator over 2-tuples of (str, :doc:`uproot4.model.Model`). + iterator over 2-tuples of (str, :py:class:`~uproot4.model.Model`). Note that this reads all objects that are selected by ``filter_name`` and ``filter_classname``. @@ -1755,9 +1755,9 @@ def classname_of(self, where, encoded=False, version=None): def class_of(self, where, version=None): """ Returns a class object for the ROOT object selected by ``where``. If - ``version`` is specified, get a :doc:`uproot4.model.VersionedModel`; - otherwise, get a :doc:`uproot4.model.DispatchByVersion` or a versionless - :doc:`uproot4.model.Model`. + ``version`` is specified, get a :py:class:`~uproot4.model.VersionedModel`; + otherwise, get a :py:class:`~uproot4.model.DispatchByVersion` or a versionless + :py:class:`~uproot4.model.Model`. The syntax for ``where`` is the same as in square brakets, namely that cycle numbers can be specified after semicolons (``;``) and nested @@ -1773,7 +1773,7 @@ def class_of(self, where, version=None): def streamer_of(self, where, version): """ - Returns a ``TStreamerInfo`` (:doc:`uproot4.streamers.Model_TStreamerInfo`) + Returns a ``TStreamerInfo`` (:py:class:`~uproot4.streamers.Model_TStreamerInfo`) for the object selected by ``where`` and ``version``. The syntax for ``where`` is the same as in square brakets, namely that @@ -1790,7 +1790,7 @@ def streamer_of(self, where, version): def key(self, where): """ - Returns a ``TKey`` (:doc:`uproot4.reading.ReadOnlyKey`) for the object + Returns a ``TKey`` (:py:class:`~uproot4.reading.ReadOnlyKey`) for the object selected by ``where``. The syntax for ``where`` is the same as in square brakets, namely that @@ -1960,24 +1960,24 @@ def fSeekKeys(self): def hook_before_read(self, **kwargs): """ - Called in the :doc:`uproot4.reading.ReadOnlyDirectory` constructor before + Called in the :py:class:`~uproot4.reading.ReadOnlyDirectory` constructor before reading the ``TDirectory`` header fields. This is the first hook called in the - :doc:`uproot4.reading.ReadOnlyDirecotry` constructor. + :py:class:`~uproot4.reading.ReadOnlyDirecotry` constructor. """ pass def hook_before_interpret(self, **kwargs): """ - Called in the :doc:`uproot4.reading.ReadOnlyDirectory` constructor after + Called in the :py:class:`~uproot4.reading.ReadOnlyDirectory` constructor after reading the ``TDirectory`` header fields and before interpreting them. """ pass def hook_before_read_keys(self, **kwargs): """ - Called in the :doc:`uproot4.reading.ReadOnlyDirectory` constructor after + Called in the :py:class:`~uproot4.reading.ReadOnlyDirectory` constructor after interpreting the ``TDirectory`` header fields and before reading the chunk of ``TKeys``. """ @@ -1985,14 +1985,14 @@ def hook_before_read_keys(self, **kwargs): def hook_before_header_key(self, **kwargs): """ - Called in the :doc:`uproot4.reading.ReadOnlyDirectory` constructor after + Called in the :py:class:`~uproot4.reading.ReadOnlyDirectory` constructor after reading the chunk of ``TKeys`` and before interpreting the header ``TKey``. """ pass def hook_before_keys(self, **kwargs): """ - Called in the :doc:`uproot4.reading.ReadOnlyDirectory` constructor after + Called in the :py:class:`~uproot4.reading.ReadOnlyDirectory` constructor after interpreting the header ``TKey`` and number of keys, and before interpeting the object ``TKeys``. """ @@ -2000,11 +2000,11 @@ def hook_before_keys(self, **kwargs): def hook_after_keys(self, **kwargs): """ - Called in the :doc:`uproot4.reading.ReadOnlyDirectory` constructor after + Called in the :py:class:`~uproot4.reading.ReadOnlyDirectory` constructor after interpeting the object ``TKeys``. This is the last hook called in the - :doc:`uproot4.reading.ReadOnlyDirecotry` constructor. + :py:class:`~uproot4.reading.ReadOnlyDirecotry` constructor. """ pass @@ -2016,12 +2016,12 @@ def hook_after_keys(self, **kwargs): class ReadOnlyKey(object): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. - cursor (:doc:`uproot4.source.cursor.Cursor`): Current position in - the :doc:`uproot4.reading.ReadOnlyFile`. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. + cursor (:py:class:`~uproot4.source.cursor.Cursor`): Current position in + the :py:class:`~uproot4.reading.ReadOnlyFile`. context (dict): Auxiliary data used in deserialization. - file (:doc:`uproot4.reading.ReadOnlyFile`): The open file object. + file (:py:class:`~uproot4.reading.ReadOnlyFile`): The open file object. parent (None or calling object): The previous ``read`` in the recursive descent. read_strings (bool): If True, interpret the `fClassName`, `fName`, and @@ -2113,7 +2113,7 @@ def __repr__(self): @property def cursor(self): """ - A :doc:`uproot4.source.cursor.Cursor` pointing to the seek point in the + A :py:class:`~uproot4.source.cursor.Cursor` pointing to the seek point in the file where this ``TKey`` starts (before its header fields). """ return self._cursor @@ -2121,7 +2121,7 @@ def cursor(self): @property def data_cursor(self): """ - A :doc:`uproot4.source.cursor.Cursor` pointing to the seek point in the + A :py:class:`~uproot4.source.cursor.Cursor` pointing to the seek point in the file where the data begins (the object to be read, after its copy of the ``TKey`` and before the object's number of bytes/version header). """ @@ -2130,7 +2130,7 @@ def data_cursor(self): @property def file(self): """ - The :doc:`uproot4.reading.ReadOnlyFile` in which this ``TKey`` resides. + The :py:class:`~uproot4.reading.ReadOnlyFile` in which this ``TKey`` resides. """ return self._file @@ -2195,7 +2195,7 @@ def is_64bit(self): True if the ``TKey`` is 64-bit ready; False otherwise. This refers to seek points like - :doc:`uproot4.reading.ReadOnlyKey.fSeekKey` being 64-bit integers, + :py:attr:`~uproot4.reading.ReadOnlyKey.fSeekKey` being 64-bit integers, rather than 32-bit. """ return self._fVersion > 1000 @@ -2215,7 +2215,7 @@ def data_uncompressed_bytes(self): """ Number of bytes in the uncompressed object (excluding any keys) - This is equal to :doc:`uproot4.reading.ReadOnlyKey.fObjlen``. + This is equal to :py:attr:`~uproot4.reading.ReadOnlyKey.fObjlen``. """ return self._fObjlen @@ -2224,8 +2224,8 @@ def data_compressed_bytes(self): """ Number of bytes in the compressed object (excluding any keys) - This is equal to :doc:`uproot4.reading.ReadOnlyKey.fNbytes`` - minus :doc:`uproot4.reading.ReadOnlyKey.fKeylen``. + This is equal to :py:attr:`~uproot4.reading.ReadOnlyKey.fNbytes`` + minus :py:attr:`~uproot4.reading.ReadOnlyKey.fKeylen``. """ return self._fNbytes - self._fKeylen @@ -2235,11 +2235,11 @@ def get(self): necessary. If the first attempt to deserialize the object fails with - :doc:`uproot4.deserialization.DeserializationError` and any of the + :py:exc:`~uproot4.deserialization.DeserializationError` and any of the models used in that attempt were predefined (not from - :doc:`uproot4.reading.ReadOnlyFile.streamers`), this method will + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers`), this method will try again with the file's own - :doc:`uproot4.reading.ReadOnlyFile.streamers`. + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers`. (Some ROOT files do have classes that don't match the standard ``TStreamerInfo``; they may have been produced from private builds of @@ -2317,8 +2317,8 @@ def get(self): def get_uncompressed_chunk_cursor(self): """ - Returns an uncompressed :doc:`uproot4.source.chunk.Chunk` and - :doc:`uproot4.source.cursor.Cursor` for the object pointed to by this + Returns an uncompressed :py:class:`~uproot4.source.chunk.Chunk` and + :py:class:`~uproot4.source.cursor.Cursor` for the object pointed to by this ``TKey`` as a 2-tuple. """ cursor = uproot4.source.cursor.Cursor(0, origin=-self._fKeylen) @@ -2414,7 +2414,7 @@ def fSeekPdir(self): def fClassName(self): """ The C++ (decoded) classname of the object or None if the - :doc:`uproot4.reading.ReadOnlyKey` was constructed with + :py:class:`~uproot4.reading.ReadOnlyKey` was constructed with ``read_strings=False``. """ return self._fClassName @@ -2422,7 +2422,7 @@ def fClassName(self): @property def fName(self): """ - The name of the object or None if the :doc:`uproot4.reading.ReadOnlyKey` + The name of the object or None if the :py:class:`~uproot4.reading.ReadOnlyKey` was constructed with ``read_strings=False``. """ return self._fName @@ -2430,28 +2430,28 @@ def fName(self): @property def fTitle(self): """ - The title of the object or None if the :doc:`uproot4.reading.ReadOnlyKey` + The title of the object or None if the :py:class:`~uproot4.reading.ReadOnlyKey` was constructed with ``read_strings=False``. """ return self._fTitle def hook_before_interpret(self, **kwargs): """ - Called in the :doc:`uproot4.reading.ReadOnlyKey` constructor before + Called in the :py:class:`~uproot4.reading.ReadOnlyKey` constructor before interpeting anything. This is the first hook called in the - :doc:`uproot4.reading.ReadOnlyKey` constructor. + :py:class:`~uproot4.reading.ReadOnlyKey` constructor. """ pass def hook_before_strings(self, **kwargs): """ - Called in the :doc:`uproot4.reading.ReadOnlyKey` constructor after + Called in the :py:class:`~uproot4.reading.ReadOnlyKey` constructor after interpeting the header and before interpreting - :doc:`uproot4.reading.ReadOnlyKey.fClassName`, - :doc:`uproot4.reading.ReadOnlyKey.fName`, and - :doc:`uproot4.reading.ReadOnlyKey.fTitle`. + :py:attr:`~uproot4.reading.ReadOnlyKey.fClassName`, + :py:attr:`~uproot4.reading.ReadOnlyKey.fName`, and + :py:attr:`~uproot4.reading.ReadOnlyKey.fTitle`. Only called if ``read_strings=True`` is passed to the constructor. """ @@ -2459,10 +2459,10 @@ def hook_before_strings(self, **kwargs): def hook_after_interpret(self, **kwargs): """ - Called in the :doc:`uproot4.reading.ReadOnlyKey` constructor after + Called in the :py:class:`~uproot4.reading.ReadOnlyKey` constructor after interpeting everything. This is the last hook called in the - :doc:`uproot4.reading.ReadOnlyKey` constructor. + :py:class:`~uproot4.reading.ReadOnlyKey` constructor. """ pass diff --git a/uproot4/source/__init__.py b/uproot4/source/__init__.py index 18e822b2f..e9c1049e7 100644 --- a/uproot4/source/__init__.py +++ b/uproot4/source/__init__.py @@ -6,14 +6,14 @@ is distinguished from "interpretation" in that the meaning of the bytes that have been read are not relevant in this layer. The "interpretation layer" interacts with the "physical layer" by requesting a -:doc:`uproot4.source.chunk.Chunk` from a :doc:`uproot4.source.chunk.Source` and -inspecting it with a :doc:`uproot4.source.cursor.Cursor`. +:py:class:`~uproot4.source.chunk.Chunk` from a :py:class:`~uproot4.source.chunk.Source` and +inspecting it with a :py:class:`~uproot4.source.cursor.Cursor`. Any threads used for parallel reading are launched and shut down with the file handle or handles themselves. Context management (Python's ``with`` statement) controls both I/O resources and threads. -This module includes a :doc:`uproot4.source.futures` implementation that +This module includes a :py:mod:`uproot4.source.futures` implementation that connects file handles with threads. """ diff --git a/uproot4/source/chunk.py b/uproot4/source/chunk.py index 02512275e..ab7a4d790 100644 --- a/uproot4/source/chunk.py +++ b/uproot4/source/chunk.py @@ -1,13 +1,13 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/master/LICENSE """ -Defines a :doc:`uproot4.source.chunk.Chunk`, which is a range of bytes +Defines a :py:class:`~uproot4.source.chunk.Chunk`, which is a range of bytes requested from a file. All interaction between the "physical layer" and the -"interpretation layer" is through a :doc:`uproot4.source.cursor.Cursor`'s -interpretation of a :doc:`uproot4.source.chunk.Chunk`. +"interpretation layer" is through a :py:class:`~uproot4.source.cursor.Cursor`'s +interpretation of a :py:class:`~uproot4.source.chunk.Chunk`. -Also defines abstract classes for :doc:`uproot4.source.chunk.Resource` and -:doc:`uproot4.source.chunk.Source`, the primary types of the "physical layer." +Also defines abstract classes for :py:class:`~uproot4.source.chunk.Resource` and +:py:class:`~uproot4.source.chunk.Source`, the primary types of the "physical layer." """ from __future__ import absolute_import @@ -24,9 +24,9 @@ class Resource(object): Abstract class for a file handle whose lifetime may be linked to threads in a thread pool executor. - A :doc:`uproot4.source.chunk.Resource` instance is always the first + A :py:class:`~uproot4.source.chunk.Resource` instance is always the first argument of functions evaluated by a - :doc:`uproot4.source.future.ResourceFuture`. + :py:class:`~uproot4.source.future.ResourceFuture`. """ def file_path(self): @@ -41,8 +41,8 @@ class Source(object): Abstract class for physically reading and writing data from a file, which might be remote. - In addition to the file handle, a :doc:`uproot4.source.chunk.Source` might - manage a :doc:`uproot4.source.future.ResourceThreadPoolExecutor` to read + In addition to the file handle, a :py:class:`~uproot4.source.chunk.Source` might + manage a :py:class:`~uproot4.source.future.ResourceThreadPoolExecutor` to read the file in parallel. Stopping these threads is part of the act of closing the file. """ @@ -55,7 +55,7 @@ def chunk(self, start, stop): (one greater than the last byte to include). Request a byte range of data from the file as a - :doc:`uproot4.source.chunk.Chunk`. + :py:class:`~uproot4.source.chunk.Chunk`. """ pass @@ -74,10 +74,10 @@ def chunks(self, ranges, notifications): This method has two outputs: * The method returns a list of unfilled - :doc:`uproot4.source.chunk.Chunk` objects, which get filled + :py:class:`~uproot4.source.chunk.Chunk` objects, which get filled in a background thread. If you try to read data from an unfilled chunk, it will wait until it is filled. - * The method also puts the same :doc:`uproot4.source.chunk.Chunk` + * The method also puts the same :py:class:`~uproot4.source.chunk.Chunk` objects onto the ``notifications`` queue as soon as they are filled. @@ -113,7 +113,7 @@ def num_requests(self): @property def num_requested_chunks(self): """ - The number of :doc:`uproot4.source.chunk.Chunk` objects that have been + The number of :py:class:`~uproot4.source.chunk.Chunk` objects that have been requested (performance counter). """ return self._num_requested_chunks @@ -142,8 +142,8 @@ def closed(self): class MultithreadedSource(Source): """ - Abstract class for a :doc:`uproot4.source.chunk.Source` that maintains a - :doc:`uproot4.source.future.ResourceThreadPoolExecutor`. + Abstract class for a :py:class:`~uproot4.source.chunk.Source` that maintains a + :py:class:`~uproot4.source.future.ResourceThreadPoolExecutor`. """ def __repr__(self): @@ -181,22 +181,22 @@ def chunks(self, ranges, notifications): @property def executor(self): """ - The :doc:`uproot4.source.future.ResourceThreadPoolExecutor` + The :py:class:`~uproot4.source.future.ResourceThreadPoolExecutor` """ return self._executor @property def num_workers(self): """ - The number of :doc:`uproot4.source.future.ResourceWorker` threads in - the :doc:`uproot4.source.future.ResourceThreadPoolExecutor`. + The number of :py:class:`~uproot4.source.future.ResourceWorker` threads in + the :py:class:`~uproot4.source.future.ResourceThreadPoolExecutor`. """ return self._executor.num_workers @property def closed(self): """ - True if the :doc:`uproot4.source.future.ResourceThreadPoolExecutor` has + True if the :py:class:`~uproot4.source.future.ResourceThreadPoolExecutor` has been shut down and the file handles have been closed. """ return self._executor.closed @@ -219,29 +219,29 @@ def notify(): class Chunk(object): """ Args: - source (:doc:`uproot4.source.chunk.Source`): Source from which the + source (:py:class:`~uproot4.source.chunk.Source`): Source from which the data were derived. start (int): Seek position of the first byte to include. stop (int): Seek position of the first byte to exclude (one greater than the last byte to include). - future (:doc:`uproot4.source.futures.NoFuture` or :doc:`uproot4.source.futures.Future`): Handle + future (:py:class:`~uproot4.source.futures.NoFuture` or :py:class:`~uproot4.source.futures.Future`): Handle to the synchronous or asynchronous data. A chunk is "filled" when the ``future`` completes. - A range of bytes from a :doc:`uproot4.source.chunk.Source`, which may be + A range of bytes from a :py:class:`~uproot4.source.chunk.Source`, which may be synchronously or asynchronously filled. The following methods must wait for the - :doc:`uproot4.source.chunk.Chunk.future` to complete (to be filled): + :py:attr:`~uproot4.source.chunk.Chunk.future` to complete (to be filled): - * :doc:`uproot4.source.chunk.Chunk.wait`: Waits and nothing else. - * :doc:`uproot4.source.chunk.Chunk.raw_data`: The data as a + * :py:meth:`~uproot4.source.chunk.Chunk.wait`: Waits and nothing else. + * :py:attr:`~uproot4.source.chunk.Chunk.raw_data`: The data as a ``numpy.ndarray`` of ``numpy.uint8``. - * :doc:`uproot4.source.chunk.Chunk.get`: A subinterval of the data as + * :py:meth:`~uproot4.source.chunk.Chunk.get`: A subinterval of the data as a ``numpy.ndarray`` of ``numpy.uint8``. - * :doc:`uproot4.source.chunk.Chunk.remainder`: A subinterval from the - :doc:`uproot4.source.cursor.Cursor` to the end of the - :doc:`uproot4.source.chunk.Chunk`. + * :py:meth:`~uproot4.source.chunk.Chunk.remainder`: A subinterval from the + :py:class:`~uproot4.source.cursor.Cursor` to the end of the + :py:class:`~uproot4.source.chunk.Chunk`. """ _dtype = numpy.dtype(numpy.uint8) @@ -250,11 +250,11 @@ class Chunk(object): def wrap(cls, source, data): """ Args: - source (:doc:`uproot4.source.chunk.Source`): Source to attach to + source (:py:class:`~uproot4.source.chunk.Source`): Source to attach to the new chunk. data (``numpy.ndarray`` of ``numpy.uint8``): Data for the new chunk. - Manually creates a synchronous :doc:`uproot4.source.chunk.Chunk`. + Manually creates a synchronous :py:class:`~uproot4.source.chunk.Chunk`. """ future = uproot4.source.futures.NoFuture(data) return Chunk(source, 0, len(data), future) @@ -310,7 +310,7 @@ def __contains__(self, range): def wait(self): """ Explicitly wait until the chunk is filled (the - :doc:`uproot4.source.chunk.Chunk.future` completes). + :py:attr:`~uproot4.source.chunk.Chunk.future` completes). """ if self._raw_data is None: self._raw_data = numpy.frombuffer(self._future.result(), dtype=self._dtype) @@ -331,7 +331,7 @@ def raw_data(self): Data from the Source as a ``numpy.ndarray`` of ``numpy.uint8``. This method will wait until the chunk is filled (the - :doc:`uproot4.source.chunk.Chunk.future` completes), if it isn't + :py:attr:`~uproot4.source.chunk.Chunk.future` completes), if it isn't already. """ self.wait() @@ -343,20 +343,20 @@ def get(self, start, stop, cursor, context): start (int): Seek position of the first byte to include. stop (int): Seek position of the first byte to exclude (one greater than the last byte to include). - cursor (:doc:`uproot4.source.cursor.Cursor`): A pointer to the + cursor (:py:class:`~uproot4.source.cursor.Cursor`): A pointer to the current position in this chunk. context (dict): Auxiliary data used in deserialization. - Returns a subinterval of the :doc:`uproot4.source.chunk.Chunk.raw_data` + Returns a subinterval of the :py:attr:`~uproot4.source.chunk.Chunk.raw_data` as a ``numpy.ndarray`` of ``numpy.uint8``. Note that this ``start`` and ``stop`` are in the same coordinate - system as the :doc:`uproot4.source.chunk.Chunk.start` and - :doc:`uproot4.source.chunk.Chunk.stop`. That is, to get the whole + system as the :py:attr:`~uproot4.source.chunk.Chunk.start` and + :py:attr:`~uproot4.source.chunk.Chunk.stop`. That is, to get the whole chunk, use ``start=chunk.start`` and ``stop=chunk.stop``. This method will wait until the chunk is filled (the - :doc:`uproot4.source.chunk.Chunk.future` completes), if it isn't + :py:attr:`~uproot4.source.chunk.Chunk.future` completes), if it isn't already. """ self.wait() @@ -382,20 +382,20 @@ def remainder(self, start, cursor, context): """ Args: start (int): Seek position of the first byte to include. - cursor (:doc:`uproot4.source.cursor.Cursor`): A pointer to the + cursor (:py:class:`~uproot4.source.cursor.Cursor`): A pointer to the current position in this chunk. context (dict): Auxiliary data used in deserialization. - Returns a subinterval of the :doc:`uproot4.source.chunk.Chunk.raw_data` + Returns a subinterval of the :py:attr:`~uproot4.source.chunk.Chunk.raw_data` as a ``numpy.ndarray`` of ``numpy.uint8`` from ``start`` to the end of the chunk. Note that this ``start`` is in the same coordinate system as the - :doc:`uproot4.source.chunk.Chunk.start`. That is, to get the whole + :py:attr:`~uproot4.source.chunk.Chunk.start`. That is, to get the whole chunk, use ``start=chunk.start``. This method will wait until the chunk is filled (the - :doc:`uproot4.source.chunk.Chunk.future` completes), if it isn't + :py:attr:`~uproot4.source.chunk.Chunk.future` completes), if it isn't already. """ self.wait() diff --git a/uproot4/source/cursor.py b/uproot4/source/cursor.py index e88d3898b..85ec0b4b2 100644 --- a/uproot4/source/cursor.py +++ b/uproot4/source/cursor.py @@ -1,8 +1,8 @@ # BSD 3-Clause License; see https://github.com/scikit-hep/uproot4/blob/master/LICENSE """ -Defines the :doc:`uproot4.source.cursor.Cursor`, which maintains a thread-local -pointer into a :doc:`uproot.source.chunk.Chunk` and performs the lowest level +Defines the :py:class:`~uproot4.source.cursor.Cursor`, which maintains a thread-local +pointer into a :py:class:`~uproot.source.chunk.Chunk` and performs the lowest level of interpretation (numbers, strings, raw arrays, etc.). """ @@ -29,17 +29,17 @@ class Cursor(object): """ Args: index (int): Global seek position in the ROOT file or local position - in an uncompressed :doc:`uproot4.source.chunk.Chunk`. + in an uncompressed :py:class:`~uproot4.source.chunk.Chunk`. origin (int): Zero-point for numerical keys in ``refs``. refs (None or dict): References to data already read in - :doc:`uproot4.deserialization.read_object_any`. + :py:func:`~uproot4.deserialization.read_object_any`. Represents a seek point in a ROOT file, which may be held for later reference or advanced while interpreting data from a - :doc:`uproot4.source.chunk.Chunk`. + :py:class:`~uproot4.source.chunk.Chunk`. A cursor also holds references to previously read data that might be - requested by :doc:`uproot4.deserialization.read_object_any`. + requested by :py:func:`~uproot4.deserialization.read_object_any`. """ def __init__(self, index, origin=0, refs=None): @@ -70,7 +70,7 @@ def __repr__(self): def index(self): """ Global seek position in the ROOT file or local position in an - uncompressed :doc:`uproot4.source.chunk.Chunk`. + uncompressed :py:class:`~uproot4.source.chunk.Chunk`. """ return self._index @@ -78,7 +78,7 @@ def index(self): def origin(self): """ Zero-point for numerical keys in - :doc:`uproot4.source.cursor.Cursor.refs`. + :py:attr:`~uproot4.source.cursor.Cursor.refs`. """ return self._origin @@ -86,7 +86,7 @@ def origin(self): def refs(self): """ References to data already read in - :doc:`uproot4.deserialization.read_object_any`. + :py:func:`~uproot4.deserialization.read_object_any`. """ if self._refs is None: self._refs = {} @@ -94,9 +94,9 @@ def refs(self): def displacement(self, other=None): """ - The number of bytes between this :doc:`uproot4.source.cursor.Cursor` - and its :doc:`uproot4.source.cursor.Cursor.origin` (if None) - or the ``other`` :doc:`uproot4.source.cursor.Cursor` (if provided). + The number of bytes between this :py:class:`~uproot4.source.cursor.Cursor` + and its :py:attr:`~uproot4.source.cursor.Cursor.origin` (if None) + or the ``other`` :py:class:`~uproot4.source.cursor.Cursor` (if provided). If the displacement is positive, ``self`` is later in the file than the ``origin`` or ``other``; if negative, it is earlier. @@ -108,8 +108,8 @@ def displacement(self, other=None): def copy(self, link_refs=True): """ - Returns a copy of this :doc:`uproot4.source.cursor.Cursor`. If - ``link_refs`` is True, any :doc:`uproot4.source.cursor.Cursor.refs` + Returns a copy of this :py:class:`~uproot4.source.cursor.Cursor`. If + ``link_refs`` is True, any :py:attr:`~uproot4.source.cursor.Cursor.refs` will be *referenced*, rather than *copied*. """ if link_refs or self._refs is None: @@ -119,21 +119,21 @@ def copy(self, link_refs=True): def move_to(self, index): """ - Move the :doc:`uproot4.source.cursor.Cursor.index` to a specified seek + Move the :py:attr:`~uproot4.source.cursor.Cursor.index` to a specified seek position. """ self._index = index def skip(self, num_bytes): """ - Move the :doc:`uproot4.source.cursor.Cursor.index` forward + Move the :py:attr:`~uproot4.source.cursor.Cursor.index` forward ``num_bytes``. """ self._index += num_bytes def skip_after(self, obj): """ - Move the :doc:`uproot4.source.cursor.Cursor.index` just after an object + Move the :py:attr:`~uproot4.source.cursor.Cursor.index` just after an object that has a starting ``obj.cursor`` and an expected ``obj.num_bytes``. """ start_cursor = getattr(obj, "cursor", None) @@ -152,13 +152,13 @@ def skip_after(self, obj): def skip_over(self, chunk, context): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. context (dict): Auxiliary data used in deserialization. - Move the :doc:`uproot4.source.cursor.Cursor.index` to a seek position + Move the :py:attr:`~uproot4.source.cursor.Cursor.index` to a seek position beyond the serialized data for an object that can be interpreted with - :doc:`uproot4.deserialization.numbytes_version`. + :py:func:`~uproot4.deserialization.numbytes_version`. Returns True if successful (cursor has moved), False otherwise (cursor has NOT moved). @@ -175,16 +175,16 @@ def skip_over(self, chunk, context): def fields(self, chunk, format, context, move=True): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. format (``struct.Struct``): Specification to interpret the bytes of data. context (dict): Auxiliary data used in deserialization. move (bool): If True, move the - :doc:`uproot4.source.cursor.Cursor.index` past the fields; + :py:attr:`~uproot4.source.cursor.Cursor.index` past the fields; otherwise, leave it where it is. - Interpret data at this :doc:`uproot4.source.cursor.Cursor.index` with a + Interpret data at this :py:attr:`~uproot4.source.cursor.Cursor.index` with a specified format. Returns a tuple of data whose types and length are determined by the ``format``. """ @@ -197,16 +197,16 @@ def fields(self, chunk, format, context, move=True): def field(self, chunk, format, context, move=True): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. format (``struct.Struct``): Specification to interpret the bytes of data. context (dict): Auxiliary data used in deserialization. move (bool): If True, move the - :doc:`uproot4.source.cursor.Cursor.index` past the fields; + :py:attr:`~uproot4.source.cursor.Cursor.index` past the fields; otherwise, leave it where it is. - Interpret data at this :doc:`uproot4.source.cursor.Cursor.index` with a + Interpret data at this :py:attr:`~uproot4.source.cursor.Cursor.index` with a format that only specifies one field, returning a single item instead of a tuple. """ @@ -219,14 +219,14 @@ def field(self, chunk, format, context, move=True): def double32(self, chunk, context, move=True): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. context (dict): Auxiliary data used in deserialization. move (bool): If True, move the - :doc:`uproot4.source.cursor.Cursor.index` past the fields; + :py:attr:`~uproot4.source.cursor.Cursor.index` past the fields; otherwise, leave it where it is. - Interpret data at this :doc:`uproot4.source.cursor.Cursor.index` as + Interpret data at this :py:attr:`~uproot4.source.cursor.Cursor.index` as ROOT's ``Double32_t`` type, returning the Python ``float``. """ # https://github.com/root-project/root/blob/e87a6311278f859ca749b491af4e9a2caed39161/io/io/src/TBufferFile.cxx#L448-L464 @@ -239,15 +239,15 @@ def double32(self, chunk, context, move=True): def float16(self, chunk, num_bits, context, move=True): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. num_bits (int): Number of bits in the mantissa. context (dict): Auxiliary data used in deserialization. move (bool): If True, move the - :doc:`uproot4.source.cursor.Cursor.index` past the fields; + :py:attr:`~uproot4.source.cursor.Cursor.index` past the fields; otherwise, leave it where it is. - Interpret data at this :doc:`uproot4.source.cursor.Cursor.index` as + Interpret data at this :py:attr:`~uproot4.source.cursor.Cursor.index` as ROOT's ``Float16_t`` type, returning the Python ``float``. """ # https://github.com/root-project/root/blob/e87a6311278f859ca749b491af4e9a2caed39161/io/io/src/TBufferFile.cxx#L432-L442 @@ -272,15 +272,15 @@ def float16(self, chunk, num_bits, context, move=True): def bytes(self, chunk, length, context, move=True): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. length (int): Number of bytes to retrieve. context (dict): Auxiliary data used in deserialization. move (bool): If True, move the - :doc:`uproot4.source.cursor.Cursor.index` past the fields; + :py:attr:`~uproot4.source.cursor.Cursor.index` past the fields; otherwise, leave it where it is. - Interpret data at this :doc:`uproot4.source.cursor.Cursor.index` as raw + Interpret data at this :py:attr:`~uproot4.source.cursor.Cursor.index` as raw bytes with a given ``length``. """ start = self._index @@ -292,16 +292,16 @@ def bytes(self, chunk, length, context, move=True): def array(self, chunk, length, dtype, context, move=True): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. length (int): Number of bytes to retrieve. dtype (``numpy.dtype``): Data type for the array. context (dict): Auxiliary data used in deserialization. move (bool): If True, move the - :doc:`uproot4.source.cursor.Cursor.index` past the fields; + :py:attr:`~uproot4.source.cursor.Cursor.index` past the fields; otherwise, leave it where it is. - Interpret data at this :doc:`uproot4.source.cursor.Cursor.index` as a + Interpret data at this :py:attr:`~uproot4.source.cursor.Cursor.index` as a one-dimensional array with a given ``length`` and ``dtype``. """ start = self._index @@ -316,14 +316,14 @@ def array(self, chunk, length, dtype, context, move=True): def bytestring(self, chunk, context, move=True): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. context (dict): Auxiliary data used in deserialization. move (bool): If True, move the - :doc:`uproot4.source.cursor.Cursor.index` past the fields; + :py:attr:`~uproot4.source.cursor.Cursor.index` past the fields; otherwise, leave it where it is. - Interpret data at this :doc:`uproot4.source.cursor.Cursor.index` as a + Interpret data at this :py:attr:`~uproot4.source.cursor.Cursor.index` as a bytestring. The first byte is taken to be the length of the subsequent string unless @@ -351,14 +351,14 @@ def bytestring(self, chunk, context, move=True): def string(self, chunk, context, move=True): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. context (dict): Auxiliary data used in deserialization. move (bool): If True, move the - :doc:`uproot4.source.cursor.Cursor.index` past the fields; + :py:attr:`~uproot4.source.cursor.Cursor.index` past the fields; otherwise, leave it where it is. - Interpret data at this :doc:`uproot4.source.cursor.Cursor.index` as a + Interpret data at this :py:attr:`~uproot4.source.cursor.Cursor.index` as a UTF-8 encoded string. The first byte is taken to be the length of the subsequent string unless @@ -374,15 +374,15 @@ def string(self, chunk, context, move=True): def bytestring_with_length(self, chunk, context, length, move=True): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. context (dict): Auxiliary data used in deserialization. length (int): Number of bytes in the bytestring. move (bool): If True, move the - :doc:`uproot4.source.cursor.Cursor.index` past the fields; + :py:attr:`~uproot4.source.cursor.Cursor.index` past the fields; otherwise, leave it where it is. - Interpret data at this :doc:`uproot4.source.cursor.Cursor.index` as a + Interpret data at this :py:attr:`~uproot4.source.cursor.Cursor.index` as a bytestring. """ start = self._index @@ -398,15 +398,15 @@ def bytestring_with_length(self, chunk, context, length, move=True): def string_with_length(self, chunk, context, length, move=True): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. context (dict): Auxiliary data used in deserialization. length (int): Number of bytes in the string. move (bool): If True, move the - :doc:`uproot4.source.cursor.Cursor.index` past the fields; + :py:attr:`~uproot4.source.cursor.Cursor.index` past the fields; otherwise, leave it where it is. - Interpret data at this :doc:`uproot4.source.cursor.Cursor.index` as a + Interpret data at this :py:attr:`~uproot4.source.cursor.Cursor.index` as a UTF-8 encoded string. """ out = self.bytestring_with_length(chunk, context, length, move=move) @@ -418,14 +418,14 @@ def string_with_length(self, chunk, context, length, move=True): def classname(self, chunk, context, move=True): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Buffer of contiguous data - from the file :doc:`uproot4.source.chunk.Source`. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Buffer of contiguous data + from the file :py:class:`~uproot4.source.chunk.Source`. context (dict): Auxiliary data used in deserialization. move (bool): If True, move the - :doc:`uproot4.source.cursor.Cursor.index` past the fields; + :py:attr:`~uproot4.source.cursor.Cursor.index` past the fields; otherwise, leave it where it is. - Interpret data at this :doc:`uproot4.source.cursor.Cursor.index` as a + Interpret data at this :py:attr:`~uproot4.source.cursor.Cursor.index` as a null-terminated, UTF-8 encoded string. """ remainder = chunk.remainder(self._index, self, context) @@ -467,12 +467,12 @@ def debug( ): """ Args: - chunk (:doc:`uproot4.source.chunk.Chunk`): Data to examine. + chunk (:py:class:`~uproot4.source.chunk.Chunk`): Data to examine. context (dict): Auxiliary data used in deserialization. limit_bytes (None or int): Number of bytes to limit the output to. A line of debugging output (without any ``offset``) is 20 bytes, so multiples of 20 show full lines. If None, everything is - shown to the end of the :doc:`uproot4.source.chunk.Chunk`, + shown to the end of the :py:class:`~uproot4.source.chunk.Chunk`, which might be large. dtype (None, ``numpy.dtype``, or its constructor argument): If None, present only the bytes as decimal values (0-255). Otherwise, @@ -492,7 +492,7 @@ def debug( Example output with ``dtype=">f4"`` and ``offset=3``. - .. code-block:: raw + .. code-block:: --+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+---+- 123 123 123 63 140 204 205 64 12 204 205 64 83 51 51 64 140 204 205 64 diff --git a/uproot4/source/file.py b/uproot4/source/file.py index 62888d036..edd05cf0b 100644 --- a/uproot4/source/file.py +++ b/uproot4/source/file.py @@ -3,13 +3,13 @@ """ Physical layer for local files. -Defines a :doc:`uproot4.source.file.FileResource` (wrapped Python file handle) -and two sources: :doc:`uproot4.source.file.MultithreadedFileSource` and -:doc:`uproot4.source.file.MemmapSource`, which provide thread-safe local +Defines a :py:class:`~uproot4.source.file.FileResource` (wrapped Python file handle) +and two sources: :py:class:`~uproot4.source.file.MultithreadedFileSource` and +:py:class:`~uproot4.source.file.MemmapSource`, which provide thread-safe local file readers using many file handles or a memory-mapped file, respectively. If the filesystem or operating system does not support memory-mapped files, the -:doc:`uproot4.source.file.MultithreadedFileSource` is an automatic fallback. +:py:class:`~uproot4.source.file.MultithreadedFileSource` is an automatic fallback. """ from __future__ import absolute_import @@ -28,7 +28,7 @@ class FileResource(uproot4.source.chunk.Resource): Args: file_path (str): The filesystem path of the file to open. - A :doc:`uproot4.source.chunk.Resource` for a simple file handle. + A :py:class:`~uproot4.source.chunk.Resource` for a simple file handle. """ def __init__(self, file_path): @@ -71,14 +71,14 @@ def get(self, start, stop): def future(source, start, stop): """ Args: - source (:doc:`uproot4.source.chunk.MultithreadedFileSource`): The + source (:py:class:`~uproot4.source.chunk.MultithreadedFileSource`): The data source. start (int): Seek position of the first byte to include. stop (int): Seek position of the first byte to exclude (one greater than the last byte to include). - Returns a :doc:`uproot4.source.futures.ResourceFuture` that calls - :doc:`uproot4.source.file.FileResource.get` with ``start`` and ``stop``. + Returns a :py:class:`~uproot4.source.futures.ResourceFuture` that calls + :py:meth:`~uproot4.source.file.FileResource.get` with ``start`` and ``stop``. """ def task(resource): @@ -93,7 +93,7 @@ class MemmapSource(uproot4.source.chunk.Source): file_path (str): The filesystem path of the file to open. options: Must include ``"num_fallback_workers"``. - A :doc:`uproot4.source.chunk.Source` that manages one memory-mapped file. + A :py:class:`~uproot4.source.chunk.Source` that manages one memory-mapped file. """ _dtype = uproot4.source.chunk.Chunk._dtype @@ -175,10 +175,10 @@ def file(self): @property def fallback(self): """ - If None, the :doc:`uproot4.source.file.MemmapSource.file` opened + If None, the :py:attr:`~uproot4.source.file.MemmapSource.file` opened successfully and no fallback is needed. - Otherwise, this is a :doc:`uproot4.source.file.MultithreadedFileSource` + Otherwise, this is a :py:class:`~uproot4.source.file.MultithreadedFileSource` to which all requests are forwarded. """ return self._fallback @@ -229,8 +229,8 @@ class MultithreadedFileSource(uproot4.source.chunk.MultithreadedSource): file_path (str): The filesystem path of the file to open. options: Must include ``"num_workers"``. - A :doc:`uproot4.source.chunk.MultithreadedSource` that manages many - :doc:`uproot4.source.file.FileResource` objects. + A :py:class:`~uproot4.source.chunk.MultithreadedSource` that manages many + :py:class:`~uproot4.source.file.FileResource` objects. """ ResourceClass = FileResource diff --git a/uproot4/source/futures.py b/uproot4/source/futures.py index 0c6509e35..909dfdf83 100644 --- a/uproot4/source/futures.py +++ b/uproot4/source/futures.py @@ -3,18 +3,18 @@ """ Defines a Python-like Future and Executor for Uproot in three levels: -1. :doc:`uproot4.source.futures.NoFuture` and - :doc:`uproot4.source.futures.TrivialExecutor`: interface only, all activity +1. :py:class:`~uproot4.source.futures.NoFuture` and + :py:class:`~uproot4.source.futures.TrivialExecutor`: interface only, all activity is synchronous. -2. :doc:`uproot4.source.futures.Future`, :doc:`uproot4.source.futures.Worker`, - and :doc:`uproot4.source.futures.ThreadPoolExecutor`: similar to Python's +2. :py:class:`~uproot4.source.futures.Future`, :py:class:`~uproot4.source.futures.Worker`, + and :py:class:`~uproot4.source.futures.ThreadPoolExecutor`: similar to Python's own Future, Thread, and ThreadPoolExecutor, though only a minimal implementation is provided. These exist to unify behavior between Python 2 and 3 and provide a base class for the following. -3. :doc:`uproot4.source.futures.ResourceFuture`, - :doc:`uproot4.source.futures.ResourceWorker`, - and :doc:`uproot4.source.futures.ResourceThreadPoolExecutor`: like the above - except that a :doc:`uproot4.source.chunk.Resource` is associated with every +3. :py:class:`~uproot4.source.futures.ResourceFuture`, + :py:class:`~uproot4.source.futures.ResourceWorker`, + and :py:class:`~uproot4.source.futures.ResourceThreadPoolExecutor`: like the above + except that a :py:class:`~uproot4.source.chunk.Resource` is associated with every worker. When the threads are shut down, the resources (i.e. file handles) are released. @@ -51,7 +51,7 @@ def delayed_raise(exception_class, exception_value, traceback): class NoFuture(object): """ - Formally satisfies the interface for a :doc:`uproot4.source.futures.Future` + Formally satisfies the interface for a :py:class:`~uproot4.source.futures.Future` object, but it is already complete at the time when it is constructed. """ @@ -68,8 +68,8 @@ def result(self, timeout=None): class TrivialExecutor(object): """ Formally satisfies the interface for a - :doc:`uproot4.source.futures.ThreadPoolExecutor`, but the - :doc:`uproot4.source.futures.TrivialExecutor.submit` method computes its + :py:class:`~uproot4.source.futures.ThreadPoolExecutor`, but the + :py:meth:`~uproot4.source.futures.TrivialExecutor.submit` method computes its ``task`` synchronously. """ @@ -101,7 +101,7 @@ class Future(object): Like Python 3 ``concurrent.futures.Future`` except that it has only the subset of the interface Uproot needs and is available in Python 2. - The :doc:`uproot4.source.futures.ResourceFuture` extends this class. + The :py:class:`~uproot4.source.futures.ResourceFuture` extends this class. """ def __init__(self, task, args): @@ -137,12 +137,12 @@ class Worker(threading.Thread): """ Args: work_queue (``queue.Queue``): The worker calls ``get`` on this queue - for tasks in the form of :doc:`uproot4.source.futures.Future` + for tasks in the form of :py:class:`~uproot4.source.futures.Future` objects and runs them. If it ever gets a None value, the thread is stopped. A ``threading.Thread`` for the - :doc:`uproot4.source.futures.ThreadPoolExecutor`. + :py:class:`~uproot4.source.futures.ThreadPoolExecutor`. """ def __init__(self, work_queue): @@ -154,15 +154,15 @@ def __init__(self, work_queue): def work_queue(self): """ The worker calls ``get`` on this queue for tasks in the form of - :doc:`uproot4.source.futures.Future` objects and runs them. If it ever + :py:class:`~uproot4.source.futures.Future` objects and runs them. If it ever gets a None value, the thread is stopped. """ return self._work_queue def run(self): """ - Listens to the :doc:`uproot4.source.futures.Worker.work_queue` and - executes each :doc:`uproot4.source.futures.Future` it receives until it + Listens to the :py:attr:`~uproot4.source.futures.Worker.work_queue` and + executes each :py:class:`~uproot4.source.futures.Future` it receives until it receives None. """ while True: @@ -182,7 +182,7 @@ class ThreadPoolExecutor(object): Like Python 3 ``concurrent.futures.ThreadPoolExecutor`` except that it has only the subset of the interface Uproot needs and is available in Python 2. - The :doc:`uproot4.source.futures.ResourceThreadPoolExecutor` extends this + The :py:class:`~uproot4.source.futures.ResourceThreadPoolExecutor` extends this class. """ @@ -217,15 +217,15 @@ def num_workers(self): @property def workers(self): """ - A list of workers (:doc:`uproot4.source.futures.Worker`). + A list of workers (:py:class:`~uproot4.source.futures.Worker`). """ return self._workers def submit(self, task, *args): """ Pass the ``task`` and ``args`` onto the workers' - :doc:`uproot4.source.futures.Worker.work_queue` as a - :doc:`uproot4.source.futures.Future` so that it will be executed when + :py:attr:`~uproot4.source.futures.Worker.work_queue` as a + :py:class:`~uproot4.source.futures.Future` so that it will be executed when one is available. """ future = Future(task, args) @@ -234,8 +234,8 @@ def submit(self, task, *args): def shutdown(self, wait=True): """ - Stop every :doc:`uproot4.source.futures.Worker` by putting None - on the :doc:`uproot4.source.futures.Worker.work_queue` until none of + Stop every :py:class:`~uproot4.source.futures.Worker` by putting None + on the :py:attr:`~uproot4.source.futures.Worker.work_queue` until none of them satisfy ``worker.is_alive()``. """ while True: @@ -255,11 +255,11 @@ class ResourceFuture(Future): """ Args: task (function): The function to evaluate with a - :doc:`uproot4.source.chunk.Resource` as its first argument. + :py:class:`~uproot4.source.chunk.Resource` as its first argument. - A :doc:`uproot4.source.futures.Future` that uses the - :doc:`uproot4.source.chunk.Resource` associated with the - :doc:`uproot4.source.futures.ResourceWorker` that runs it. + A :py:class:`~uproot4.source.futures.Future` that uses the + :py:class:`~uproot4.source.chunk.Resource` associated with the + :py:class:`~uproot4.source.futures.ResourceWorker` that runs it. """ def __init__(self, task): @@ -290,14 +290,14 @@ class ResourceWorker(Worker): """ Args: work_queue (``queue.Queue``): The worker calls ``get`` on this queue - for tasks in the form of :doc:`uproot4.source.futures.Future` + for tasks in the form of :py:class:`~uproot4.source.futures.Future` objects and runs them. If it ever gets a None value, the thread is stopped. - A :doc:`uproot4.source.futures.Worker` that is bound to a - :doc:`uproot4.source.chunk.Resource`. This - :doc:`uproot4.source.futures.ResourceWorker.resource` is the first argument - passed to each :doc:`uproot4.source.futures.ResourceFuture` that it + A :py:class:`~uproot4.source.futures.Worker` that is bound to a + :py:class:`~uproot4.source.chunk.Resource`. This + :py:attr:`~uproot4.source.futures.ResourceWorker.resource` is the first argument + passed to each :py:class:`~uproot4.source.futures.ResourceFuture` that it executes. """ @@ -308,15 +308,15 @@ def __init__(self, work_queue, resource): @property def resource(self): """ - The :doc:`uproot4.source.chunk.Resource` that is bound to this worker. + The :py:class:`~uproot4.source.chunk.Resource` that is bound to this worker. """ return self._resource def run(self): """ - Listens to the :doc:`uproot4.source.futures.ResourceWorker.work_queue` - and executes each :doc:`uproot4.source.futures.ResourceFuture` it - receives (with :doc:`uproot4.source.futures.ResourceWorker.resource` as + Listens to the :py:attr:`~uproot4.source.futures.ResourceWorker.work_queue` + and executes each :py:class:`~uproot4.source.futures.ResourceFuture` it + receives (with :py:attr:`~uproot4.source.futures.ResourceWorker.resource` as its first argument) until it receives None. """ while True: @@ -330,10 +330,10 @@ def run(self): class ResourceThreadPoolExecutor(ThreadPoolExecutor): """ Args: - resources (list of :doc:`uproot4.source.chunk.Resource`): Resources to - wrap as :doc:`uproot4.source.futures.ResourceFuture` objects. + resources (list of :py:class:`~uproot4.source.chunk.Resource`): Resources to + wrap as :py:class:`~uproot4.source.futures.ResourceFuture` objects. - A :doc:`uproot4.source.futures.ThreadPoolExecutor` whose workers are bound + A :py:class:`~uproot4.source.futures.ThreadPoolExecutor` whose workers are bound to resources, such as file handles. """ @@ -358,9 +358,9 @@ def __repr__(self): def submit(self, future): """ Pass the ``task`` onto the workers' - :doc:`uproot4.source.futures.ResourceWorker.work_queue` as a - :doc:`uproot4.source.futures.ResourceFuture` so that it will be - executed with its :doc:`uproot4.source.futures.ResourceFuture.resource` + :py:attr:`~uproot4.source.futures.ResourceWorker.work_queue` as a + :py:class:`~uproot4.source.futures.ResourceFuture` so that it will be + executed with its :py:attr:`~uproot4.source.futures.ResourceFuture.resource` when that worker is available. """ assert isinstance(future, ResourceFuture) @@ -375,17 +375,17 @@ def submit(self, future): def close(self): """ - Stops all :doc:`uproot4.source.futures.ResourceWorker` threads and frees - their :doc:`uproot4.source.futures.ResourceWorker.resource`. + Stops all :py:class:`~uproot4.source.futures.ResourceWorker` threads and frees + their :py:attr:`~uproot4.source.futures.ResourceWorker.resource`. """ self.__exit__(None, None, None) @property def closed(self): """ - True if the :doc:`uproot4.source.futures.ResourceWorker` threads have + True if the :py:class:`~uproot4.source.futures.ResourceWorker` threads have been stopped and their - :doc:`uproot4.source.futures.ResourceWorker.resource` freed. + :py:attr:`~uproot4.source.futures.ResourceWorker.resource` freed. """ return self._closed diff --git a/uproot4/source/http.py b/uproot4/source/http.py index 058989ed4..76ca43f1e 100644 --- a/uproot4/source/http.py +++ b/uproot4/source/http.py @@ -3,13 +3,13 @@ """ Physical layer for remote files, accessed via HTTP(S). -Defines a :doc:`uproot4.source.http.HTTPResource` (stateless) and two sources: -:doc:`uproot4.source.http.MultithreadedHTTPSource` and -:doc:`uproot4.source.http.HTTPSource`. The multi-threaded source only requires +Defines a :py:class:`~uproot4.source.http.HTTPResource` (stateless) and two sources: +:py:class:`~uproot4.source.http.MultithreadedHTTPSource` and +:py:class:`~uproot4.source.http.HTTPSource`. The multi-threaded source only requires the server to support byte range requests (code 206), but the general source requires the server to support multi-part byte range requests. If the server -does not support multi-part GET, :doc:`uproot4.source.http.HTTPSource` -automatically falls back to :doc:`uproot4.source.http.MultithreadedHTTPSource`. +does not support multi-part GET, :py:class:`~uproot4.source.http.HTTPSource` +automatically falls back to :py:class:`~uproot4.source.http.MultithreadedHTTPSource`. Despite the name, both sources support secure HTTPS (selected by URL scheme). """ @@ -117,7 +117,7 @@ class HTTPResource(uproot4.source.chunk.Resource): file_path (str): A URL of the file to open. timeout (None or float): An optional timeout in seconds. - A :doc:`uproot4.source.chunk.Resource` for HTTP(S) connections. + A :py:class:`~uproot4.source.chunk.Resource` for HTTP(S) connections. For simplicity, this resource does not manage a live ``http.client.HTTPConnection`` or ``http.client.HTTPSConnection``, though @@ -181,14 +181,14 @@ def get(self, connection, start, stop): def future(source, start, stop): """ Args: - source (:doc:`uproot4.source.chunk.HTTPSource` or :doc:`uproot4.source.chunk.MultithreadedHTTPSource`): The + source (:py:class:`~uproot4.source.chunk.HTTPSource` or :py:class:`~uproot4.source.chunk.MultithreadedHTTPSource`): The data source. start (int): Seek position of the first byte to include. stop (int): Seek position of the first byte to exclude (one greater than the last byte to include). - Returns a :doc:`uproot4.source.futures.ResourceFuture` that calls - :doc:`uproot4.source.file.HTTPResource.get` with ``start`` and ``stop``. + Returns a :py:class:`~uproot4.source.futures.ResourceFuture` that calls + :py:meth:`~uproot4.source.file.HTTPResource.get` with ``start`` and ``stop``. """ connection = make_connection(source.parsed_url, source.timeout) connection.request( @@ -206,25 +206,25 @@ def task(resource): def multifuture(source, ranges, futures, results): u""" Args: - source (:doc:`uproot4.source.chunk.HTTPSource`): The data source. + source (:py:class:`~uproot4.source.chunk.HTTPSource`): The data source. ranges (list of (int, int) 2-tuples): Intervals to fetch as (start, stop) pairs in a single request, if possible. - futures (dict of (int, int) \u2192 :doc:`uproot4.source.futures.ResourceFuture`): Mapping + futures (dict of (int, int) \u2192 :py:class:`~uproot4.source.futures.ResourceFuture`): Mapping from (start, stop) to a future that is awaiting its result. results (dict of (int, int) \u2192 None or ``numpy.ndarray`` of ``numpy.uint8``): Mapping from (start, stop) to None or results. - Returns a :doc:`uproot4.source.futures.ResourceFuture` that attempts + Returns a :py:class:`~uproot4.source.futures.ResourceFuture` that attempts to perform an HTTP(S) multipart GET, filling ``results`` to satisfy - the individual :doc:`uproot4.source.chunk.Chunk`'s ``futures`` with + the individual :py:class:`~uproot4.source.chunk.Chunk`'s ``futures`` with its multipart response. If the server does not support multipart GET, that same future - sets :doc:`uproot4.source.chunk.HTTPSource.fallback` and retries the + sets :py:attr:`~uproot4.source.chunk.HTTPSource.fallback` and retries the request without multipart, using a - :doc:`uproot4.source.http.MultithreadedHTTPSource` to fill the same + :py:class:`~uproot4.source.http.MultithreadedHTTPSource` to fill the same ``results`` and ``futures``. Subsequent attempts would immediately - use the :doc:`uproot4.source.chunk.HTTPSource.fallback`. + use the :py:attr:`~uproot4.source.chunk.HTTPSource.fallback`. """ connection = make_connection(source.parsed_url, source.timeout) @@ -263,7 +263,7 @@ def task(resource): def is_multipart_supported(self, ranges, response): """ - Helper function for :doc:`uproot4.source.http.HTTPResource.multifuture` + Helper function for :py:meth:`~uproot4.source.http.HTTPResource.multifuture` to check for multipart GET support. """ if response.status != 206: @@ -280,7 +280,7 @@ def is_multipart_supported(self, ranges, response): def handle_no_multipart(self, source, ranges, futures, results): """ - Helper function for :doc:`uproot4.source.http.HTTPResource.multifuture` + Helper function for :py:meth:`~uproot4.source.http.HTTPResource.multifuture` to handle a lack of multipart GET support. """ source._set_fallback() @@ -295,7 +295,7 @@ def handle_no_multipart(self, source, ranges, futures, results): def handle_multipart(self, source, futures, results, response): """ - Helper function for :doc:`uproot4.source.http.HTTPResource.multifuture` + Helper function for :py:meth:`~uproot4.source.http.HTTPResource.multifuture` to handle the multipart GET response. """ for i in uproot4._util.range(len(futures)): @@ -341,7 +341,7 @@ def handle_multipart(self, source, futures, results, response): def next_header(self, response): """ - Helper function for :doc:`uproot4.source.http.HTTPResource.multifuture` + Helper function for :py:meth:`~uproot4.source.http.HTTPResource.multifuture` to return the next header from the ``response``. """ line = response.fp.readline() @@ -364,12 +364,12 @@ def next_header(self, response): @staticmethod def partfuture(results, start, stop): """ - Returns a :doc:`uproot4.source.futures.ResourceFuture` to simply select + Returns a :py:class:`~uproot4.source.futures.ResourceFuture` to simply select the ``(start, stop)`` item from the ``results`` dict. - In :doc:`uproot4.source.http.HTTPSource.chunks`, each chunk has a - :doc:`uproot4.source.http.HTTPResource.partfuture` that are collectively - filled by a single :doc:`uproot4.source.http.HTTPResource.multifuture`. + In :py:meth:`~uproot4.source.http.HTTPSource.chunks`, each chunk has a + :py:meth:`~uproot4.source.http.HTTPResource.partfuture` that are collectively + filled by a single :py:meth:`~uproot4.source.http.HTTPResource.multifuture`. """ def task(resource): @@ -384,15 +384,15 @@ class HTTPSource(uproot4.source.chunk.Source): file_path (str): A URL of the file to open. options: Must include ``"num_fallback_workers"`` and ``"timeout"``. - A :doc:`uproot4.source.chunk.Source` that first attempts an HTTP(S) + A :py:class:`~uproot4.source.chunk.Source` that first attempts an HTTP(S) multipart GET, but if the server doesn't support it, it falls back to many HTTP(S) connections in threads - (:doc:`uproot4.source.http.MultithreadedHTTPSource). + (:py:class:`~uproot4.source.http.MultithreadedHTTPSource`). Since the multipart GET is a single request and response, it needs only one thread, but it is a background thread (a single - :doc:`uproot4.source.futures.ResourceWorker` in a - :doc:`uproot4.source.futures.ResourceThreadPoolExecutor`). + :py:class:`~uproot4.source.futures.ResourceWorker` in a + :py:class:`~uproot4.source.futures.ResourceThreadPoolExecutor`). """ ResourceClass = HTTPResource @@ -466,7 +466,7 @@ def chunks(self, ranges, notifications): @property def executor(self): """ - The :doc:`uproot4.source.futures.ResourceThreadPoolExecutor` that + The :py:class:`~uproot4.source.futures.ResourceThreadPoolExecutor` that manages this source's single background thread. """ return self._executor @@ -509,7 +509,7 @@ def fallback(self): If None, the source has not encountered an unsuccessful multipart GET and no fallback is needed yet. - Otherwise, this is a :doc:`uproot4.source.http.MultithreadedHTTPSource` + Otherwise, this is a :py:class:`~uproot4.source.http.MultithreadedHTTPSource` to which all requests are forwarded. """ return self._fallback @@ -527,8 +527,8 @@ class MultithreadedHTTPSource(uproot4.source.chunk.MultithreadedSource): file_path (str): A URL of the file to open. options: Must include ``"num_workers"`` and ``"timeout"``. - A :doc:`uproot4.source.chunk.MultithreadedSource` that manages many - :doc:`uproot4.source.http.HTTPResource` objects. + A :py:class:`~uproot4.source.chunk.MultithreadedSource` that manages many + :py:class:`~uproot4.source.http.HTTPResource` objects. """ ResourceClass = HTTPResource diff --git a/uproot4/source/object.py b/uproot4/source/object.py index 41d15f861..efabd9cda 100644 --- a/uproot4/source/object.py +++ b/uproot4/source/object.py @@ -3,8 +3,8 @@ """ Physical layer for file-like objects. -Defines a :doc:`uproot4.source.object.ObjectResource` (wrapped Python file-like -object) and one source :doc:`uproot4.source.object.ObjectSource` which always +Defines a :py:class:`~uproot4.source.object.ObjectResource` (wrapped Python file-like +object) and one source :py:class:`~uproot4.source.object.ObjectSource` which always has exactly one worker (we can't assume that the object is thread-safe). """ @@ -20,7 +20,7 @@ class ObjectResource(uproot4.source.chunk.Resource): Args: obj: The file-like object to use. - A :doc:`uproot4.source.chunk.Resource` for a file-like object. + A :py:class:`~uproot4.source.chunk.Resource` for a file-like object. This object must have the following methods: @@ -69,13 +69,13 @@ def get(self, start, stop): def future(source, start, stop): """ Args: - source (:doc:`uproot4.source.chunk.ObjectSource`): The data source. + source (:py:class:`~uproot4.source.chunk.ObjectSource`): The data source. start (int): Seek position of the first byte to include. stop (int): Seek position of the first byte to exclude (one greater than the last byte to include). - Returns a :doc:`uproot4.source.futures.ResourceFuture` that calls - :doc:`uproot4.source.object.ObjectResource.get` with ``start`` and + Returns a :py:class:`~uproot4.source.futures.ResourceFuture` that calls + :py:meth:`~uproot4.source.object.ObjectResource.get` with ``start`` and ``stop``. """ @@ -90,8 +90,8 @@ class ObjectSource(uproot4.source.chunk.MultithreadedSource): Args: obj: The file-like object to use. - A :doc:`uproot4.source.chunk.Source` for a file-like object. (Although this - is a :doc:`uproot4.source.chunk.MultithreadedSource`, it never has more or + A :py:class:`~uproot4.source.chunk.Source` for a file-like object. (Although this + is a :py:class:`~uproot4.source.chunk.MultithreadedSource`, it never has more or less than one thread.) This object must have the following methods: diff --git a/uproot4/source/xrootd.py b/uproot4/source/xrootd.py index 3e5c3a7ea..79dcc5275 100644 --- a/uproot4/source/xrootd.py +++ b/uproot4/source/xrootd.py @@ -3,11 +3,11 @@ """ Physical layer for remote files, accessed via the XRootD protocol. -Defines a :doc:`uproot4.source.http.XRootDResource` (``XRootD.File``) and two -sources: :doc:`uproot4.source.http.MultithreadedXRootDSource` and -:doc:`uproot4.source.http.XRootDSource`. The latter requires the server to +Defines a :py:class:`~uproot4.source.http.XRootDResource` (``XRootD.File``) and two +sources: :py:class:`~uproot4.source.http.MultithreadedXRootDSource` and +:py:class:`~uproot4.source.http.XRootDSource`. The latter requires the server to support vector-read requests; if not, it automatically falls back to -:doc:`uproot4.source.http.MultithreadedXRootDSource`. +:py:class:`~uproot4.source.http.MultithreadedXRootDSource`. """ from __future__ import absolute_import @@ -73,7 +73,7 @@ class XRootDResource(uproot4.source.chunk.Resource): file_path (str): A URL of the file to open. timeout (None or float): An optional timeout in seconds. - A :doc:`uproot4.source.chunk.Resource` for XRootD connections. + A :py:class:`~uproot4.source.chunk.Resource` for XRootD connections. """ def __init__(self, file_path, timeout): @@ -158,14 +158,14 @@ def get(self, start, stop): def future(source, start, stop): """ Args: - source (:doc:`uproot4.source.chunk.MultithreadedXRootDSource`): The + source (:py:class:`~uproot4.source.chunk.MultithreadedXRootDSource`): The data source. start (int): Seek position of the first byte to include. stop (int): Seek position of the first byte to exclude (one greater than the last byte to include). - Returns a :doc:`uproot4.source.futures.ResourceFuture` that calls - :doc:`uproot4.source.xrootd.XRootDResource.get` with ``start`` and + Returns a :py:class:`~uproot4.source.futures.ResourceFuture` that calls + :py:meth:`~uproot4.source.xrootd.XRootDResource.get` with ``start`` and ``stop``. """ @@ -177,12 +177,12 @@ def task(resource): @staticmethod def partfuture(results, start, stop): """ - Returns a :doc:`uproot4.source.futures.ResourceFuture` to simply select + Returns a :py:class:`~uproot4.source.futures.ResourceFuture` to simply select the ``(start, stop)`` item from the ``results`` dict. - In :doc:`uproot4.source.xrootd.XRootDSource.chunks`, each chunk has a - :doc:`uproot4.source.xrootd.XRootDResource.partfuture` that are collectively - filled by callbacks from :doc:`uproot4.source.xrootd.XRootDResource.callbacker`. + In :py:meth:`~uproot4.source.xrootd.XRootDSource.chunks`, each chunk has a + :py:meth:`~uproot4.source.xrootd.XRootDResource.partfuture` that are collectively + filled by callbacks from :py:meth:`~uproot4.source.xrootd.XRootDResource.callbacker`. """ def task(resource): @@ -212,7 +212,7 @@ class XRootDSource(uproot4.source.chunk.Source): file_path (str): A URL of the file to open. options: Must include ``"timeout"`` and ``"max_num_elements"``. - A :doc:`uproot4.source.chunk.Source` that uses XRootD's vector-read + A :py:class:`~uproot4.source.chunk.Source` that uses XRootD's vector-read to get many chunks in one request. """ @@ -294,7 +294,7 @@ def chunks(self, ranges, notifications): @property def resource(self): """ - The :doc:`uproot4.source.xrootd.XRootDResource` object. + The :py:class:`~uproot4.source.xrootd.XRootDResource` object. """ return self._resource @@ -335,8 +335,8 @@ class MultithreadedXRootDSource(uproot4.source.chunk.MultithreadedSource): file_path (str): A URL of the file to open. options: Must include ``"num_workers"`` and ``"timeout"``. - A :doc:`uproot4.source.chunk.MultithreadedSource` that manages many - :doc:`uproot4.source.xrootd.XRootDResource` objects. + A :py:class:`~uproot4.source.chunk.MultithreadedSource` that manages many + :py:class:`~uproot4.source.xrootd.XRootDResource` objects. """ ResourceClass = XRootDResource diff --git a/uproot4/streamers.py b/uproot4/streamers.py index 4726081fb..a11782000 100644 --- a/uproot4/streamers.py +++ b/uproot4/streamers.py @@ -135,7 +135,7 @@ def _ftype_to_struct(fType): class Model_TStreamerInfo(uproot4.model.Model): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerInfo``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerInfo``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -157,7 +157,7 @@ def show(self, stream=sys.stdout): Example: - .. code-block:: raw + .. code-block:: TLorentzVector (v4): TObject (v1) fP: TVector3 (TStreamerObject) @@ -193,7 +193,7 @@ def typename(self): def elements(self): """ This ``TStreamerInfo``'s list of ``TStreamerElements`` - (:doc:`uproot4.streamers.TStreamerElement`). + (:py:class:`~uproot4.streamers.TStreamerElement`). """ return self._members["fElements"] @@ -207,7 +207,7 @@ def class_version(self): def class_code(self): """ Returns Python code as a string that, when evaluated, would be a suitable - :doc:`uproot4.model.VersionedModel` for this class and version. + :py:class:`~uproot4.model.VersionedModel` for this class and version. """ read_members = [ " def read_members(self, chunk, cursor, context, file):", @@ -330,12 +330,12 @@ def class_code(self): def new_class(self, file): """ Args: - file (:doc:`uproot4.reading.ReadOnlyFile`): File to use to generate - :doc:`uproot4.model.Model` classes as needed from its - :doc:`uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` + file (:py:class:`~uproot4.reading.ReadOnlyFile`): File to use to generate + :py:class:`~uproot4.model.Model` classes as needed from its + :py:attr:`~uproot4.reading.ReadOnlyFile.streamers` and ``file_path`` for error messages. - Returns a new subclass of :doc:`uproot4.model.VersionedModel` for this + Returns a new subclass of :py:class:`~uproot4.model.VersionedModel` for this class and version. """ class_code = self.class_code() @@ -348,7 +348,7 @@ class and version. @property def file_uuid(self): """ - The unique identifier (:doc:`uproot4.reading.ReadOnlyFile`) of the file + The unique identifier (:py:class:`~uproot4.reading.ReadOnlyFile`) of the file from which this ``TStreamerInfo`` was extracted. """ return self._file.uuid @@ -356,14 +356,14 @@ def file_uuid(self): def walk_members(self, streamers): """ Args: - streamers (list of :doc:`uproot4.streamers.TStreamerInfo`): The + streamers (list of :py:class:`~uproot4.streamers.TStreamerInfo`): The complete set of ``TStreamerInfos``, probably including this one. Generator that yields all ``TStreamerElements`` - (:doc:`uproot4.streamers.TStreamerElement`) for this class and its + (:py:class:`~uproot4.streamers.TStreamerElement`) for this class and its superclasses. - The ``TStreamerBase`` elements (:doc:`uproot4.streamers.TStreamerBase`) + The ``TStreamerBase`` elements (:py:class:`~uproot4.streamers.TStreamerBase`) are not yielded, but they are extracted from ``streamers`` to include their elements. """ @@ -413,7 +413,7 @@ def _dependencies(self, streamers, out): class Model_TStreamerElement(uproot4.model.Model): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerElement``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerElement``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -467,7 +467,7 @@ def array_length(self): @property def file_uuid(self): """ - The unique identifier (:doc:`uproot4.reading.ReadOnlyFile`) of the file + The unique identifier (:py:class:`~uproot4.reading.ReadOnlyFile`) of the file from which this ``TStreamerElement`` was extracted. """ return self._file.uuid @@ -534,7 +534,7 @@ def _dependencies(self, streamers, out): class Model_TStreamerArtificial(Model_TStreamerElement): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerArtificial``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerArtificial``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -600,7 +600,7 @@ def class_code( class Model_TStreamerBase(Model_TStreamerElement): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerBase``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerBase``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -687,7 +687,7 @@ def _dependencies(self, streamers, out): class Model_TStreamerBasicPointer(Model_TStreamerElement): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerBasicPointer``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerBasicPointer``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -778,7 +778,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TStreamerBasicType(Model_TStreamerElement): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerBasicType``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerBasicType``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -986,7 +986,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TStreamerLoop(Model_TStreamerElement): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerLoop``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerLoop``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -1085,7 +1085,7 @@ def _dependencies(self, streamers, out): class Model_TStreamerSTL(Model_TStreamerElement): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerSTL``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerSTL``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -1185,7 +1185,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TStreamerSTLstring(Model_TStreamerSTL): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerSTLString``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerSTLString``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -1209,8 +1209,8 @@ def read_members(self, chunk, cursor, context, file): class TStreamerPointerTypes(object): """ A class to share code between - :doc:`uproot4.streamers.Model_TStreamerObjectAnyPointer` and - :doc:`uproot4.streamers.Model_TStreamerObjectPointer`. + :py:class:`~uproot4.streamers.Model_TStreamerObjectAnyPointer` and + :py:class:`~uproot4.streamers.Model_TStreamerObjectPointer`. """ def class_code( @@ -1284,7 +1284,7 @@ def _dependencies(self, streamers, out): class Model_TStreamerObjectAnyPointer(TStreamerPointerTypes, Model_TStreamerElement): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerObjectAnyPointer``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerObjectAnyPointer``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -1307,7 +1307,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TStreamerObjectPointer(TStreamerPointerTypes, Model_TStreamerElement): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerObjectPointer``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerObjectPointer``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -1331,9 +1331,9 @@ def read_members(self, chunk, cursor, context, file): class TStreamerObjectTypes(object): """ A class to share code between - :doc:`uproot4.streamers.Model_TStreamerObject`, - :doc:`uproot4.streamers.Model_TStreamerObjectAny`, and - :doc:`uproot4.streamers.Model_TStreamerString`. + :py:class:`~uproot4.streamers.Model_TStreamerObject`, + :py:class:`~uproot4.streamers.Model_TStreamerObjectAny`, and + :py:class:`~uproot4.streamers.Model_TStreamerString`. """ def class_code( @@ -1384,7 +1384,7 @@ def _dependencies(self, streamers, out): class Model_TStreamerObject(TStreamerObjectTypes, Model_TStreamerElement): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerObject``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerObject``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -1407,7 +1407,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TStreamerObjectAny(TStreamerObjectTypes, Model_TStreamerElement): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerObjectAny``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerObjectAny``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model @@ -1430,7 +1430,7 @@ def read_members(self, chunk, cursor, context, file): class Model_TStreamerString(TStreamerObjectTypes, Model_TStreamerElement): """ - A versionless :doc:`uproot4.model.Model` for ``TStreamerString``. + A versionless :py:class:`~uproot4.model.Model` for ``TStreamerString``. Since this model is versionless and most of its functionality is internal (not to be directly accessed by most users), it is defined on the model