├── .gitignore ├── LICENSE ├── README.rst ├── dev ├── allstreamers.c ├── streamergen.py └── streamerversions.json ├── docs ├── Makefile ├── README_107_0.png ├── README_243_0.png ├── abstraction-layers.png ├── all_file_project.pdf ├── all_file_project.png ├── all_file_project.svg ├── logscales.png ├── make.bat ├── old-tutorial.rst ├── pip-scientificlinux-uproot.pdf ├── pip-scientificlinux-uproot.png ├── root-none-muon.png ├── rootnumpy-none-muon.png ├── scaling.png ├── source │ ├── caches.rst │ ├── conf.py │ ├── index.rst │ ├── interpretation.rst │ ├── logo-300px.png │ ├── logo-600px.png │ ├── logo.svg │ ├── opening-files.rst │ ├── parallel-io.rst │ ├── root-io.rst │ └── ttree-handling.rst ├── terminology.png ├── uproot-scaling-2.png ├── uproot-scaling-2.svg ├── uproot-scaling.png └── uproot-scaling.svg ├── requirements.txt ├── setup.py ├── tests ├── README.md ├── __init__.py ├── samples │ ├── HZZ-lz4.root │ ├── HZZ-lzma.root │ ├── HZZ-objects.root │ ├── HZZ-uncompressed.root │ ├── HZZ-zlib.root │ ├── HZZ-zstd.root │ ├── HZZ.root │ ├── Zmumu-lz4.root │ ├── Zmumu-lzma.root │ ├── Zmumu-uncompressed.root │ ├── Zmumu-zlib.root │ ├── Zmumu-zstd.root │ ├── Zmumu.root │ ├── demo-double32.root │ ├── foriter.root │ ├── foriter2.root │ ├── from-geant4.root │ ├── hepdata-example.root │ ├── histograms.root │ ├── issue124.root │ ├── issue126a.root │ ├── issue126b.root │ ├── issue187.root │ ├── issue21.root │ ├── issue213.root │ ├── issue232.root │ ├── issue243-new.root │ ├── issue243.root │ ├── issue30.root │ ├── issue31.root │ ├── issue327.root │ ├── issue33.root │ ├── issue367.root │ ├── issue371.root │ ├── issue38a.root │ ├── issue38b.root │ ├── issue390.root │ ├── issue399.root │ ├── issue404.root │ ├── issue429.root │ ├── issue431.root │ ├── issue434.root │ ├── issue447.root │ ├── issue447_recursive.root │ ├── issue46.root │ ├── issue49.root │ ├── issue57.root │ ├── issue60.root │ ├── issue63.root │ ├── issue64.root │ ├── issue66.root │ ├── issue70.root │ ├── issue74.root │ ├── issue76.root │ ├── issue79.root │ ├── issue96.root │ ├── leaflist.root │ ├── make_HZZ_objects.C │ ├── make_HZZ_objects.h │ ├── mc10events.root │ ├── nesteddirs.root │ ├── ntpl001_staff.root │ ├── sample-5.23.02-uncompressed.root │ ├── sample-5.23.02-zlib.root │ ├── sample-5.24.00-uncompressed.root │ ├── sample-5.24.00-zlib.root │ ├── sample-5.25.02-uncompressed.root │ ├── sample-5.25.02-zlib.root │ ├── sample-5.26.00-uncompressed.root │ ├── sample-5.26.00-zlib.root │ ├── sample-5.27.02-uncompressed.root │ ├── sample-5.27.02-zlib.root │ ├── sample-5.28.00-uncompressed.root │ ├── sample-5.28.00-zlib.root │ ├── sample-5.29.02-uncompressed.root │ ├── sample-5.29.02-zlib.root │ ├── sample-5.30.00-lzma.root │ ├── sample-5.30.00-uncompressed.root │ ├── sample-5.30.00-zlib.root │ ├── sample-6.08.04-lzma.root │ ├── sample-6.08.04-uncompressed.root │ ├── sample-6.08.04-zlib.root │ ├── sample-6.10.05-lz4.root │ ├── sample-6.10.05-lzma.root │ ├── sample-6.10.05-uncompressed.root │ ├── sample-6.10.05-zlib.root │ ├── sample-6.14.00-lz4.root │ ├── sample-6.14.00-lzma.root │ ├── sample-6.14.00-uncompressed.root │ ├── sample-6.14.00-zlib.root │ ├── sample-6.16.00-lz4.root │ ├── sample-6.16.00-lzma.root │ ├── sample-6.16.00-uncompressed.root │ ├── sample-6.16.00-zlib.root │ ├── sample-6.18.00-lz4.root │ ├── sample-6.18.00-lzma.root │ ├── sample-6.18.00-uncompressed.root │ ├── sample-6.18.00-zlib.root │ ├── sample-6.20.04-lz4.root │ ├── sample-6.20.04-lzma.root │ ├── sample-6.20.04-uncompressed.root │ ├── sample-6.20.04-zlib.root │ ├── sample4version.C │ ├── simple.root │ ├── small-dy-nooffsets.root │ ├── small-dy-withoffsets.root │ ├── small-evnt-tree-fullsplit.root │ ├── small-evnt-tree-nosplit.root │ ├── small-flat-tree.root │ └── vectorVectorDouble.root ├── test_cache.py ├── test_compression.py ├── test_http.py ├── test_issues.py ├── test_jagged.py ├── test_rntuple.py ├── test_stlvector.py ├── test_tree.py ├── test_versions.py └── test_write.py └── uproot3 ├── __init__.py ├── _connect ├── __init__.py └── _pandas.py ├── _help.py ├── _util.py ├── cache.py ├── const.py ├── interp ├── __init__.py ├── auto.py ├── interp.py ├── jagged.py ├── numerical.py └── objects.py ├── pandas.py ├── rootio.py ├── source ├── __init__.py ├── chunked.py ├── compressed.py ├── cursor.py ├── file.py ├── http.py ├── memmap.py ├── source.py └── xrootd.py ├── tree.py ├── version.py └── write ├── TDirectory.py ├── TFile.py ├── TFree.py ├── TKey.py ├── __init__.py ├── compress.py ├── objects ├── TH.py ├── TObjString.py ├── TTree.py ├── __init__.py └── util.py ├── sink ├── __init__.py ├── cursor.py └── file.py ├── streamers.py └── util.py /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | *$py.class 5 | 6 | # C extensions 7 | *.so 8 | 9 | # Distribution / packaging 10 | .Python 11 | env/ 12 | build/ 13 | develop-eggs/ 14 | dist/ 15 | downloads/ 16 | eggs/ 17 | .eggs/ 18 | lib/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | wheels/ 24 | *.egg-info/ 25 | .installed.cfg 26 | *.egg 27 | 28 | # PyInstaller 29 | # Usually these files are written by a python script from a template 30 | # before PyInstaller builds the exe, so as to inject date/other infos into it. 31 | *.manifest 32 | *.spec 33 | 34 | # Installer logs 35 | pip-log.txt 36 | pip-delete-this-directory.txt 37 | 38 | # Unit test / coverage reports 39 | htmlcov/ 40 | .tox/ 41 | .coverage 42 | .coverage.* 43 | .cache 44 | nosetests.xml 45 | coverage.xml 46 | *.cover 47 | .hypothesis/ 48 | 49 | # Translations 50 | *.mo 51 | *.pot 52 | 53 | # Django stuff: 54 | *.log 55 | local_settings.py 56 | 57 | # Flask stuff: 58 | instance/ 59 | .webassets-cache 60 | 61 | # Scrapy stuff: 62 | .scrapy 63 | 64 | # Sphinx documentation 65 | docs/_build/ 66 | 67 | # PyBuilder 68 | target/ 69 | 70 | # Jupyter Notebook 71 | .ipynb_checkpoints 72 | 73 | # pyenv 74 | .python-version 75 | 76 | # celery beat schedule file 77 | celerybeat-schedule 78 | 79 | # SageMath parsed files 80 | *.sage.py 81 | 82 | # dotenv 83 | .env 84 | 85 | # virtualenv 86 | .venv 87 | venv/ 88 | ENV/ 89 | 90 | # Spyder project settings 91 | .spyderproject 92 | .spyproject 93 | 94 | # Rope project settings 95 | .ropeproject 96 | 97 | # mkdocs documentation 98 | /site 99 | 100 | # mypy 101 | .mypy_cache/ 102 | 103 | # Pycharm 104 | .idea/ 105 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | BSD 3-Clause License 2 | 3 | Copyright (c) 2017-2020, Jim Pivarski 4 | All rights reserved. 5 | 6 | Redistribution and use in source and binary forms, with or without 7 | modification, are permitted provided that the following conditions are met: 8 | 9 | * Redistributions of source code must retain the above copyright notice, this 10 | list of conditions and the following disclaimer. 11 | 12 | * Redistributions in binary form must reproduce the above copyright notice, 13 | this list of conditions and the following disclaimer in the documentation 14 | and/or other materials provided with the distribution. 15 | 16 | * Neither the name of the copyright holder nor the names of its 17 | contributors may be used to endorse or promote products derived from 18 | this software without specific prior written permission. 19 | 20 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 21 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 22 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 23 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 24 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 25 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 26 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 27 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 28 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 29 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 30 | -------------------------------------------------------------------------------- /dev/allstreamers.c: -------------------------------------------------------------------------------- 1 | void allstreamers(){ 2 | TFile *tfile = new TFile("dev/allstreamers.root", "RECREATE"); 3 | tfile->SetCompressionLevel(0); 4 | 5 | TH1F* hist1 = new TH1F("habla1f", "th1f title", 10, 2.1, 3.1); 6 | TH1C* hist2 = new TH1C("habla1c", "th1c title", 10, 2.1, 3.1); 7 | TH1I* hist3 = new TH1I("habla1i", "th1i title", 10, 2.1, 3.1); 8 | TH1D* hist4 = new TH1D("habla1d", "th1d title", 10, 2.1, 3.1); 9 | TH1S* hist5 = new TH1S("habla1s", "th1s title", 10, 2.1, 3.1); 10 | 11 | TH2C* hist6 = new TH2C("habla2c", "th2c title", 10, 2.1, 3.1, 5, 1.1, 2.1); 12 | TH2S* hist7 = new TH2S("habla2s", "th2s title", 10, 2.1, 3.1, 5, 1.1, 2.1); 13 | TH2I* hist8 = new TH2I("habla2i", "th2i title", 10, 2.1, 3.1, 5, 1.1, 2.1); 14 | TH2F* hist9 = new TH2F("habla2f", "th2f title", 10, 2.1, 3.1, 5, 1.1, 2.1); 15 | TH2D* hist10 = new TH2D("habla2d", "th2d title", 10, 2.1, 3.1, 5, 1.1, 2.1); 16 | 17 | TH3C* hist11 = new TH3C("habla3c", "th3c title", 10, 2.1, 3.1, 5, 1.1, 2.1, 5, 1.1, 2.1); 18 | TH3S* hist12 = new TH3S("habla3s", "th3s title", 10, 2.1, 3.1, 5, 1.1, 2.1, 5, 1.1, 2.1); 19 | TH3I* hist13 = new TH3I("habla3i", "th3i title", 10, 2.1, 3.1, 5, 1.1, 2.1, 5, 1.1, 2.1); 20 | TH3D* hist14 = new TH3D("habla3d", "th3d title", 10, 2.1, 3.1, 5, 1.1, 2.1, 5, 1.1, 2.1); 21 | TH3F* hist15 = new TH3F("habla3f", "th3f title", 10, 2.1, 3.1, 5, 1.1, 2.1, 5, 1.1, 2.1); 22 | 23 | TObjString* comment = new TObjString("Hello World"); 24 | comment->Write(); 25 | 26 | TLorentzVector v2(1., 1., 1., 1.); 27 | v2.Write(); 28 | 29 | TVector2 tvector2(5.0, 6.0); 30 | tvector2.Write(); 31 | 32 | TProfile profile1("hprof","Profile of pz versus px",100,-4,4,0,20); 33 | profile1.Write(); 34 | 35 | TProfile2D profile2("hprof2d","Profile of pz versus px and py",40,-4,4,40,-4,4,0,20); 36 | profile2.Write(); 37 | 38 | TProfile3D profile3("hprof3d","Profile of pt versus px, py and pz",40,-4,4,40,-4,4,40,0,20); 39 | profile3.Write(); 40 | 41 | TTree *t = new TTree("tvec","Tree with vectors"); 42 | 43 | int i1; 44 | double d1; 45 | float f1; 46 | Long64_t l1; 47 | char c1; 48 | short s1; 49 | bool b1; 50 | 51 | t -> Branch("intBranch", &i1); 52 | t -> Branch("doubleBranch", &d1); 53 | t -> Branch("floatBranch", &f1); 54 | t -> Branch("longBranch", &l1); 55 | t -> Branch("charBranch", &c1); 56 | t -> Branch("shortBranch", &s1); 57 | t -> Branch("boolBranch", &b1); 58 | 59 | std::vector i2; 60 | std::vector d2; 61 | std::vector f2; 62 | std::vector l2; 63 | std::vector c2; 64 | std::vector s2; 65 | 66 | t -> Branch("intvector", &i2); 67 | t -> Branch("doublevector", &d2); 68 | t -> Branch("floatvector", &f2); 69 | t -> Branch("longVector", &l2); 70 | t -> Branch("charVector", &c2); 71 | t -> Branch("shortVector", &s2); 72 | 73 | char* s; 74 | // ? - Warning in : Extra characters after type tag 'C/B' for branch 'character star/C'; must be one character. 75 | t -> Branch("character star/C", s); 76 | 77 | std::string a_string("blah"); 78 | t -> Branch("str_branch_name", &a_string); 79 | 80 | std::vector sample; 81 | t -> Branch("sample string", &sample); 82 | 83 | t -> Fill(); 84 | t -> Write(); 85 | 86 | TGraph g(10); 87 | g.Write(); 88 | 89 | TMultiGraph *mg = new TMultiGraph(); 90 | mg -> Write(); 91 | 92 | tfile -> Write(); 93 | tfile -> Close(); 94 | } 95 | -------------------------------------------------------------------------------- /dev/streamergen.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | # Run this script from the root directory of the project. 6 | 7 | import sys 8 | import os 9 | sys.path.insert(0, os.path.abspath("")) 10 | 11 | import uproot3 12 | 13 | import subprocess 14 | import json 15 | 16 | # Make sure c file is named allstreamers.c 17 | subprocess.run("root -l -q dev/allstreamers.c", shell=True) 18 | 19 | f = uproot3.open("dev/allstreamers.root") 20 | 21 | # Check with json 22 | data = json.load(open("dev/streamerversions.json")) 23 | for x in f._context.streamerinfos: 24 | if data[x._fName.decode("ascii")] != x._fClassVersion: 25 | print("Old {0} version = {1}. New {0} version = {2}".format(x._fName, data[x._fName.decode("ascii")], x._fClassVersion)) 26 | 27 | tkey = uproot3.rootio.TKey.read(f._context.source, uproot3.source.cursor.Cursor(f._context.tfile["_fSeekInfo"]), None, None) 28 | start = f._context.tfile["_fSeekInfo"] + tkey._fKeylen 29 | streamerlen = tkey._fObjlen 30 | 31 | with open("dev/allstreamers.root", "rb") as binary_file: 32 | binary_file.seek(start) 33 | couple_bytes = binary_file.read(streamerlen) 34 | streamers = "streamers = {0}".format(repr(couple_bytes)) 35 | 36 | lines = [] 37 | for line in open("uproot3/write/streamers.py"): 38 | if line.startswith("streamers"): 39 | lines.append(streamers) 40 | else: 41 | lines.append(line) 42 | 43 | with open("uproot3/write/streamers.py", "w") as streamerfile: 44 | for line in lines: 45 | streamerfile.writelines(line) 46 | 47 | os.remove("dev/allstreamers.root") 48 | -------------------------------------------------------------------------------- /dev/streamerversions.json: -------------------------------------------------------------------------------- 1 | { 2 | "TObjString": 1, 3 | "TObject": 1, 4 | "TLorentzVector": 4, 5 | "TVector3": 3, 6 | "TVector2": 3, 7 | "TProfile": 7, 8 | "TH1D": 3, 9 | "TH1": 8, 10 | "TNamed": 1, 11 | "TAttLine": 2, 12 | "TAttFill": 2, 13 | "TAttMarker": 2, 14 | "TArray": 1, 15 | "TAxis": 10, 16 | "TAttAxis": 4, 17 | "THashList": 0, 18 | "TList": 5, 19 | "TSeqCollection": 0, 20 | "TCollection": 3, 21 | "TString": 2, 22 | "TProfile2D": 8, 23 | "TH2D": 4, 24 | "TH2": 5, 25 | "TProfile3D": 8, 26 | "TH3D": 4, 27 | "TH3": 6, 28 | "TAtt3D": 1, 29 | "vector": 6, 30 | "vector": 6, 31 | "vector": 6, 32 | "vector": 6, 33 | "vector": 6, 34 | "vector": 6, 35 | "vector": 6, 36 | "TTree": 20, 37 | "ROOT::TIOFeatures": 1, 38 | "TBranch": 13, 39 | "TLeafI": 1, 40 | "TLeaf": 2, 41 | "TLeafD": 1, 42 | "TLeafF": 1, 43 | "TLeafL": 1, 44 | "TLeafB": 1, 45 | "TLeafS": 1, 46 | "TLeafO": 1, 47 | "TBranchElement": 10, 48 | "TLeafElement": 1, 49 | "TLeafC": 1, 50 | "TBranchRef": 1, 51 | "TRefTable": 3, 52 | "TObjArray": 3, 53 | "TGraph": 4, 54 | "TH1F": 3, 55 | "TArrayF": 1, 56 | "TMultiGraph": 2, 57 | "TH1C": 3, 58 | "TH1I": 3, 59 | "TH1S": 3, 60 | "TH2C": 4, 61 | "TH2S": 4, 62 | "TH2I": 4, 63 | "TH2F": 4, 64 | "TH3C": 4, 65 | "TH3S": 4, 66 | "TH3I": 4, 67 | "TH3F": 4 68 | } 69 | -------------------------------------------------------------------------------- /docs/Makefile: -------------------------------------------------------------------------------- 1 | # Makefile for Sphinx documentation 2 | # 3 | 4 | # You can set these variables from the command line. 5 | SPHINXOPTS = 6 | SPHINXBUILD = sphinx-build 7 | PAPER = 8 | BUILDDIR = build 9 | 10 | # Internal variables. 11 | PAPEROPT_a4 = -D latex_paper_size=a4 12 | PAPEROPT_letter = -D latex_paper_size=letter 13 | ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 14 | # the i18n builder cannot share the environment and doctrees with the others 15 | I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source 16 | 17 | .PHONY: help 18 | help: 19 | @echo "Please use \`make ' where is one of" 20 | @echo " html to make standalone HTML files" 21 | @echo " dirhtml to make HTML files named index.html in directories" 22 | @echo " singlehtml to make a single large HTML file" 23 | @echo " pickle to make pickle files" 24 | @echo " json to make JSON files" 25 | @echo " htmlhelp to make HTML files and a HTML help project" 26 | @echo " qthelp to make HTML files and a qthelp project" 27 | @echo " applehelp to make an Apple Help Book" 28 | @echo " devhelp to make HTML files and a Devhelp project" 29 | @echo " epub to make an epub" 30 | @echo " epub3 to make an epub3" 31 | @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" 32 | @echo " latexpdf to make LaTeX files and run them through pdflatex" 33 | @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" 34 | @echo " text to make text files" 35 | @echo " man to make manual pages" 36 | @echo " texinfo to make Texinfo files" 37 | @echo " info to make Texinfo files and run them through makeinfo" 38 | @echo " gettext to make PO message catalogs" 39 | @echo " changes to make an overview of all changed/added/deprecated items" 40 | @echo " xml to make Docutils-native XML files" 41 | @echo " pseudoxml to make pseudoxml-XML files for display purposes" 42 | @echo " linkcheck to check all external links for integrity" 43 | @echo " doctest to run all doctests embedded in the documentation (if enabled)" 44 | @echo " coverage to run coverage check of the documentation (if enabled)" 45 | @echo " dummy to check syntax errors of document sources" 46 | 47 | .PHONY: clean 48 | clean: 49 | rm -rf $(BUILDDIR)/* 50 | 51 | .PHONY: html 52 | html: 53 | $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html 54 | @echo 55 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." 56 | 57 | .PHONY: dirhtml 58 | dirhtml: 59 | $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml 60 | @echo 61 | @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." 62 | 63 | .PHONY: singlehtml 64 | singlehtml: 65 | $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml 66 | @echo 67 | @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." 68 | 69 | .PHONY: pickle 70 | pickle: 71 | $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle 72 | @echo 73 | @echo "Build finished; now you can process the pickle files." 74 | 75 | .PHONY: json 76 | json: 77 | $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json 78 | @echo 79 | @echo "Build finished; now you can process the JSON files." 80 | 81 | .PHONY: htmlhelp 82 | htmlhelp: 83 | $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp 84 | @echo 85 | @echo "Build finished; now you can run HTML Help Workshop with the" \ 86 | ".hhp project file in $(BUILDDIR)/htmlhelp." 87 | 88 | .PHONY: qthelp 89 | qthelp: 90 | $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp 91 | @echo 92 | @echo "Build finished; now you can run "qcollectiongenerator" with the" \ 93 | ".qhcp project file in $(BUILDDIR)/qthelp, like this:" 94 | @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/uproot.qhcp" 95 | @echo "To view the help file:" 96 | @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/uproot.qhc" 97 | 98 | .PHONY: applehelp 99 | applehelp: 100 | $(SPHINXBUILD) -b applehelp $(ALLSPHINXOPTS) $(BUILDDIR)/applehelp 101 | @echo 102 | @echo "Build finished. The help book is in $(BUILDDIR)/applehelp." 103 | @echo "N.B. You won't be able to view it unless you put it in" \ 104 | "~/Library/Documentation/Help or install it in your application" \ 105 | "bundle." 106 | 107 | .PHONY: devhelp 108 | devhelp: 109 | $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp 110 | @echo 111 | @echo "Build finished." 112 | @echo "To view the help file:" 113 | @echo "# mkdir -p $$HOME/.local/share/devhelp/uproot" 114 | @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/uproot" 115 | @echo "# devhelp" 116 | 117 | .PHONY: epub 118 | epub: 119 | $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub 120 | @echo 121 | @echo "Build finished. The epub file is in $(BUILDDIR)/epub." 122 | 123 | .PHONY: epub3 124 | epub3: 125 | $(SPHINXBUILD) -b epub3 $(ALLSPHINXOPTS) $(BUILDDIR)/epub3 126 | @echo 127 | @echo "Build finished. The epub3 file is in $(BUILDDIR)/epub3." 128 | 129 | .PHONY: latex 130 | latex: 131 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 132 | @echo 133 | @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." 134 | @echo "Run \`make' in that directory to run these through (pdf)latex" \ 135 | "(use \`make latexpdf' here to do that automatically)." 136 | 137 | .PHONY: latexpdf 138 | latexpdf: 139 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 140 | @echo "Running LaTeX files through pdflatex..." 141 | $(MAKE) -C $(BUILDDIR)/latex all-pdf 142 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 143 | 144 | .PHONY: latexpdfja 145 | latexpdfja: 146 | $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex 147 | @echo "Running LaTeX files through platex and dvipdfmx..." 148 | $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja 149 | @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." 150 | 151 | .PHONY: text 152 | text: 153 | $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text 154 | @echo 155 | @echo "Build finished. The text files are in $(BUILDDIR)/text." 156 | 157 | .PHONY: man 158 | man: 159 | $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man 160 | @echo 161 | @echo "Build finished. The manual pages are in $(BUILDDIR)/man." 162 | 163 | .PHONY: texinfo 164 | texinfo: 165 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 166 | @echo 167 | @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." 168 | @echo "Run \`make' in that directory to run these through makeinfo" \ 169 | "(use \`make info' here to do that automatically)." 170 | 171 | .PHONY: info 172 | info: 173 | $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo 174 | @echo "Running Texinfo files through makeinfo..." 175 | make -C $(BUILDDIR)/texinfo info 176 | @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." 177 | 178 | .PHONY: gettext 179 | gettext: 180 | $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale 181 | @echo 182 | @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." 183 | 184 | .PHONY: changes 185 | changes: 186 | $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes 187 | @echo 188 | @echo "The overview file is in $(BUILDDIR)/changes." 189 | 190 | .PHONY: linkcheck 191 | linkcheck: 192 | $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck 193 | @echo 194 | @echo "Link check complete; look for any errors in the above output " \ 195 | "or in $(BUILDDIR)/linkcheck/output.txt." 196 | 197 | .PHONY: doctest 198 | doctest: 199 | $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest 200 | @echo "Testing of doctests in the sources finished, look at the " \ 201 | "results in $(BUILDDIR)/doctest/output.txt." 202 | 203 | .PHONY: coverage 204 | coverage: 205 | $(SPHINXBUILD) -b coverage $(ALLSPHINXOPTS) $(BUILDDIR)/coverage 206 | @echo "Testing of coverage in the sources finished, look at the " \ 207 | "results in $(BUILDDIR)/coverage/python.txt." 208 | 209 | .PHONY: xml 210 | xml: 211 | $(SPHINXBUILD) -b xml $(ALLSPHINXOPTS) $(BUILDDIR)/xml 212 | @echo 213 | @echo "Build finished. The XML files are in $(BUILDDIR)/xml." 214 | 215 | .PHONY: pseudoxml 216 | pseudoxml: 217 | $(SPHINXBUILD) -b pseudoxml $(ALLSPHINXOPTS) $(BUILDDIR)/pseudoxml 218 | @echo 219 | @echo "Build finished. The pseudo-XML files are in $(BUILDDIR)/pseudoxml." 220 | 221 | .PHONY: dummy 222 | dummy: 223 | $(SPHINXBUILD) -b dummy $(ALLSPHINXOPTS) $(BUILDDIR)/dummy 224 | @echo 225 | @echo "Build finished. Dummy builder generates no files." 226 | -------------------------------------------------------------------------------- /docs/README_107_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/README_107_0.png -------------------------------------------------------------------------------- /docs/README_243_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/README_243_0.png -------------------------------------------------------------------------------- /docs/abstraction-layers.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/abstraction-layers.png -------------------------------------------------------------------------------- /docs/all_file_project.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/all_file_project.pdf -------------------------------------------------------------------------------- /docs/all_file_project.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/all_file_project.png -------------------------------------------------------------------------------- /docs/logscales.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/logscales.png -------------------------------------------------------------------------------- /docs/make.bat: -------------------------------------------------------------------------------- 1 | @ECHO OFF 2 | 3 | REM Command file for Sphinx documentation 4 | 5 | if "%SPHINXBUILD%" == "" ( 6 | set SPHINXBUILD=sphinx-build 7 | ) 8 | set BUILDDIR=build 9 | set ALLSPHINXOPTS=-d %BUILDDIR%/doctrees %SPHINXOPTS% source 10 | set I18NSPHINXOPTS=%SPHINXOPTS% source 11 | if NOT "%PAPER%" == "" ( 12 | set ALLSPHINXOPTS=-D latex_paper_size=%PAPER% %ALLSPHINXOPTS% 13 | set I18NSPHINXOPTS=-D latex_paper_size=%PAPER% %I18NSPHINXOPTS% 14 | ) 15 | 16 | if "%1" == "" goto help 17 | 18 | if "%1" == "help" ( 19 | :help 20 | echo.Please use `make ^` where ^ is one of 21 | echo. html to make standalone HTML files 22 | echo. dirhtml to make HTML files named index.html in directories 23 | echo. singlehtml to make a single large HTML file 24 | echo. pickle to make pickle files 25 | echo. json to make JSON files 26 | echo. htmlhelp to make HTML files and a HTML help project 27 | echo. qthelp to make HTML files and a qthelp project 28 | echo. devhelp to make HTML files and a Devhelp project 29 | echo. epub to make an epub 30 | echo. epub3 to make an epub3 31 | echo. latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter 32 | echo. text to make text files 33 | echo. man to make manual pages 34 | echo. texinfo to make Texinfo files 35 | echo. gettext to make PO message catalogs 36 | echo. changes to make an overview over all changed/added/deprecated items 37 | echo. xml to make Docutils-native XML files 38 | echo. pseudoxml to make pseudoxml-XML files for display purposes 39 | echo. linkcheck to check all external links for integrity 40 | echo. doctest to run all doctests embedded in the documentation if enabled 41 | echo. coverage to run coverage check of the documentation if enabled 42 | echo. dummy to check syntax errors of document sources 43 | goto end 44 | ) 45 | 46 | if "%1" == "clean" ( 47 | for /d %%i in (%BUILDDIR%\*) do rmdir /q /s %%i 48 | del /q /s %BUILDDIR%\* 49 | goto end 50 | ) 51 | 52 | 53 | REM Check if sphinx-build is available and fallback to Python version if any 54 | %SPHINXBUILD% 1>NUL 2>NUL 55 | if errorlevel 9009 goto sphinx_python 56 | goto sphinx_ok 57 | 58 | :sphinx_python 59 | 60 | set SPHINXBUILD=python -m sphinx.__init__ 61 | %SPHINXBUILD% 2> nul 62 | if errorlevel 9009 ( 63 | echo. 64 | echo.The 'sphinx-build' command was not found. Make sure you have Sphinx 65 | echo.installed, then set the SPHINXBUILD environment variable to point 66 | echo.to the full path of the 'sphinx-build' executable. Alternatively you 67 | echo.may add the Sphinx directory to PATH. 68 | echo. 69 | echo.If you don't have Sphinx installed, grab it from 70 | echo.http://sphinx-doc.org/ 71 | exit /b 1 72 | ) 73 | 74 | :sphinx_ok 75 | 76 | 77 | if "%1" == "html" ( 78 | %SPHINXBUILD% -b html %ALLSPHINXOPTS% %BUILDDIR%/html 79 | if errorlevel 1 exit /b 1 80 | echo. 81 | echo.Build finished. The HTML pages are in %BUILDDIR%/html. 82 | goto end 83 | ) 84 | 85 | if "%1" == "dirhtml" ( 86 | %SPHINXBUILD% -b dirhtml %ALLSPHINXOPTS% %BUILDDIR%/dirhtml 87 | if errorlevel 1 exit /b 1 88 | echo. 89 | echo.Build finished. The HTML pages are in %BUILDDIR%/dirhtml. 90 | goto end 91 | ) 92 | 93 | if "%1" == "singlehtml" ( 94 | %SPHINXBUILD% -b singlehtml %ALLSPHINXOPTS% %BUILDDIR%/singlehtml 95 | if errorlevel 1 exit /b 1 96 | echo. 97 | echo.Build finished. The HTML pages are in %BUILDDIR%/singlehtml. 98 | goto end 99 | ) 100 | 101 | if "%1" == "pickle" ( 102 | %SPHINXBUILD% -b pickle %ALLSPHINXOPTS% %BUILDDIR%/pickle 103 | if errorlevel 1 exit /b 1 104 | echo. 105 | echo.Build finished; now you can process the pickle files. 106 | goto end 107 | ) 108 | 109 | if "%1" == "json" ( 110 | %SPHINXBUILD% -b json %ALLSPHINXOPTS% %BUILDDIR%/json 111 | if errorlevel 1 exit /b 1 112 | echo. 113 | echo.Build finished; now you can process the JSON files. 114 | goto end 115 | ) 116 | 117 | if "%1" == "htmlhelp" ( 118 | %SPHINXBUILD% -b htmlhelp %ALLSPHINXOPTS% %BUILDDIR%/htmlhelp 119 | if errorlevel 1 exit /b 1 120 | echo. 121 | echo.Build finished; now you can run HTML Help Workshop with the ^ 122 | .hhp project file in %BUILDDIR%/htmlhelp. 123 | goto end 124 | ) 125 | 126 | if "%1" == "qthelp" ( 127 | %SPHINXBUILD% -b qthelp %ALLSPHINXOPTS% %BUILDDIR%/qthelp 128 | if errorlevel 1 exit /b 1 129 | echo. 130 | echo.Build finished; now you can run "qcollectiongenerator" with the ^ 131 | .qhcp project file in %BUILDDIR%/qthelp, like this: 132 | echo.^> qcollectiongenerator %BUILDDIR%\qthelp\uproot.qhcp 133 | echo.To view the help file: 134 | echo.^> assistant -collectionFile %BUILDDIR%\qthelp\uproot.ghc 135 | goto end 136 | ) 137 | 138 | if "%1" == "devhelp" ( 139 | %SPHINXBUILD% -b devhelp %ALLSPHINXOPTS% %BUILDDIR%/devhelp 140 | if errorlevel 1 exit /b 1 141 | echo. 142 | echo.Build finished. 143 | goto end 144 | ) 145 | 146 | if "%1" == "epub" ( 147 | %SPHINXBUILD% -b epub %ALLSPHINXOPTS% %BUILDDIR%/epub 148 | if errorlevel 1 exit /b 1 149 | echo. 150 | echo.Build finished. The epub file is in %BUILDDIR%/epub. 151 | goto end 152 | ) 153 | 154 | if "%1" == "epub3" ( 155 | %SPHINXBUILD% -b epub3 %ALLSPHINXOPTS% %BUILDDIR%/epub3 156 | if errorlevel 1 exit /b 1 157 | echo. 158 | echo.Build finished. The epub3 file is in %BUILDDIR%/epub3. 159 | goto end 160 | ) 161 | 162 | if "%1" == "latex" ( 163 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 164 | if errorlevel 1 exit /b 1 165 | echo. 166 | echo.Build finished; the LaTeX files are in %BUILDDIR%/latex. 167 | goto end 168 | ) 169 | 170 | if "%1" == "latexpdf" ( 171 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 172 | cd %BUILDDIR%/latex 173 | make all-pdf 174 | cd %~dp0 175 | echo. 176 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 177 | goto end 178 | ) 179 | 180 | if "%1" == "latexpdfja" ( 181 | %SPHINXBUILD% -b latex %ALLSPHINXOPTS% %BUILDDIR%/latex 182 | cd %BUILDDIR%/latex 183 | make all-pdf-ja 184 | cd %~dp0 185 | echo. 186 | echo.Build finished; the PDF files are in %BUILDDIR%/latex. 187 | goto end 188 | ) 189 | 190 | if "%1" == "text" ( 191 | %SPHINXBUILD% -b text %ALLSPHINXOPTS% %BUILDDIR%/text 192 | if errorlevel 1 exit /b 1 193 | echo. 194 | echo.Build finished. The text files are in %BUILDDIR%/text. 195 | goto end 196 | ) 197 | 198 | if "%1" == "man" ( 199 | %SPHINXBUILD% -b man %ALLSPHINXOPTS% %BUILDDIR%/man 200 | if errorlevel 1 exit /b 1 201 | echo. 202 | echo.Build finished. The manual pages are in %BUILDDIR%/man. 203 | goto end 204 | ) 205 | 206 | if "%1" == "texinfo" ( 207 | %SPHINXBUILD% -b texinfo %ALLSPHINXOPTS% %BUILDDIR%/texinfo 208 | if errorlevel 1 exit /b 1 209 | echo. 210 | echo.Build finished. The Texinfo files are in %BUILDDIR%/texinfo. 211 | goto end 212 | ) 213 | 214 | if "%1" == "gettext" ( 215 | %SPHINXBUILD% -b gettext %I18NSPHINXOPTS% %BUILDDIR%/locale 216 | if errorlevel 1 exit /b 1 217 | echo. 218 | echo.Build finished. The message catalogs are in %BUILDDIR%/locale. 219 | goto end 220 | ) 221 | 222 | if "%1" == "changes" ( 223 | %SPHINXBUILD% -b changes %ALLSPHINXOPTS% %BUILDDIR%/changes 224 | if errorlevel 1 exit /b 1 225 | echo. 226 | echo.The overview file is in %BUILDDIR%/changes. 227 | goto end 228 | ) 229 | 230 | if "%1" == "linkcheck" ( 231 | %SPHINXBUILD% -b linkcheck %ALLSPHINXOPTS% %BUILDDIR%/linkcheck 232 | if errorlevel 1 exit /b 1 233 | echo. 234 | echo.Link check complete; look for any errors in the above output ^ 235 | or in %BUILDDIR%/linkcheck/output.txt. 236 | goto end 237 | ) 238 | 239 | if "%1" == "doctest" ( 240 | %SPHINXBUILD% -b doctest %ALLSPHINXOPTS% %BUILDDIR%/doctest 241 | if errorlevel 1 exit /b 1 242 | echo. 243 | echo.Testing of doctests in the sources finished, look at the ^ 244 | results in %BUILDDIR%/doctest/output.txt. 245 | goto end 246 | ) 247 | 248 | if "%1" == "coverage" ( 249 | %SPHINXBUILD% -b coverage %ALLSPHINXOPTS% %BUILDDIR%/coverage 250 | if errorlevel 1 exit /b 1 251 | echo. 252 | echo.Testing of coverage in the sources finished, look at the ^ 253 | results in %BUILDDIR%/coverage/python.txt. 254 | goto end 255 | ) 256 | 257 | if "%1" == "xml" ( 258 | %SPHINXBUILD% -b xml %ALLSPHINXOPTS% %BUILDDIR%/xml 259 | if errorlevel 1 exit /b 1 260 | echo. 261 | echo.Build finished. The XML files are in %BUILDDIR%/xml. 262 | goto end 263 | ) 264 | 265 | if "%1" == "pseudoxml" ( 266 | %SPHINXBUILD% -b pseudoxml %ALLSPHINXOPTS% %BUILDDIR%/pseudoxml 267 | if errorlevel 1 exit /b 1 268 | echo. 269 | echo.Build finished. The pseudo-XML files are in %BUILDDIR%/pseudoxml. 270 | goto end 271 | ) 272 | 273 | if "%1" == "dummy" ( 274 | %SPHINXBUILD% -b dummy %ALLSPHINXOPTS% %BUILDDIR%/dummy 275 | if errorlevel 1 exit /b 1 276 | echo. 277 | echo.Build finished. Dummy builder generates no files. 278 | goto end 279 | ) 280 | 281 | :end 282 | -------------------------------------------------------------------------------- /docs/pip-scientificlinux-uproot.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/pip-scientificlinux-uproot.pdf -------------------------------------------------------------------------------- /docs/pip-scientificlinux-uproot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/pip-scientificlinux-uproot.png -------------------------------------------------------------------------------- /docs/root-none-muon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/root-none-muon.png -------------------------------------------------------------------------------- /docs/rootnumpy-none-muon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/rootnumpy-none-muon.png -------------------------------------------------------------------------------- /docs/scaling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/scaling.png -------------------------------------------------------------------------------- /docs/source/caches.rst: -------------------------------------------------------------------------------- 1 | Caches 2 | ====== 3 | 4 | Many functions in Uproot may be given a cache to avoid expensive re-reading or re-calculating previously read or calculated quantities. These functions assume nothing about the cache other than a ``dict``-like interface: square brackets get old values and set new ones and ``in`` checks for existence. Therefore, a ``dict`` may be used as a "save forever" cache, but of course you might not have enough memory to save all data in memory forever. 5 | 6 | The classes described on this page are drop-in replacements for ``dict`` with additional properties: least-recently-used (LRU) eviction, which drops the oldest cache item upon reaching a memory budget, as well as thread safety and process safety. 7 | 8 | This interface, in which the user instantiates and passes the cache object explicitly instead of turning on an internal cache option, is to avoid situations in which the user can't determine where large amounts of memory are accumulating. When Uproot reads a ROOT file, it does not save anything for reuse except what it puts in user-provided caches, so the user can always inspect these objects to see what's being saved. 9 | 10 | The array-reading functions (in :py:class:`TTreeMethods ` and :py:class:`TBranchMethods `) each have three cache parameters: 11 | 12 | - **cache** for fully interpreted data. Accessing the same arrays with a different interpretation or a different entry range results in a cache miss. 13 | - **basketcache** for raw basket data. Accessing the same arrays with a different interpretation or a different entry range fully utilizes this cache, since the interpretation/construction from baskets is performed after retrieving data from this cache. 14 | - **keycache** for basket TKeys. TKeys are small, but require file access, so caching them can speed up repeated access. 15 | 16 | Passing explicit caches to **basketcache** and **keycache** will ensure that the file is read only once, while passing explicit caches to **cache** and **keycache** will ensure that the file is read *and interpreted* only once. 17 | 18 | uproot3.cache.ArrayCache 19 | ----------------------- 20 | 21 | .. autoclass:: uproot3.cache.ArrayCache 22 | 23 | uproot3.cache.ThreadSafeArrayCache 24 | --------------------------------- 25 | 26 | .. autoclass:: uproot3.cache.ThreadSafeArrayCache 27 | -------------------------------------------------------------------------------- /docs/source/conf.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | import os.path 4 | 5 | # If your documentation needs a minimal Sphinx version, state it here. 6 | # needs_sphinx = "1.0" 7 | 8 | extensions = [ 9 | "sphinx.ext.autodoc", 10 | "sphinx.ext.napoleon", 11 | "sphinx.ext.doctest", 12 | "sphinx.ext.todo", 13 | "sphinx.ext.coverage", 14 | "sphinx.ext.viewcode", 15 | "sphinx.ext.githubpages", 16 | ] 17 | 18 | # Add any paths that contain templates here, relative to this directory. 19 | templates_path = ["-templates"] 20 | 21 | source_suffix = ".rst" 22 | source_encoding = "utf-8" 23 | master_doc = "index" 24 | 25 | project = u"uproot3" 26 | copyright = u"2019, IRIS-HEP" 27 | author = u"Jim Pivarski" 28 | 29 | def get_version(): 30 | g = {} 31 | exec(open(os.path.join("..", "..", "uproot3", "version.py")).read(), g) 32 | return g["__version__"] 33 | 34 | version = get_version() 35 | release = get_version() 36 | 37 | # The language for content autogenerated by Sphinx. Refer to documentation 38 | # for a list of supported languages. 39 | language = None 40 | 41 | # List of patterns, relative to source directory, that match files and 42 | # directories to ignore when looking for source files. 43 | # This patterns also effect to html_static_path and html_extra_path 44 | exclude_patterns = [] 45 | 46 | # If true, the current module name will be prepended to all description 47 | # unit titles (such as .. function::). 48 | # add_module_names = True 49 | 50 | # If true, sectionauthor and moduleauthor directives will be shown in the 51 | # output. They are ignored by default. 52 | # show_authors = False 53 | 54 | # The name of the Pygments (syntax highlighting) style to use. 55 | # pygments_style = "sphinx" 56 | 57 | # A list of ignored prefixes for module index sorting. 58 | # modindex_common_prefix = [] 59 | 60 | # If true, keep warnings as "system message" paragraphs in the built documents. 61 | # keep_warnings = False 62 | 63 | # If true, `todo` and `todoList` produce output, else they produce nothing. 64 | todo_include_todos = True 65 | 66 | add_function_parentheses = False 67 | 68 | # -- Options for HTML output ---------------------------------------------- 69 | 70 | # html_theme = "alabaster" 71 | # html_theme_options = {} 72 | # html_theme_path = [] 73 | 74 | html_title = u"uproot v" + get_version() 75 | 76 | # A shorter title for the navigation bar. Default is the same as html_title. 77 | # html_short_title = None 78 | 79 | # The name of an image file (relative to this directory) to place at the top 80 | # of the sidebar. 81 | # html_logo = None 82 | 83 | # The name of an image file (relative to this directory) to use as a favicon of 84 | # the docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 85 | # pixels large. 86 | # html_favicon = None 87 | 88 | # Add any paths that contain custom static files (such as style sheets) here, 89 | # relative to this directory. They are copied after the builtin static files, 90 | # so a file named "default.css" will overwrite the builtin "default.css". 91 | html_static_path = ["-static"] 92 | 93 | # Add any extra paths that contain custom files (such as robots.txt or 94 | # .htaccess) here, relative to this directory. These files are copied 95 | # directly to the root of the documentation. 96 | # html_extra_path = [] 97 | 98 | # If not None, a "Last updated on:" timestamp is inserted at every page 99 | # bottom, using the given strftime format. 100 | # The empty string is equivalent to "%b %d, %Y". 101 | html_last_updated_fmt = "" 102 | 103 | # If true, SmartyPants will be used to convert quotes and dashes to 104 | # typographically correct entities. 105 | # html_use_smartypants = True 106 | 107 | # Custom sidebar templates, maps document names to template names. 108 | # html_sidebars = {} 109 | 110 | # Additional templates that should be rendered to pages, maps page names to 111 | # template names. 112 | # html_additional_pages = {} 113 | 114 | # If false, no module index is generated. 115 | # html_domain_indices = True 116 | 117 | # If false, no index is generated. 118 | # html_use_index = True 119 | 120 | # If true, the index is split into individual pages for each letter. 121 | # html_split_index = False 122 | 123 | # If true, links to the reST sources are added to the pages. 124 | # html_show_sourcelink = True 125 | 126 | # If true, "Created using Sphinx" is shown in the HTML footer. Default is True. 127 | # html_show_sphinx = True 128 | 129 | # If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. 130 | # html_show_copyright = True 131 | 132 | # If true, an OpenSearch description file will be output, and all pages will 133 | # contain a tag referring to it. The value of this option must be the 134 | # base URL from which the finished HTML is served. 135 | # html_use_opensearch = "" 136 | 137 | # This is the file name suffix for HTML files (e.g. ".xhtml"). 138 | # html_file_suffix = None 139 | 140 | # Language to be used for generating the HTML full-text search index. 141 | # Sphinx supports the following languages: 142 | # "da", "de", "en", "es", "fi", "fr", "hu", "it", "ja" 143 | # "nl", "no", "pt", "ro", "ru", "sv", "tr", "zh" 144 | # html_search_language = "en" 145 | 146 | # A dictionary with options for the search language support, empty by default. 147 | # "ja" uses this config value. 148 | # "zh" user can custom change `jieba` dictionary path. 149 | # html_search_options = {"type": "default"} 150 | 151 | # The name of a javascript file (relative to the configuration directory) that 152 | # implements a search results scorer. If empty, the default will be used. 153 | # html_search_scorer = "scorer.js" 154 | 155 | # Output file base name for HTML help builder. 156 | htmlhelp_basename = "uprootdoc" 157 | 158 | # -- Options for LaTeX output --------------------------------------------- 159 | 160 | latex_elements = {} 161 | latex_documents = [(master_doc, "uproot.tex", u"uproot Documentation", u"Jim Pivarski", "manual"),] 162 | 163 | # The name of an image file (relative to this directory) to place at the top of 164 | # the title page. 165 | # latex_logo = None 166 | 167 | # For "manual" documents, if this is true, then toplevel headings are parts, 168 | # not chapters. 169 | # latex_use_parts = False 170 | 171 | # If true, show page references after internal links. 172 | # latex_show_pagerefs = False 173 | 174 | # If true, show URL addresses after external links. 175 | # latex_show_urls = False 176 | 177 | # Documents to append as an appendix to all manuals. 178 | # latex_appendices = [] 179 | 180 | # It false, will not define \strong, \code, itleref, \crossref ... but only 181 | # \sphinxstrong, ..., \sphinxtitleref, ... To help avoid clash with user added 182 | # packages. 183 | # latex_keep_old_macro_names = True 184 | 185 | # If false, no module index is generated. 186 | # latex_domain_indices = True 187 | 188 | # -- Options for manual page output --------------------------------------- 189 | 190 | man_pages = [(master_doc, "uproot", u"Uproot 3.x Documentation", [author], 1)] 191 | 192 | # If true, show URL addresses after external links. 193 | # man_show_urls = False 194 | 195 | # -- Options for Texinfo output ------------------------------------------- 196 | 197 | # Grouping the document tree into Texinfo files. List of tuples 198 | # (source start file, target name, title, author, 199 | # dir menu entry, description, category) 200 | texinfo_documents = [(master_doc, "uproot", u"Uproot 3.x Documentation", author, "uproot", "Minimalist ROOT I/O in pure Python and Numpy.", "Miscellaneous"),] 201 | 202 | # Documents to append as an appendix to all manuals. 203 | # texinfo_appendices = [] 204 | 205 | # If false, no module index is generated. 206 | # texinfo_domain_indices = True 207 | 208 | # How to display URL addresses: "footnote", "no", or "inline". 209 | # texinfo_show_urls = "footnote" 210 | 211 | # If true, do not generate a @detailmenu in the "Top" node's menu. 212 | # texinfo_no_detailmenu = False 213 | -------------------------------------------------------------------------------- /docs/source/index.rst: -------------------------------------------------------------------------------- 1 | .. image:: logo-300px.png 2 | :alt: uproot 3 | :target: https://github.com/scikit-hep/uproot3 4 | :align: center 5 | 6 | Uproot 3.x 7 | ========== 8 | 9 | .. include:: ../../README.rst 10 | :start-after: inclusion-marker-1-do-not-remove 11 | :end-before: inclusion-marker-3-do-not-remove 12 | 13 | Tutorial 14 | -------- 15 | 16 | See the `project homepage `__ for a `tutorial `__. 17 | 18 | Run `the tutorial `__ on Binder. 19 | 20 | Reference documentation 21 | ----------------------- 22 | 23 | .. toctree:: 24 | :maxdepth: 3 25 | 26 | opening-files 27 | root-io 28 | ttree-handling 29 | interpretation 30 | caches 31 | parallel-io 32 | -------------------------------------------------------------------------------- /docs/source/interpretation.rst: -------------------------------------------------------------------------------- 1 | Interpretation 2 | ============== 3 | 4 | ROOT was designed for C++, so ROOT data have an unambiguous C++ interpretation. However, their Python interpretation is open to interpretation. For instance, you may want a branch to be read as a new Numpy array, or perhaps a user-provided array in shared memory, with or without byte-swapping, type conversion, or reshaping, or as an array of unequal-length arrays, or an array of classes defined by the ROOT streamers, or an array of custom classes, or as a Numpy record array, etc. The Uproot :py:class:`Interpretation ` mechanism provides such flexibility without sacrificing the flexibility of the selective reading methods. 5 | 6 | If no interpretation is specified, :py:func:`uproot3.interpret ` is automatically called to provide a reasonable default. This function may also be called by the user with custom arguments and its output may be modified in the *branches* or *interpretation* arguments of :py:class:`TTreeMethods ` and :py:class:`TBranchMethods ` array-producing functions. 7 | 8 | uproot3.interp.interp.Interpretation 9 | ----------------------------------- 10 | 11 | .. autoclass:: uproot3.interp.interp.Interpretation 12 | 13 | uproot3.interpret 14 | ---------------- 15 | 16 | .. autofunction:: uproot3.interp.auto.interpret 17 | 18 | uproot3.interp.numerical.asdtype 19 | ------------------------------- 20 | 21 | .. autoclass:: uproot3.interp.numerical.asdtype 22 | 23 | .. automethod:: uproot3.interp.numerical.asdtype.to 24 | 25 | .. automethod:: uproot3.interp.numerical.asdtype.toarray 26 | 27 | uproot3.interp.numerical.asarray 28 | ------------------------------- 29 | 30 | .. autoclass:: uproot3.interp.numerical.asarray 31 | 32 | uproot3.interp.numerical.asdouble32 33 | ---------------------------------- 34 | 35 | .. autoclass:: uproot3.interp.numerical.asdouble32 36 | 37 | uproot3.interp.numerical.asstlbitset 38 | ----------------------------------- 39 | 40 | .. autoclass:: uproot3.interp.numerical.asstlbitset 41 | 42 | uproot3.interp.jagged.asjagged 43 | ----------------------------- 44 | 45 | .. autoclass:: uproot3.interp.jagged.asjagged 46 | 47 | .. automethod:: uproot3.interp.jagged.asjagged.to 48 | 49 | uproot3.interp.objects.astable 50 | ----------------------------- 51 | 52 | .. autoclass:: uproot3.interp.objects.astable 53 | 54 | uproot3.interp.objects.asobj 55 | --------------------------- 56 | 57 | .. autoclass:: uproot3.interp.objects.asobj 58 | 59 | uproot3.interp.objects.asgenobj 60 | ------------------------------ 61 | 62 | .. autoclass:: uproot3.interp.objects.asgenobj 63 | 64 | uproot3.interp.objects.asstring 65 | ------------------------------ 66 | 67 | .. autoclass:: uproot3.interp.objects.asstring 68 | -------------------------------------------------------------------------------- /docs/source/logo-300px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/source/logo-300px.png -------------------------------------------------------------------------------- /docs/source/logo-600px.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/source/logo-600px.png -------------------------------------------------------------------------------- /docs/source/logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 21 | 23 | 24 | 26 | image/svg+xml 27 | 29 | 30 | 31 | 32 | 33 | 35 | 59 | 65 | 71 | 77 | 83 | 89 | 95 | 101 | 102 | -------------------------------------------------------------------------------- /docs/source/opening-files.rst: -------------------------------------------------------------------------------- 1 | Opening files 2 | ============= 3 | 4 | Unlike ROOT, Uproot strongly assumes that the input file does not change while you read it. File :py:class:`Sources ` do not lock the file, and they may open, close, and reopen it as needed to read the file in parallel. Therefore, if another process is changing the contents of a file while Uproot reads it, the behavior is undefined (but likely bad!). 5 | 6 | uproot3.open 7 | ----------- 8 | 9 | All ROOT objects come from ROOT files, so :py:func:`uproot3.open ` is probably the first function you'll call. The :py:class:`ROOTDirectory ` object it returns is a handle for accessing contents deeper within the file. If the file is remote, use ``"root://"`` or ``"http://"`` in the file name to invoke a remote protocol. 10 | 11 | .. autofunction:: uproot3.rootio.open 12 | 13 | uproot3.xrootd 14 | ------------- 15 | 16 | Although :py:func:`uproot3.open ` opens files regardless of whether they're local or remote, you can explicitly invoke XRootD with :py:func:`uproot3.xrootd `. You get the same kind of :py:class:`ROOTDirectory ` as from :py:func:`uproot3.open `. 17 | 18 | .. autofunction:: uproot3.rootio.xrootd 19 | 20 | uproot3.http 21 | ----------- 22 | 23 | You can also open files through the HTTP protocol (and some XRootD servers support HTTP, too). The :py:func:`uproot3.http ` function opens files via HTTP. 24 | 25 | .. autofunction:: uproot3.rootio.http 26 | 27 | uproot3.iterate 28 | -------------- 29 | 30 | With a :py:class:`ROOTDirectory `, you can dig into a file and extract objects, subdirectories, or TTree data, but sometimes you know exactly where to find a TTree and have a collection of identically-typed files to iterate through. 31 | 32 | The :py:func:`uproot3.iterate ` function gives you an iterator over groups of arrays just like :py:meth:`TreeMethods.iterate `, except that it iterates over a large set of files (and verifies that the selected TTree branches are compatible). This serves essentially the same function as ROOT's TChain, allowing you to use TTrees in a set of files the same way you would use a single TTree. 33 | 34 | .. autofunction:: uproot3.tree.iterate 35 | 36 | uproot3.pandas.iterate 37 | --------------------- 38 | 39 | The :py:func:`uproot3.pandas.iterate ` function is like the above, except that it iterates over Pandas DataFrames (as though you passed ``outputtype=pandas.DataFrame`` and changed some defaults). 40 | 41 | .. autofunction:: uproot3.pandas.iterate 42 | 43 | uproot3.lazyarray and lazyarrays 44 | ------------------------------- 45 | 46 | The :py:func:`uproot3.lazyarray ` and :py:func:`uproot3.lazyarrays ` give you a lazy view into a whole collection of files. They behave like the :py:meth:`TTreeMethods.lazyarray ` and :py:meth:`TTreeMethods.lazyarrays ` methods except that they wildcarded filenames and a TTree name as the first arguments. 47 | 48 | .. autofunction:: uproot3.tree.lazyarray 49 | 50 | .. autofunction:: uproot3.tree.lazyarrays 51 | 52 | uproot3.daskarray and daskframe 53 | ------------------------------ 54 | 55 | The following are the above, but presents the data as `Dask `__ objects. 56 | 57 | .. autofunction:: uproot3.tree.daskarray 58 | 59 | .. autofunction:: uproot3.tree.daskframe 60 | 61 | uproot3.numentries 62 | ----------------- 63 | 64 | If you need to know the total number of entries of a set of files before processing them (e.g. for normalization or setting weights), you could open each file and TTree individually, but the function below is faster because it skips some steps that aren't needed when you only want the number of files. 65 | 66 | .. autofunction:: uproot3.tree.numentries 67 | -------------------------------------------------------------------------------- /docs/source/parallel-io.rst: -------------------------------------------------------------------------------- 1 | Parallel I/O 2 | ============ 3 | 4 | An essential aspect of Uproot's file-reader is that data :py:class:`Sources ` are completely distinct from :py:class:`Cursors `, which track position in the source. This interface is similar to memory-mapped files, which do not track a position but respond as needed to requests for data by address, and it is unlike traditional file handles, which reference the source of data (integer linked to a file through syscalls) and a position within it (queried by ``seek`` and changed by ``tell``) as an indivisible unit. By default, Uproot reads data through memory-mapped files; all other sources are made to *look* like a memory-mapped file. 5 | 6 | Throughout the ROOT I/O and TTree-handling modules, :py:class:`Sources ` and :py:class:`Cursors ` are passed as independent objects. A :py:class:`Cursor ` cannot read data without being given an explicit :py:class:`Source `. When parts of a file are to be read in parallel, lightweight :py:class:`Cursors ` are duplicated, one per thread, while :py:class:`Sources ` are only duplicated (e.g. multiple file handles into the same file) if the source is not inherently thread-safe (as memory-mapped files are). 7 | 8 | Even when not reading in parallel, copying a :py:class:`Cursor ` when passing it to a subroutine is a lightweight way to keep one's place without the spaghetti of ``seek`` and ``tell`` commands to backtrack, as is often necessary in the ROOT file structure. 9 | 10 | uproot3.source.cursor.Cursor 11 | --------------------------- 12 | 13 | .. autoclass:: uproot3.source.cursor.Cursor 14 | 15 | .. automethod:: uproot3.source.cursor.Cursor.copied 16 | 17 | .. automethod:: uproot3.source.cursor.Cursor.skipped 18 | 19 | .. automethod:: uproot3.source.cursor.Cursor.skip 20 | 21 | .. automethod:: uproot3.source.cursor.Cursor.fields 22 | 23 | .. automethod:: uproot3.source.cursor.Cursor.field 24 | 25 | .. automethod:: uproot3.source.cursor.Cursor.bytes 26 | 27 | .. automethod:: uproot3.source.cursor.Cursor.array 28 | 29 | .. automethod:: uproot3.source.cursor.Cursor.string 30 | 31 | .. automethod:: uproot3.source.cursor.Cursor.cstring 32 | 33 | .. automethod:: uproot3.source.cursor.Cursor.skipstring 34 | 35 | .. automethod:: uproot3.source.cursor.Cursor.hexdump 36 | 37 | uproot3.source.source.Source 38 | --------------------------- 39 | 40 | .. autoclass:: uproot3.source.source.Source 41 | 42 | uproot3.FileSource 43 | ----------------- 44 | 45 | .. autoattribute:: uproot3.source.file.FileSource.defaults 46 | 47 | .. autoclass:: uproot3.source.file.FileSource 48 | 49 | uproot3.MemmapSource 50 | ------------------- 51 | 52 | .. autoattribute:: uproot3.source.memmap.MemmapSource.defaults 53 | 54 | .. autoclass:: uproot3.source.memmap.MemmapSource 55 | 56 | uproot3.XRootDSource 57 | ------------------- 58 | 59 | .. autoattribute:: uproot3.source.xrootd.XRootDSource.defaults 60 | 61 | .. autoclass:: uproot3.source.xrootd.XRootDSource 62 | 63 | uproot3.HTTPSource 64 | ------------------- 65 | 66 | .. autoattribute:: uproot3.source.http.HTTPSource.defaults 67 | 68 | .. autoclass:: uproot3.source.http.HTTPSource 69 | 70 | uproot3.source.compressed.CompressedSource 71 | ----------------------------------------- 72 | 73 | .. autoclass:: uproot3.source.compressed.Compression 74 | 75 | .. autoclass:: uproot3.source.compressed.CompressedSource 76 | -------------------------------------------------------------------------------- /docs/source/root-io.rst: -------------------------------------------------------------------------------- 1 | ROOT I/O 2 | ======== 3 | 4 | The :py:mod:`uproot3.rootio` module contains everything needed to navigate through a ROOT file and extract inert, data-only objects. Methods for those objects are defined in other modules. The :py:func:`uproot3.open ` function returns a :py:class:`ROOTDirectory ` object, which is a handle into the file, from which all other data can be accessed. 5 | 6 | This module has many more classes than those documented here, but all but a few are considered internal details. The classes documented below represent the public API. In fact, only :py:class:`ROOTDirectory ` has useful attributes and methods for a typical user. The other two, :py:class:`ROOTObject ` and :py:class:`ROOTStreamedObject `, are documented because they are superclasses of all objects that could be extracted from a ROOT file, and may be useful in ``isinstance`` checks. 7 | 8 | uproot3.rootio.ROOTDirectory 9 | --------------------------- 10 | 11 | Although :py:class:`ROOTDirectory ` resembles ROOT's TFile, TDirectory, and TFileDirectory to some degree, it does not have a direct relationship to any of them. (This is because we adopted a different model for representing the contents of a ROOT file: purely acyclic with continuation passing.) As a result, :py:class:`ROOTDirectory ` is not a :py:class:`ROOTObject ` and isn't named "TFile." 12 | 13 | A :py:class:`ROOTDirectory ` may represent a whole ROOT file or a single TDirectory within that file--- after reading, there is no difference. 14 | 15 | .. autoclass:: uproot3.rootio.ROOTDirectory 16 | 17 | .. automethod:: uproot3.rootio.ROOTDirectory.get 18 | 19 | .. automethod:: uproot3.rootio.ROOTDirectory.iterkeys 20 | 21 | .. automethod:: uproot3.rootio.ROOTDirectory.itervalues 22 | 23 | .. automethod:: uproot3.rootio.ROOTDirectory.iteritems 24 | 25 | .. automethod:: uproot3.rootio.ROOTDirectory.iterclasses 26 | 27 | .. automethod:: uproot3.rootio.ROOTDirectory.keys 28 | 29 | .. automethod:: uproot3.rootio.ROOTDirectory.values 30 | 31 | .. automethod:: uproot3.rootio.ROOTDirectory.items 32 | 33 | .. automethod:: uproot3.rootio.ROOTDirectory.classes 34 | 35 | .. automethod:: uproot3.rootio.ROOTDirectory.allkeys 36 | 37 | .. automethod:: uproot3.rootio.ROOTDirectory.allvalues 38 | 39 | .. automethod:: uproot3.rootio.ROOTDirectory.allitems 40 | 41 | .. automethod:: uproot3.rootio.ROOTDirectory.allclasses 42 | 43 | uproot3.rootio.ROOTObject 44 | ------------------------ 45 | 46 | .. autoclass:: uproot3.rootio.ROOTObject 47 | 48 | uproot3.rootio.ROOTStreamedObject 49 | -------------------------------- 50 | 51 | .. autoclass:: uproot3.rootio.ROOTStreamedObject 52 | -------------------------------------------------------------------------------- /docs/source/ttree-handling.rst: -------------------------------------------------------------------------------- 1 | TTree Handling 2 | ============== 3 | 4 | TTree and TBranch are two of the data objects that are versioned and streamed from ROOT files (subclasses of :py:class:`ROOTStreamedObject `). As such, their classes do not exist until observed in a ROOT file, and different class objects may be generated by different versions of the class with different member variables. 5 | 6 | However, you may use TTrees and TBranches consistently across versions because they inherit from mix-ins :py:class:`TTreeMethods ` and :py:class:`TBranchMethods `. These interfaces provide more Pythonic names for TTree/TBranch private data and a variety of data-reading routines. 7 | 8 | TLeaf and its subclasses do not (currently) have mix-ins: they are used only for their data. TBasket does not even have an instantiation--- TBasket bytes are read directly into arrays. 9 | 10 | These bytes are read according to some :py:class:`Interpretation `, which governs how the bytes are interpreted (source) and what kinds of objects are filled (destination). For numerical data, the source is usually one big-endian array per basket and the destination is usually one native-endian array per branch. You have complete freedom to set the :py:class:`Interpretation ` for each branch, but sensible defaults are provided (by the :py:func:`interpret ` function, automatically). 11 | 12 | Many of the :py:class:`TTreeMethods ` and :py:class:`TBranchMethods ` have the same parameters--- identical parameter names have identical meanings. In the documentation below, the definitions are repeated for each method (because it may be the first you call ``help`` on, though it inflates the size of this page.). 13 | 14 | uproot3.tree.TTreeMethods 15 | ------------------------ 16 | 17 | Every class read from a ROOT file named "TTree" is mixed in with :py:class:`TTreeMethods ` so that the following methods are available. 18 | 19 | .. autoclass:: uproot3.tree.TTreeMethods 20 | 21 | branch accessors 22 | ^^^^^^^^^^^^^^^^ 23 | 24 | .. automethod:: uproot3.tree.TTreeMethods.get 25 | 26 | .. automethod:: uproot3.tree.TTreeMethods.iterkeys 27 | 28 | .. automethod:: uproot3.tree.TTreeMethods.itervalues 29 | 30 | .. automethod:: uproot3.tree.TTreeMethods.iteritems 31 | 32 | .. automethod:: uproot3.tree.TTreeMethods.keys 33 | 34 | .. automethod:: uproot3.tree.TTreeMethods.values 35 | 36 | .. automethod:: uproot3.tree.TTreeMethods.items 37 | 38 | .. automethod:: uproot3.tree.TTreeMethods.allkeys 39 | 40 | .. automethod:: uproot3.tree.TTreeMethods.allvalues 41 | 42 | .. automethod:: uproot3.tree.TTreeMethods.allitems 43 | 44 | .. automethod:: uproot3.tree.TTreeMethods.clusters 45 | 46 | .. automethod:: uproot3.tree.TTreeMethods.mempartitions 47 | 48 | array 49 | ^^^^^ 50 | 51 | .. automethod:: uproot3.tree.TTreeMethods.array 52 | 53 | arrays 54 | ^^^^^^ 55 | 56 | .. automethod:: uproot3.tree.TTreeMethods.arrays 57 | 58 | lazyarray 59 | ^^^^^^^^^ 60 | 61 | .. automethod:: uproot3.tree.TTreeMethods.lazyarray 62 | 63 | lazyarrays 64 | ^^^^^^^^^^ 65 | 66 | .. automethod:: uproot3.tree.TTreeMethods.lazyarrays 67 | 68 | iterate 69 | ^^^^^^^ 70 | 71 | .. automethod:: uproot3.tree.TTreeMethods.iterate 72 | 73 | pandas 74 | ^^^^^^ 75 | 76 | TTree objects can be converted into `Pandas `__ DataFrames. 77 | 78 | .. autoattribute:: uproot3.tree.TTreeMethods.pandas 79 | :annotation: = methods for interacting with Pandas. 80 | 81 | .. automethod:: uproot3._connect._pandas.TTreeMethods_pandas.df 82 | 83 | uproot3.tree.TBranchMethods 84 | -------------------------- 85 | 86 | Every class read from a ROOT file named "TBranch" is mixed in with :py:class:`TBranchMethods ` so that the following methods are available. Subclasses of "TBranch" (such as "TBranchElement") inherit the mix-in. 87 | 88 | .. autoclass:: uproot3.tree.TBranchMethods 89 | 90 | branch accessors 91 | ^^^^^^^^^^^^^^^^ 92 | 93 | .. automethod:: uproot3.tree.TBranchMethods.get 94 | 95 | .. automethod:: uproot3.tree.TBranchMethods.iterkeys 96 | 97 | .. automethod:: uproot3.tree.TBranchMethods.itervalues 98 | 99 | .. automethod:: uproot3.tree.TBranchMethods.iteritems 100 | 101 | .. automethod:: uproot3.tree.TBranchMethods.keys 102 | 103 | .. automethod:: uproot3.tree.TBranchMethods.values 104 | 105 | .. automethod:: uproot3.tree.TBranchMethods.items 106 | 107 | .. automethod:: uproot3.tree.TBranchMethods.allkeys 108 | 109 | .. automethod:: uproot3.tree.TBranchMethods.allvalues 110 | 111 | .. automethod:: uproot3.tree.TBranchMethods.allitems 112 | 113 | branch information 114 | ^^^^^^^^^^^^^^^^^^ 115 | 116 | .. automethod:: uproot3.tree.TBranchMethods.uncompressedbytes 117 | 118 | .. automethod:: uproot3.tree.TBranchMethods.compressedbytes 119 | 120 | .. automethod:: uproot3.tree.TBranchMethods.compressionratio 121 | 122 | .. automethod:: uproot3.tree.TBranchMethods.numitems 123 | 124 | .. automethod:: uproot3.tree.TBranchMethods.mempartitions 125 | 126 | basket information 127 | ^^^^^^^^^^^^^^^^^^ 128 | 129 | .. automethod:: uproot3.tree.TBranchMethods.basket_entrystart 130 | 131 | .. automethod:: uproot3.tree.TBranchMethods.basket_entrystop 132 | 133 | .. automethod:: uproot3.tree.TBranchMethods.basket_numentries 134 | 135 | .. automethod:: uproot3.tree.TBranchMethods.basket_uncompressedbytes 136 | 137 | .. automethod:: uproot3.tree.TBranchMethods.basket_compressedbytes 138 | 139 | .. automethod:: uproot3.tree.TBranchMethods.basket_numitems 140 | 141 | array 142 | ^^^^^ 143 | 144 | .. automethod:: uproot3.tree.TBranchMethods.array 145 | 146 | lazyarray 147 | ^^^^^^^^^ 148 | 149 | .. automethod:: uproot3.tree.TBranchMethods.lazyarray 150 | 151 | basket 152 | ^^^^^^ 153 | 154 | .. automethod:: uproot3.tree.TBranchMethods.basket 155 | 156 | baskets 157 | ^^^^^^^ 158 | 159 | .. automethod:: uproot3.tree.TBranchMethods.baskets 160 | 161 | iterate_baskets 162 | ^^^^^^^^^^^^^^^ 163 | 164 | .. automethod:: uproot3.tree.TBranchMethods.iterate_baskets 165 | -------------------------------------------------------------------------------- /docs/terminology.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/terminology.png -------------------------------------------------------------------------------- /docs/uproot-scaling-2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/uproot-scaling-2.png -------------------------------------------------------------------------------- /docs/uproot-scaling.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/docs/uproot-scaling.png -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy>=1.13.1 2 | awkward0 3 | uproot3-methods 4 | cachetools 5 | backports.lzma;python_version<"3.3" 6 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | import sys 6 | import os.path 7 | 8 | from setuptools import find_packages 9 | from setuptools import setup 10 | 11 | def get_version(): 12 | g = {} 13 | exec(open(os.path.join("uproot3", "version.py")).read(), g) 14 | return g["__version__"] 15 | 16 | def get_description(): 17 | description = open("README.rst", "rb").read().decode("utf8", "ignore") 18 | 19 | before = """.. image:: https://raw.githubusercontent.com/scikit-hep/uproot3/master/docs/source/logo-300px.png 20 | :alt: uproot 21 | :target: https://github.com/scikit-hep/uproot3 22 | 23 | """ 24 | 25 | start = description.index(".. inclusion-marker-1-5-do-not-remove") 26 | stop = description.index(".. inclusion-marker-3-do-not-remove") 27 | middle = description[start:stop].strip() 28 | start_replaceplots = middle.index(".. inclusion-marker-replaceplots-start") 29 | stop_replaceplots = middle.index(".. inclusion-marker-replaceplots-stop") + len(".. inclusion-marker-replaceplots-stop") 30 | middle = middle[:start_replaceplots] + """ 31 | .. image:: https://raw.githubusercontent.com/scikit-hep/uproot3/master/docs/root-none-muon.png 32 | :width: 350 px 33 | .. image:: https://raw.githubusercontent.com/scikit-hep/uproot3/master/docs/rootnumpy-none-muon.png 34 | :width: 350 px 35 | """ + middle[stop_replaceplots:] 36 | 37 | after = """ 38 | 39 | Tutorial 40 | ======== 41 | 42 | See the `project homepage `__ for a `tutorial `__. 43 | 44 | Run `that tutorial `__ on Binder. 45 | 46 | **Tutorial contents:** 47 | 48 | * `Introduction `__ 49 | * `What is Uproot? `__ 50 | * `Exploring a file `__ 51 | 52 | - `Compressed objects in ROOT files `__ 53 | - `Exploring a TTree `__ 54 | - `Some terminology `__ 55 | 56 | * `Reading arrays from a TTree `__ 57 | * `Caching data `__ 58 | 59 | - `Automatically managed caches `__ 60 | - `Caching at all levels of abstraction `__ 61 | 62 | * `Lazy arrays `__ 63 | 64 | - `Lazy array of many files `__ 65 | - `Lazy arrays with caching `__ 66 | - `Lazy arrays as lightweight skims `__ 67 | - `Lazy arrays in Dask `__ 68 | 69 | * `Iteration `__ 70 | 71 | - `Filenames and entry numbers while iterating `__ 72 | - `Limiting the number of entries to be read `__ 73 | - `Controlling lazy chunk and iteration step sizes `__ 74 | - `Caching and iteration `__ 75 | 76 | * `Changing the output container type `__ 77 | * `Filling Pandas DataFrames `__ 78 | * `Selecting and interpreting branches `__ 79 | 80 | - `TBranch interpretations `__ 81 | - `Reading data into a preexisting array `__ 82 | - `Passing many new interpretations in one call `__ 83 | - `Multiple values per event: fixed size arrays `__ 84 | - `Multiple values per event: leaf-lists `__ 85 | - `Multiple values per event: jagged arrays `__ 86 | - `Jagged array performance `__ 87 | - `Special physics objects: Lorentz vectors `__ 88 | - `Variable-width values: strings `__ 89 | - `Arbitrary objects in TTrees `__ 90 | - `Doubly nested jagged arrays (i.e. std::vector>) `__ 91 | 92 | * `Parallel array reading `__ 93 | * `Histograms, TProfiles, TGraphs, and others `__ 94 | * `Creating and writing data to ROOT files `__ 95 | 96 | - `Writing histograms `__ 97 | - `Writing TTrees `__ 98 | """ 99 | return before + middle + after 100 | 101 | setup(name = "uproot3", 102 | version = get_version(), 103 | packages = find_packages(exclude = ["tests"]), 104 | scripts = [], 105 | description = "ROOT I/O in pure Python and Numpy.", 106 | long_description = get_description(), 107 | author = "Jim Pivarski (IRIS-HEP)", 108 | author_email = "pivarski@princeton.edu", 109 | maintainer = "Jim Pivarski (IRIS-HEP)", 110 | maintainer_email = "pivarski@princeton.edu", 111 | url = "https://github.com/scikit-hep/uproot3", 112 | download_url = "https://github.com/scikit-hep/uproot3/releases", 113 | license = "BSD 3-clause", 114 | test_suite = "tests", 115 | python_requires = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*", 116 | install_requires = ["numpy>=1.13.1", "awkward0", "uproot3-methods", "cachetools"], 117 | setup_requires = ["pytest-runner"], 118 | extras_require = { 119 | "testing": ["pytest>=3.9", "pkgconfig", "lz4", "zstandard", 'backports.lzma;python_version<"3.3"', "xxhash", "mock", "requests"], 120 | "compress": ["lz4", "zstandard", 'backports.lzma;python_version<"3.3"', "xxhash"], 121 | }, 122 | classifiers = [ 123 | "Development Status :: 7 - Inactive", 124 | "Intended Audience :: Developers", 125 | "Intended Audience :: Information Technology", 126 | "Intended Audience :: Science/Research", 127 | "License :: OSI Approved :: BSD License", 128 | "Operating System :: MacOS", 129 | "Operating System :: POSIX", 130 | "Operating System :: Unix", 131 | "Programming Language :: Python", 132 | "Programming Language :: Python :: 2.7", 133 | "Programming Language :: Python :: 3.5", 134 | "Programming Language :: Python :: 3.6", 135 | "Programming Language :: Python :: 3.7", 136 | "Programming Language :: Python :: 3.8", 137 | "Programming Language :: Python :: 3.9", 138 | "Topic :: Scientific/Engineering", 139 | "Topic :: Scientific/Engineering :: Information Analysis", 140 | "Topic :: Scientific/Engineering :: Mathematics", 141 | "Topic :: Scientific/Engineering :: Physics", 142 | "Topic :: Software Development", 143 | "Topic :: Utilities", 144 | ], 145 | platforms = "Any", 146 | ) 147 | -------------------------------------------------------------------------------- /tests/README.md: -------------------------------------------------------------------------------- 1 | # Test coverage 2 | 3 | Note: this message is very old and I'd have to check it before trusting its contents (2019-09-25). 4 | 5 | | Can be tested | Is it tested? | 6 | |:--------------|:-------------:| 7 | | flat numerical types (including booleans) | ✓ | 8 | | strings (`TLeafC` and `TString`) | ✓ | 9 | | signed/unsigned integers | ✓ | 10 | | fixed-size array leaves | ✓ | 11 | | variable-size array leaves | ✓ | 12 | | split objects (`small-evnt-tree-fullsplit.root`) | ✓ | 13 | | split objects in `TClonesArray` | ✓ | 14 | | leaflist (FIXME: not implemented) | **no!** | 15 | | unsplit objects | **(won't do)** | 16 | | `std::vector`, `std::string` (???) | **(unsure)** | 17 | | branch with "speed bumps" | ✓ | 18 | | all compression algorithms (none, zlib, lzma, lz4; ignoring "old") | ✓ | 19 | | files from 2009 (`TTree` version 16) to present (`TTree` version 19) | ✓ | 20 | | nested directories, cycle numbers, '/' and ';' notation | ✓ | 21 | | arrays interface | ✓ | 22 | | iterator interface | ✓ | 23 | | selection by list of branch names | ✓ | 24 | | pass array to fill, rather than `dtype` | ✓ | 25 | | different `outputtypes` | ✓ | 26 | | memory-mapped files | ✓ | 27 | | standard files (not using; remove?) | **no!** | 28 | | XRootD (would have to get XRootD library into `tests_require` somehow...) | **no!** | 29 | | big files (64-bit addresses in TFile header) | **no!** | 30 | | parallel processing (not deterministic: hard to include in test suite) | **no!** | 31 | | exception raising! | **no!** | 32 | | informational methods (keys/branches listings) | **partial** | 33 | | partitioning routines | ✓ | 34 | | low-level TBranch.baskets interface | **no!** | 35 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | -------------------------------------------------------------------------------- /tests/samples/HZZ-lz4.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/HZZ-lz4.root -------------------------------------------------------------------------------- /tests/samples/HZZ-lzma.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/HZZ-lzma.root -------------------------------------------------------------------------------- /tests/samples/HZZ-objects.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/HZZ-objects.root -------------------------------------------------------------------------------- /tests/samples/HZZ-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/HZZ-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/HZZ-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/HZZ-zlib.root -------------------------------------------------------------------------------- /tests/samples/HZZ-zstd.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/HZZ-zstd.root -------------------------------------------------------------------------------- /tests/samples/HZZ.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/HZZ.root -------------------------------------------------------------------------------- /tests/samples/Zmumu-lz4.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/Zmumu-lz4.root -------------------------------------------------------------------------------- /tests/samples/Zmumu-lzma.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/Zmumu-lzma.root -------------------------------------------------------------------------------- /tests/samples/Zmumu-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/Zmumu-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/Zmumu-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/Zmumu-zlib.root -------------------------------------------------------------------------------- /tests/samples/Zmumu-zstd.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/Zmumu-zstd.root -------------------------------------------------------------------------------- /tests/samples/Zmumu.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/Zmumu.root -------------------------------------------------------------------------------- /tests/samples/demo-double32.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/demo-double32.root -------------------------------------------------------------------------------- /tests/samples/foriter.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/foriter.root -------------------------------------------------------------------------------- /tests/samples/foriter2.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/foriter2.root -------------------------------------------------------------------------------- /tests/samples/from-geant4.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/from-geant4.root -------------------------------------------------------------------------------- /tests/samples/hepdata-example.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/hepdata-example.root -------------------------------------------------------------------------------- /tests/samples/histograms.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/histograms.root -------------------------------------------------------------------------------- /tests/samples/issue124.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue124.root -------------------------------------------------------------------------------- /tests/samples/issue126a.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue126a.root -------------------------------------------------------------------------------- /tests/samples/issue126b.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue126b.root -------------------------------------------------------------------------------- /tests/samples/issue187.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue187.root -------------------------------------------------------------------------------- /tests/samples/issue21.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue21.root -------------------------------------------------------------------------------- /tests/samples/issue213.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue213.root -------------------------------------------------------------------------------- /tests/samples/issue232.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue232.root -------------------------------------------------------------------------------- /tests/samples/issue243-new.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue243-new.root -------------------------------------------------------------------------------- /tests/samples/issue243.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue243.root -------------------------------------------------------------------------------- /tests/samples/issue30.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue30.root -------------------------------------------------------------------------------- /tests/samples/issue31.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue31.root -------------------------------------------------------------------------------- /tests/samples/issue327.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue327.root -------------------------------------------------------------------------------- /tests/samples/issue33.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue33.root -------------------------------------------------------------------------------- /tests/samples/issue367.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue367.root -------------------------------------------------------------------------------- /tests/samples/issue371.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue371.root -------------------------------------------------------------------------------- /tests/samples/issue38a.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue38a.root -------------------------------------------------------------------------------- /tests/samples/issue38b.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue38b.root -------------------------------------------------------------------------------- /tests/samples/issue390.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue390.root -------------------------------------------------------------------------------- /tests/samples/issue399.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue399.root -------------------------------------------------------------------------------- /tests/samples/issue404.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue404.root -------------------------------------------------------------------------------- /tests/samples/issue429.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue429.root -------------------------------------------------------------------------------- /tests/samples/issue431.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue431.root -------------------------------------------------------------------------------- /tests/samples/issue434.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue434.root -------------------------------------------------------------------------------- /tests/samples/issue447.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue447.root -------------------------------------------------------------------------------- /tests/samples/issue447_recursive.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue447_recursive.root -------------------------------------------------------------------------------- /tests/samples/issue46.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue46.root -------------------------------------------------------------------------------- /tests/samples/issue49.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue49.root -------------------------------------------------------------------------------- /tests/samples/issue57.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue57.root -------------------------------------------------------------------------------- /tests/samples/issue60.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue60.root -------------------------------------------------------------------------------- /tests/samples/issue63.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue63.root -------------------------------------------------------------------------------- /tests/samples/issue64.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue64.root -------------------------------------------------------------------------------- /tests/samples/issue66.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue66.root -------------------------------------------------------------------------------- /tests/samples/issue70.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue70.root -------------------------------------------------------------------------------- /tests/samples/issue74.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue74.root -------------------------------------------------------------------------------- /tests/samples/issue76.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue76.root -------------------------------------------------------------------------------- /tests/samples/issue79.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue79.root -------------------------------------------------------------------------------- /tests/samples/issue96.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/issue96.root -------------------------------------------------------------------------------- /tests/samples/leaflist.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/leaflist.root -------------------------------------------------------------------------------- /tests/samples/make_HZZ_objects.C: -------------------------------------------------------------------------------- 1 | #include 2 | #include "TLorentzVector.h" 3 | 4 | void make_HZZ_objects() { 5 | TFile* file = new TFile("tests/samples/HZZ.root"); 6 | TTree* tree; 7 | file->GetObject("events", tree); 8 | 9 | TTreeReader reader(tree); 10 | 11 | TTreeReaderValue NJet(reader, "NJet"); 12 | TTreeReaderArray Jet_Px(reader, "Jet_Px"); 13 | TTreeReaderArray Jet_Py(reader, "Jet_Py"); 14 | TTreeReaderArray Jet_Pz(reader, "Jet_Pz"); 15 | TTreeReaderArray Jet_E(reader, "Jet_E"); 16 | TTreeReaderArray Jet_btag(reader, "Jet_btag"); 17 | TTreeReaderArray Jet_ID(reader, "Jet_ID"); 18 | 19 | TTreeReaderValue NMuon(reader, "NMuon"); 20 | TTreeReaderArray Muon_Px(reader, "Muon_Px"); 21 | TTreeReaderArray Muon_Py(reader, "Muon_Py"); 22 | TTreeReaderArray Muon_Pz(reader, "Muon_Pz"); 23 | TTreeReaderArray Muon_E(reader, "Muon_E"); 24 | TTreeReaderArray Muon_Charge(reader, "Muon_Charge"); 25 | TTreeReaderArray Muon_Iso(reader, "Muon_Iso"); 26 | 27 | TTreeReaderValue NElectron(reader, "NElectron"); 28 | TTreeReaderArray Electron_Px(reader, "Electron_Px"); 29 | TTreeReaderArray Electron_Py(reader, "Electron_Py"); 30 | TTreeReaderArray Electron_Pz(reader, "Electron_Pz"); 31 | TTreeReaderArray Electron_E(reader, "Electron_E"); 32 | TTreeReaderArray Electron_Charge(reader, "Electron_Charge"); 33 | TTreeReaderArray Electron_Iso(reader, "Electron_Iso"); 34 | 35 | TTreeReaderValue NPhoton(reader, "NPhoton"); 36 | TTreeReaderArray Photon_Px(reader, "Photon_Px"); 37 | TTreeReaderArray Photon_Py(reader, "Photon_Py"); 38 | TTreeReaderArray Photon_Pz(reader, "Photon_Pz"); 39 | TTreeReaderArray Photon_E(reader, "Photon_E.Photons_E"); 40 | TTreeReaderArray Photon_Iso(reader, "Photon_Iso"); 41 | 42 | TTreeReaderValue MET_px(reader, "MET_px"); 43 | TTreeReaderValue MET_py(reader, "MET_py"); 44 | 45 | TTreeReaderValue MChadronicBottom_px(reader, "MChadronicBottom_px"); 46 | TTreeReaderValue MChadronicBottom_py(reader, "MChadronicBottom_py"); 47 | TTreeReaderValue MChadronicBottom_pz(reader, "MChadronicBottom_pz"); 48 | 49 | TTreeReaderValue MCleptonicBottom_px(reader, "MCleptonicBottom_px"); 50 | TTreeReaderValue MCleptonicBottom_py(reader, "MCleptonicBottom_py"); 51 | TTreeReaderValue MCleptonicBottom_pz(reader, "MCleptonicBottom_pz"); 52 | 53 | TTreeReaderValue MChadronicWDecayQuark_px(reader, "MChadronicWDecayQuark_px"); 54 | TTreeReaderValue MChadronicWDecayQuark_py(reader, "MChadronicWDecayQuark_py"); 55 | TTreeReaderValue MChadronicWDecayQuark_pz(reader, "MChadronicWDecayQuark_pz"); 56 | TTreeReaderValue MChadronicWDecayQuarkBar_px(reader, "MChadronicWDecayQuarkBar_px"); 57 | TTreeReaderValue MChadronicWDecayQuarkBar_py(reader, "MChadronicWDecayQuarkBar_py"); 58 | TTreeReaderValue MChadronicWDecayQuarkBar_pz(reader, "MChadronicWDecayQuarkBar_pz"); 59 | 60 | TTreeReaderValue MClepton_px(reader, "MClepton_px"); 61 | TTreeReaderValue MClepton_py(reader, "MClepton_py"); 62 | TTreeReaderValue MClepton_pz(reader, "MClepton_pz"); 63 | TTreeReaderValue MCleptonPDGid(reader, "MCleptonPDGid"); 64 | 65 | TTreeReaderValue MCneutrino_px(reader, "MCneutrino_px"); 66 | TTreeReaderValue MCneutrino_py(reader, "MCneutrino_py"); 67 | TTreeReaderValue MCneutrino_pz(reader, "MCneutrino_pz"); 68 | 69 | TTreeReaderValue NPrimaryVertices(reader, "NPrimaryVertices"); 70 | TTreeReaderValue triggerIsoMu24(reader, "triggerIsoMu24"); 71 | TTreeReaderValue EventWeight(reader, "EventWeight"); 72 | 73 | TFile* outfile = new TFile("HZZ-objects.root", "RECREATE"); 74 | TTree outtree("events", ""); 75 | 76 | std::vector jetp4; 77 | std::vector jetbtag; 78 | std::vector jetid; 79 | outtree.Branch("jetp4", "std::vector", &jetp4); 80 | outtree.Branch("jetbtag", "std::vector", &jetbtag); 81 | outtree.Branch("jetid", "std::vector", &jetid); 82 | 83 | std::vector muonp4; 84 | std::vector muonq; 85 | std::vector muoniso; 86 | outtree.Branch("muonp4", "std::vector", &muonp4); 87 | outtree.Branch("muonq", "std::vector", &muonq); 88 | outtree.Branch("muoniso", "std::vector", &muoniso); 89 | 90 | std::vector electronp4; 91 | std::vector electronq; 92 | std::vector electroniso; 93 | outtree.Branch("electronp4", "std::vector", &electronp4); 94 | outtree.Branch("electronq", "std::vector", &electronq); 95 | outtree.Branch("electroniso", "std::vector", &electroniso); 96 | 97 | std::vector photonp4; 98 | std::vector photoniso; 99 | outtree.Branch("photonp4", "std::vector", &photonp4); 100 | outtree.Branch("photoniso", "std::vector", &photoniso); 101 | 102 | TVector2 MET; 103 | outtree.Branch("MET", "TVector2", &MET); 104 | 105 | TVector3 MC_bquarkhadronic; 106 | outtree.Branch("MC_bquarkhadronic", "TVector3", &MC_bquarkhadronic); 107 | 108 | TVector3 MC_bquarkleptonic; 109 | outtree.Branch("MC_bquarkleptonic", "TVector3", &MC_bquarkleptonic); 110 | 111 | TVector3 MC_wdecayb; 112 | outtree.Branch("MC_wdecayb", "TVector3", &MC_wdecayb); 113 | 114 | TVector3 MC_wdecaybbar; 115 | outtree.Branch("MC_wdecaybbar", "TVector3", &MC_wdecaybbar); 116 | 117 | TVector3 MC_lepton; 118 | int32_t MC_leptonpdgid; 119 | outtree.Branch("MC_lepton", "TVector3", &MC_lepton); 120 | outtree.Branch("MC_leptonpdgid", &MC_leptonpdgid, "MC_leptonpdgid/I"); 121 | 122 | TVector3 MC_neutrino; 123 | outtree.Branch("MC_neutrino", "TVector3", &MC_neutrino); 124 | 125 | int32_t num_primaryvertex; 126 | outtree.Branch("num_primaryvertex", &num_primaryvertex, "num_primaryvertex/I"); 127 | 128 | bool trigger_isomu24; 129 | outtree.Branch("trigger_isomu24", &trigger_isomu24, "trigger_isomu24/O"); 130 | 131 | float eventweight; 132 | outtree.Branch("eventweight", &eventweight, "eventweight/F"); 133 | 134 | while (reader.Next()) { 135 | jetp4.clear(); 136 | jetbtag.clear(); 137 | jetid.clear(); 138 | for (int i = 0; i < *NJet; i++) { 139 | jetp4.push_back(TLorentzVector(Jet_Px[i], Jet_Py[i], Jet_Pz[i], Jet_E[i])); 140 | jetbtag.push_back(Jet_btag[i]); 141 | jetid.push_back(Jet_ID[i]); 142 | } 143 | 144 | muonp4.clear(); 145 | muonq.clear(); 146 | muoniso.clear(); 147 | for (int i = 0; i < *NMuon; i++) { 148 | muonp4.push_back(TLorentzVector(Muon_Px[i], Muon_Py[i], Muon_Pz[i], Muon_E[i])); 149 | muonq.push_back(Muon_Charge[i]); 150 | muoniso.push_back(Muon_Iso[i]); 151 | } 152 | 153 | electronp4.clear(); 154 | electronq.clear(); 155 | electroniso.clear(); 156 | for (int i = 0; i < *NElectron; i++) { 157 | electronp4.push_back(TLorentzVector(Electron_Px[i], Electron_Py[i], Electron_Pz[i], Electron_E[i])); 158 | electronq.push_back(Electron_Charge[i]); 159 | electroniso.push_back(Electron_Iso[i]); 160 | } 161 | 162 | photonp4.clear(); 163 | photoniso.clear(); 164 | for (int i = 0; i < *NPhoton; i++) { 165 | photonp4.push_back(TLorentzVector(Photon_Px[i], Photon_Py[i], Photon_Pz[i], Photon_E[i])); 166 | photoniso.push_back(Photon_Iso[i]); 167 | } 168 | 169 | MET.Set(*MET_px, *MET_py); 170 | MC_bquarkhadronic.SetXYZ(*MChadronicBottom_px, *MChadronicBottom_py, *MChadronicBottom_pz); 171 | MC_bquarkleptonic.SetXYZ(*MCleptonicBottom_px, *MCleptonicBottom_py, *MCleptonicBottom_pz); 172 | MC_wdecayb.SetXYZ(*MChadronicWDecayQuark_px, *MChadronicWDecayQuark_py, *MChadronicWDecayQuark_pz); 173 | MC_wdecaybbar.SetXYZ(*MChadronicWDecayQuarkBar_px, *MChadronicWDecayQuarkBar_py, *MChadronicWDecayQuarkBar_pz); 174 | MC_lepton.SetXYZ(*MClepton_px, *MClepton_py, *MClepton_pz); 175 | MC_leptonpdgid = *MCleptonPDGid; 176 | MC_neutrino.SetXYZ(*MCneutrino_px, *MCneutrino_py, *MCneutrino_pz); 177 | num_primaryvertex = *NPrimaryVertices; 178 | trigger_isomu24 = *triggerIsoMu24; 179 | eventweight = *EventWeight; 180 | 181 | outtree.Fill(); 182 | } 183 | 184 | outtree.Write(); 185 | outfile->Close(); 186 | } 187 | -------------------------------------------------------------------------------- /tests/samples/make_HZZ_objects.h: -------------------------------------------------------------------------------- 1 | #include "TLorentzVector.h" 2 | #include 3 | 4 | #pragma link C++ class std::vector+; 5 | -------------------------------------------------------------------------------- /tests/samples/mc10events.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/mc10events.root -------------------------------------------------------------------------------- /tests/samples/nesteddirs.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/nesteddirs.root -------------------------------------------------------------------------------- /tests/samples/ntpl001_staff.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/ntpl001_staff.root -------------------------------------------------------------------------------- /tests/samples/sample-5.23.02-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.23.02-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-5.23.02-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.23.02-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample-5.24.00-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.24.00-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-5.24.00-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.24.00-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample-5.25.02-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.25.02-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-5.25.02-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.25.02-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample-5.26.00-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.26.00-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-5.26.00-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.26.00-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample-5.27.02-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.27.02-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-5.27.02-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.27.02-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample-5.28.00-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.28.00-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-5.28.00-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.28.00-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample-5.29.02-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.29.02-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-5.29.02-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.29.02-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample-5.30.00-lzma.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.30.00-lzma.root -------------------------------------------------------------------------------- /tests/samples/sample-5.30.00-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.30.00-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-5.30.00-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-5.30.00-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample-6.08.04-lzma.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.08.04-lzma.root -------------------------------------------------------------------------------- /tests/samples/sample-6.08.04-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.08.04-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-6.08.04-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.08.04-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample-6.10.05-lz4.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.10.05-lz4.root -------------------------------------------------------------------------------- /tests/samples/sample-6.10.05-lzma.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.10.05-lzma.root -------------------------------------------------------------------------------- /tests/samples/sample-6.10.05-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.10.05-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-6.10.05-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.10.05-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample-6.14.00-lz4.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.14.00-lz4.root -------------------------------------------------------------------------------- /tests/samples/sample-6.14.00-lzma.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.14.00-lzma.root -------------------------------------------------------------------------------- /tests/samples/sample-6.14.00-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.14.00-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-6.14.00-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.14.00-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample-6.16.00-lz4.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.16.00-lz4.root -------------------------------------------------------------------------------- /tests/samples/sample-6.16.00-lzma.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.16.00-lzma.root -------------------------------------------------------------------------------- /tests/samples/sample-6.16.00-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.16.00-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-6.16.00-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.16.00-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample-6.18.00-lz4.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.18.00-lz4.root -------------------------------------------------------------------------------- /tests/samples/sample-6.18.00-lzma.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.18.00-lzma.root -------------------------------------------------------------------------------- /tests/samples/sample-6.18.00-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.18.00-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-6.18.00-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.18.00-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample-6.20.04-lz4.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.20.04-lz4.root -------------------------------------------------------------------------------- /tests/samples/sample-6.20.04-lzma.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.20.04-lzma.root -------------------------------------------------------------------------------- /tests/samples/sample-6.20.04-uncompressed.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.20.04-uncompressed.root -------------------------------------------------------------------------------- /tests/samples/sample-6.20.04-zlib.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/sample-6.20.04-zlib.root -------------------------------------------------------------------------------- /tests/samples/sample4version.C: -------------------------------------------------------------------------------- 1 | #include "TFile.h" 2 | #include "TTree.h" 3 | #include "TBranch.h" 4 | #include "stdio.h" 5 | 6 | void sample4version(const char* version, const char* compression) { 7 | char filename[200]; 8 | TFile *f; 9 | 10 | if (strcmp(compression, "uncompressed") == 0) { 11 | sprintf(filename, "sample-%s-uncompressed.root", version); 12 | f = new TFile(filename, "RECREATE"); 13 | f->SetCompressionAlgorithm(1); 14 | f->SetCompressionLevel(0); 15 | } 16 | else if (strcmp(compression, "zlib") == 0) { 17 | sprintf(filename, "sample-%s-zlib.root", version); 18 | f = new TFile(filename, "RECREATE"); 19 | f->SetCompressionAlgorithm(1); 20 | f->SetCompressionLevel(4); 21 | } 22 | else if (strcmp(compression, "lzma") == 0) { 23 | sprintf(filename, "sample-%s-lzma.root", version); 24 | f = new TFile(filename, "RECREATE"); 25 | f->SetCompressionAlgorithm(2); 26 | f->SetCompressionLevel(4); 27 | } 28 | else if (strcmp(compression, "lz4") == 0) { 29 | sprintf(filename, "sample-%s-lz4.root", version); 30 | f = new TFile(filename, "RECREATE"); 31 | f->SetCompressionAlgorithm(4); 32 | f->SetCompressionLevel(4); 33 | } 34 | else if (strcmp(compression, "zstd") == 0) { 35 | sprintf(filename, "sample-%s-zstd.root", version); 36 | f = new TFile(filename, "RECREATE"); 37 | f->SetCompressionAlgorithm(5); 38 | f->SetCompressionLevel(5); 39 | } 40 | else 41 | exit(-1); 42 | 43 | TTree *t = new TTree("sample", ""); 44 | Int_t n; 45 | t->Branch("n", &n, "n/I", 50); 46 | 47 | Bool_t b; 48 | t->Branch("b", &b, "b/O", 50); 49 | Bool_t ab[3]; 50 | t->Branch("ab", ab, "ab[3]/O", 50); 51 | Bool_t Ab[10]; 52 | t->Branch("Ab", Ab, "Ab[n]/O", 50); 53 | 54 | Char_t i1; 55 | t->Branch("i1", &i1, "i1/B", 50); 56 | Char_t ai1[3]; 57 | t->Branch("ai1", ai1, "ai1[3]/B", 50); 58 | Char_t Ai1[10]; 59 | t->Branch("Ai1", Ai1, "Ai1[n]/B", 50); 60 | 61 | UChar_t u1; 62 | t->Branch("u1", &u1, "u1/b", 50); 63 | UChar_t au1[3]; 64 | t->Branch("au1", au1, "au1[3]/b", 50); 65 | UChar_t Au1[10]; 66 | t->Branch("Au1", Au1, "Au1[n]/b", 50); 67 | 68 | Short_t i2; 69 | t->Branch("i2", &i2, "i2/S", 50); 70 | Short_t ai2[3]; 71 | t->Branch("ai2", ai2, "ai2[3]/S", 50); 72 | Short_t Ai2[10]; 73 | t->Branch("Ai2", Ai2, "Ai2[n]/S", 50); 74 | 75 | UShort_t u2; 76 | t->Branch("u2", &u2, "u2/s", 50); 77 | UShort_t au2[3]; 78 | t->Branch("au2", au2, "au2[3]/s", 50); 79 | UShort_t Au2[10]; 80 | t->Branch("Au2", Au2, "Au2[n]/s", 50); 81 | 82 | Int_t i4; 83 | t->Branch("i4", &i4, "i4/I", 50); 84 | Int_t ai4[3]; 85 | t->Branch("ai4", ai4, "ai4[3]/I", 50); 86 | Int_t Ai4[10]; 87 | t->Branch("Ai4", Ai4, "Ai4[n]/I", 50); 88 | 89 | UInt_t u4; 90 | t->Branch("u4", &u4, "u4/i", 50); 91 | UInt_t au4[3]; 92 | t->Branch("au4", au4, "au4[3]/i", 50); 93 | UInt_t Au4[10]; 94 | t->Branch("Au4", Au4, "Au4[n]/i", 50); 95 | 96 | Long64_t i8; 97 | t->Branch("i8", &i8, "i8/L", 50); 98 | Long64_t ai8[3]; 99 | t->Branch("ai8", ai8, "ai8[3]/L", 50); 100 | Long64_t Ai8[10]; 101 | t->Branch("Ai8", Ai8, "Ai8[n]/L", 50); 102 | 103 | ULong64_t u8; 104 | t->Branch("u8", &u8, "u8/l", 50); 105 | ULong64_t au8[3]; 106 | t->Branch("au8", au8, "au8[3]/l", 50); 107 | ULong64_t Au8[10]; 108 | t->Branch("Au8", Au8, "Au8[n]/l", 50); 109 | 110 | float f4; 111 | t->Branch("f4", &f4, "f4/F", 50); 112 | float af4[3]; 113 | t->Branch("af4", af4, "af4[3]/F", 50); 114 | float Af4[10]; 115 | t->Branch("Af4", Af4, "Af4[n]/F", 50); 116 | 117 | double f8; 118 | t->Branch("f8", &f8, "f8/D", 50); 119 | double af8[3]; 120 | t->Branch("af8", af8, "af8[3]/D", 50); 121 | double Af8[10]; 122 | t->Branch("Af8", Af8, "Af8[n]/D", 50); 123 | 124 | char str[100]; 125 | t->Branch("str", &str, "str/C", 150); 126 | 127 | for (int i = 0; i < 30; i++) { 128 | n = (i % 5); 129 | 130 | for (int j = 0; j < n + 1; j++) { 131 | b = (i % 2 == 0); 132 | ab[0] = (i % 2 == 1); 133 | ab[1] = (i % 2 == 0); 134 | ab[2] = (i % 2 == 1); 135 | Ab[n] = ((i + j) % 2 == 0); 136 | 137 | i1 = i - 15; 138 | ai1[0] = i - 14; 139 | ai1[1] = i - 13; 140 | ai1[2] = i - 12; 141 | Ai1[n] = i - 15 + j; 142 | 143 | u1 = i; 144 | au1[0] = i + 1; 145 | au1[1] = i + 2; 146 | au1[2] = i + 3; 147 | Au1[n] = i + j; 148 | 149 | i2 = i - 15; 150 | ai2[0] = i - 14; 151 | ai2[1] = i - 13; 152 | ai2[2] = i - 12; 153 | Ai2[n] = i - 15 + j; 154 | 155 | u2 = i; 156 | au2[0] = i + 1; 157 | au2[1] = i + 2; 158 | au2[2] = i + 3; 159 | Au2[n] = i + j; 160 | 161 | i4 = i - 15; 162 | ai4[0] = i - 14; 163 | ai4[1] = i - 13; 164 | ai4[2] = i - 12; 165 | Ai4[n] = i - 15 + j; 166 | 167 | u4 = i; 168 | au4[0] = i + 1; 169 | au4[1] = i + 2; 170 | au4[2] = i + 3; 171 | Au4[n] = i + j; 172 | 173 | i8 = i - 15; 174 | ai8[0] = i - 14; 175 | ai8[1] = i - 13; 176 | ai8[2] = i - 12; 177 | Ai8[n] = i - 15 + j; 178 | 179 | u8 = i; 180 | au8[0] = i + 1; 181 | au8[1] = i + 2; 182 | au8[2] = i + 3; 183 | Au8[n] = i + j; 184 | 185 | f4 = i - 14.9; 186 | af4[0] = i - 13.9; 187 | af4[1] = i - 12.9; 188 | af4[2] = i - 11.9; 189 | Af4[n] = i - 15.0 + j*0.1; 190 | 191 | f8 = i - 14.9; 192 | af8[0] = i - 13.9; 193 | af8[1] = i - 12.9; 194 | af8[2] = i - 11.9; 195 | Af8[n] = i - 15.0 + j*0.1; 196 | 197 | sprintf(str, "hey-%d", i); 198 | } 199 | 200 | t->Fill(); 201 | } 202 | 203 | t->Write(); 204 | f->Close(); 205 | 206 | exit(0); 207 | } 208 | -------------------------------------------------------------------------------- /tests/samples/simple.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/simple.root -------------------------------------------------------------------------------- /tests/samples/small-dy-nooffsets.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/small-dy-nooffsets.root -------------------------------------------------------------------------------- /tests/samples/small-dy-withoffsets.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/small-dy-withoffsets.root -------------------------------------------------------------------------------- /tests/samples/small-evnt-tree-fullsplit.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/small-evnt-tree-fullsplit.root -------------------------------------------------------------------------------- /tests/samples/small-evnt-tree-nosplit.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/small-evnt-tree-nosplit.root -------------------------------------------------------------------------------- /tests/samples/small-flat-tree.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/small-flat-tree.root -------------------------------------------------------------------------------- /tests/samples/vectorVectorDouble.root: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scikit-hep/uproot3/54f5151fb7c686c3a161fbe44b9f299e482f346b/tests/samples/vectorVectorDouble.root -------------------------------------------------------------------------------- /tests/test_cache.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | import uproot3 6 | 7 | class Test(object): 8 | def test_flat_array(self): 9 | branch = uproot3.open("tests/samples/sample-6.10.05-uncompressed.root")["sample"]["i8"] 10 | expectation = [-15, -14, -13, -12, -11, -10, -9, -8, -7, -6, -5, -4, -3, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14] 11 | 12 | cache = {} 13 | for entrystart, entrystop in [(None, None), (1, None), (1, 2), (1, 10), (10, 11), (10, 20), (6, 12), (6, 13)]: 14 | assert len(cache) == 0 15 | assert branch.array(entrystart=entrystart, entrystop=entrystop, cache=cache).tolist() == expectation[entrystart:entrystop] 16 | assert len(cache) > 0 17 | assert branch.array(entrystart=entrystart, entrystop=entrystop, cache=cache).tolist() == expectation[entrystart:entrystop] 18 | cache = {} 19 | 20 | basketcache = {} 21 | for entrystart, entrystop in [(None, None), (1, None), (1, 2), (1, 10), (10, 11), (10, 20), (6, 12), (6, 13)]: 22 | assert len(basketcache) == 0 23 | assert branch.array(entrystart=entrystart, entrystop=entrystop, basketcache=basketcache).tolist() == expectation[entrystart:entrystop] 24 | assert len(basketcache) > 0 25 | assert branch.array(entrystart=entrystart, entrystop=entrystop, basketcache=basketcache).tolist() == expectation[entrystart:entrystop] 26 | basketcache = {} 27 | 28 | keycache = {} 29 | for entrystart, entrystop in [(None, None), (1, None), (1, 2), (1, 10), (10, 11), (10, 20), (6, 12), (6, 13)]: 30 | assert len(keycache) == 0 31 | assert branch.array(entrystart=entrystart, entrystop=entrystop, keycache=keycache).tolist() == expectation[entrystart:entrystop] 32 | assert len(keycache) > 0 33 | assert branch.array(entrystart=entrystart, entrystop=entrystop, keycache=keycache).tolist() == expectation[entrystart:entrystop] 34 | keycache = {} 35 | 36 | def test_regular_array(self): 37 | branch = uproot3.open("tests/samples/sample-6.10.05-uncompressed.root")["sample"]["ai8"] 38 | expectation = [[-14, -13, -12], [-13, -12, -11], [-12, -11, -10], [-11, -10, -9], [-10, -9, -8], [-9, -8, -7], [-8, -7, -6], [-7, -6, -5], [-6, -5, -4], [-5, -4, -3], [-4, -3, -2], [-3, -2, -1], [-2, -1, 0], [-1, 0, 1], [0, 1, 2], [1, 2, 3], [2, 3, 4], [3, 4, 5], [4, 5, 6], [5, 6, 7], [6, 7, 8], [7, 8, 9], [8, 9, 10], [9, 10, 11], [10, 11, 12], [11, 12, 13], [12, 13, 14], [13, 14, 15], [14, 15, 16], [15, 16, 17]] 39 | 40 | cache = {} 41 | for entrystart, entrystop in [(None, None), (1, None), (1, 2), (1, 10), (10, 11), (10, 20), (6, 12), (6, 13)]: 42 | assert len(cache) == 0 43 | assert branch.array(entrystart=entrystart, entrystop=entrystop, cache=cache).tolist() == expectation[entrystart:entrystop] 44 | assert len(cache) > 0 45 | assert branch.array(entrystart=entrystart, entrystop=entrystop, cache=cache).tolist() == expectation[entrystart:entrystop] 46 | cache = {} 47 | 48 | basketcache = {} 49 | for entrystart, entrystop in [(None, None), (1, None), (1, 2), (1, 10), (10, 11), (10, 20), (6, 12), (6, 13)]: 50 | assert len(basketcache) == 0 51 | assert branch.array(entrystart=entrystart, entrystop=entrystop, basketcache=basketcache).tolist() == expectation[entrystart:entrystop] 52 | assert len(basketcache) > 0 53 | assert branch.array(entrystart=entrystart, entrystop=entrystop, basketcache=basketcache).tolist() == expectation[entrystart:entrystop] 54 | basketcache = {} 55 | 56 | keycache = {} 57 | for entrystart, entrystop in [(None, None), (1, None), (1, 2), (1, 10), (10, 11), (10, 20), (6, 12), (6, 13)]: 58 | assert len(keycache) == 0 59 | assert branch.array(entrystart=entrystart, entrystop=entrystop, keycache=keycache).tolist() == expectation[entrystart:entrystop] 60 | assert len(keycache) > 0 61 | assert branch.array(entrystart=entrystart, entrystop=entrystop, keycache=keycache).tolist() == expectation[entrystart:entrystop] 62 | keycache = {} 63 | 64 | def test_irregular_array(self): 65 | branch = uproot3.open("tests/samples/sample-6.10.05-uncompressed.root")["sample"]["Ai8"] 66 | expectation = [[], [-15], [-15, -13], [-15, -13, -11], [-15, -13, -11, -9], [], [-10], [-10, -8], [-10, -8, -6], [-10, -8, -6, -4], [], [-5], [-5, -3], [-5, -3, -1], [-5, -3, -1, 1], [], [0], [0, 2], [0, 2, 4], [0, 2, 4, 6], [], [5], [5, 7], [5, 7, 9], [5, 7, 9, 11], [], [10], [10, 12], [10, 12, 14], [10, 12, 14, 16]] 67 | assert [len(x) for x in expectation] == [0, 1, 2, 3, 4] * 6 68 | 69 | cache = {} 70 | for entrystart, entrystop in [(None, None), (1, None), (1, 2), (1, 10), (10, 11), (10, 20), (6, 12), (6, 13)]: 71 | assert len(cache) == 0 72 | assert branch.array(entrystart=entrystart, entrystop=entrystop, cache=cache).tolist() == expectation[entrystart:entrystop] 73 | assert len(cache) > 0 74 | assert branch.array(entrystart=entrystart, entrystop=entrystop, cache=cache).tolist() == expectation[entrystart:entrystop] 75 | cache = {} 76 | 77 | basketcache = {} 78 | for entrystart, entrystop in [(None, None), (1, None), (1, 2), (1, 10), (10, 11), (10, 20), (6, 12), (6, 13)]: 79 | assert len(basketcache) == 0 80 | assert branch.array(entrystart=entrystart, entrystop=entrystop, basketcache=basketcache).tolist() == expectation[entrystart:entrystop] 81 | assert len(basketcache) > 0 82 | assert branch.array(entrystart=entrystart, entrystop=entrystop, basketcache=basketcache).tolist() == expectation[entrystart:entrystop] 83 | basketcache = {} 84 | 85 | keycache = {} 86 | for entrystart, entrystop in [(None, None), (1, None), (1, 2), (1, 10), (10, 11), (10, 20), (6, 12), (6, 13)]: 87 | assert len(keycache) == 0 88 | assert branch.array(entrystart=entrystart, entrystop=entrystop, keycache=keycache).tolist() == expectation[entrystart:entrystop] 89 | assert len(keycache) > 0 90 | assert branch.array(entrystart=entrystart, entrystop=entrystop, keycache=keycache).tolist() == expectation[entrystart:entrystop] 91 | keycache = {} 92 | 93 | def test_strings_array(self): 94 | branch = uproot3.open("tests/samples/sample-6.10.05-uncompressed.root")["sample"]["str"] 95 | expectation = [b"hey-0", b"hey-1", b"hey-2", b"hey-3", b"hey-4", b"hey-5", b"hey-6", b"hey-7", b"hey-8", b"hey-9", b"hey-10", b"hey-11", b"hey-12", b"hey-13", b"hey-14", b"hey-15", b"hey-16", b"hey-17", b"hey-18", b"hey-19", b"hey-20", b"hey-21", b"hey-22", b"hey-23", b"hey-24", b"hey-25", b"hey-26", b"hey-27", b"hey-28", b"hey-29"] 96 | 97 | cache = {} 98 | for entrystart, entrystop in [(None, None), (1, None), (1, 2), (1, 10), (10, 11), (10, 20), (6, 12), (6, 13)]: 99 | assert len(cache) == 0 100 | assert branch.array(entrystart=entrystart, entrystop=entrystop, cache=cache).tolist() == expectation[entrystart:entrystop] 101 | assert len(cache) > 0 102 | assert branch.array(entrystart=entrystart, entrystop=entrystop, cache=cache).tolist() == expectation[entrystart:entrystop] 103 | cache = {} 104 | 105 | basketcache = {} 106 | for entrystart, entrystop in [(None, None), (1, None), (1, 2), (1, 10), (10, 11), (10, 20), (6, 12), (6, 13)]: 107 | assert len(basketcache) == 0 108 | assert branch.array(entrystart=entrystart, entrystop=entrystop, basketcache=basketcache).tolist() == expectation[entrystart:entrystop] 109 | assert len(basketcache) > 0 110 | assert branch.array(entrystart=entrystart, entrystop=entrystop, basketcache=basketcache).tolist() == expectation[entrystart:entrystop] 111 | basketcache = {} 112 | 113 | keycache = {} 114 | for entrystart, entrystop in [(None, None), (1, None), (1, 2), (1, 10), (10, 11), (10, 20), (6, 12), (6, 13)]: 115 | assert len(keycache) == 0 116 | assert branch.array(entrystart=entrystart, entrystop=entrystop, keycache=keycache).tolist() == expectation[entrystart:entrystop] 117 | assert len(keycache) > 0 118 | assert branch.array(entrystart=entrystart, entrystop=entrystop, keycache=keycache).tolist() == expectation[entrystart:entrystop] 119 | keycache = {} 120 | -------------------------------------------------------------------------------- /tests/test_compression.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | import pytest 6 | try: 7 | import lzma 8 | except ImportError: 9 | lzma = pytest.importorskip('backports.lzma') 10 | lz4 = pytest.importorskip('lz4') 11 | zstandard = pytest.importorskip('zstandard') 12 | import uproot3 13 | 14 | 15 | class Test(object): 16 | def test_compression_identity(self): 17 | assert uproot3.open("tests/samples/Zmumu-zlib.root").compression.algoname == "zlib" 18 | assert uproot3.open("tests/samples/Zmumu-zlib.root").compression.level == 4 19 | 20 | assert uproot3.open("tests/samples/Zmumu-lzma.root").compression.algoname == "lzma" 21 | assert uproot3.open("tests/samples/Zmumu-lzma.root").compression.level == 4 22 | 23 | assert uproot3.open("tests/samples/Zmumu-lz4.root").compression.algoname == "lz4" 24 | assert uproot3.open("tests/samples/Zmumu-lz4.root").compression.level == 4 25 | 26 | assert uproot3.open("tests/samples/Zmumu-zstd.root").compression.algoname == "zstd" 27 | assert uproot3.open("tests/samples/Zmumu-zstd.root").compression.level == 5 28 | 29 | assert uproot3.open("tests/samples/Zmumu-uncompressed.root").compression.level == 0 30 | 31 | assert uproot3.open("tests/samples/HZZ-zlib.root").compression.algoname == "zlib" 32 | assert uproot3.open("tests/samples/HZZ-zlib.root").compression.level == 4 33 | 34 | assert uproot3.open("tests/samples/HZZ-lzma.root").compression.algoname == "lzma" 35 | assert uproot3.open("tests/samples/HZZ-lzma.root").compression.level == 4 36 | 37 | assert uproot3.open("tests/samples/HZZ-lz4.root").compression.algoname == "lz4" 38 | assert uproot3.open("tests/samples/HZZ-lz4.root").compression.level == 4 39 | 40 | assert uproot3.open("tests/samples/HZZ-zstd.root").compression.algoname == "zstd" 41 | assert uproot3.open("tests/samples/HZZ-zstd.root").compression.level == 5 42 | 43 | assert uproot3.open("tests/samples/HZZ-uncompressed.root").compression.level == 0 44 | 45 | def test_compression_keys(self): 46 | keys = [(n, cls._classname) for n, cls in uproot3.open("tests/samples/Zmumu-uncompressed.root").allclasses()] 47 | assert [(n, cls._classname) for n, cls in uproot3.open("tests/samples/Zmumu-zlib.root").allclasses()] == keys 48 | assert [(n, cls._classname) for n, cls in uproot3.open("tests/samples/Zmumu-lzma.root").allclasses()] == keys 49 | assert [(n, cls._classname) for n, cls in uproot3.open("tests/samples/Zmumu-lz4.root").allclasses()] == keys 50 | assert [(n, cls._classname) for n, cls in uproot3.open("tests/samples/Zmumu-zstd.root").allclasses()] == keys 51 | 52 | keys = [(n, cls._classname) for n, cls in uproot3.open("tests/samples/HZZ-uncompressed.root").allclasses()] 53 | assert [(n, cls._classname) for n, cls in uproot3.open("tests/samples/HZZ-zlib.root").allclasses()] == keys 54 | assert [(n, cls._classname) for n, cls in uproot3.open("tests/samples/HZZ-lzma.root").allclasses()] == keys 55 | assert [(n, cls._classname) for n, cls in uproot3.open("tests/samples/HZZ-lz4.root").allclasses()] == keys 56 | assert [(n, cls._classname) for n, cls in uproot3.open("tests/samples/HZZ-zstd.root").allclasses()] == keys 57 | 58 | def test_compression_branches(self): 59 | branches = list(uproot3.open("tests/samples/Zmumu-uncompressed.root")["events"].keys()) 60 | assert list(uproot3.open("tests/samples/Zmumu-zlib.root")["events"].keys()) == branches 61 | assert list(uproot3.open("tests/samples/Zmumu-lzma.root")["events"].keys()) == branches 62 | assert list(uproot3.open("tests/samples/Zmumu-lz4.root")["events"].keys()) == branches 63 | assert list(uproot3.open("tests/samples/Zmumu-zstd.root")["events"].keys()) == branches 64 | 65 | branches = list(uproot3.open("tests/samples/HZZ-uncompressed.root")["events"].keys()) 66 | assert list(uproot3.open("tests/samples/HZZ-zlib.root")["events"].keys()) == branches 67 | assert list(uproot3.open("tests/samples/HZZ-lzma.root")["events"].keys()) == branches 68 | assert list(uproot3.open("tests/samples/HZZ-lz4.root")["events"].keys()) == branches 69 | assert list(uproot3.open("tests/samples/HZZ-zstd.root")["events"].keys()) == branches 70 | 71 | def test_compression_content1(self): 72 | for name, array in uproot3.open("tests/samples/Zmumu-uncompressed.root")["events"].arrays(["Type", "Event", "E1", "px1", "Q1", "M"]).items(): 73 | array = array.tolist() 74 | assert uproot3.open("tests/samples/Zmumu-zlib.root")["events"].array(name).tolist() == array 75 | assert uproot3.open("tests/samples/Zmumu-lzma.root")["events"].array(name).tolist() == array 76 | assert uproot3.open("tests/samples/Zmumu-lz4.root")["events"].array(name).tolist() == array 77 | assert uproot3.open("tests/samples/Zmumu-zstd.root")["events"].array(name).tolist() == array 78 | 79 | def test_compression_content2(self): 80 | array = uproot3.open("tests/samples/HZZ-uncompressed.root")["events"].array("Electron_Px").tolist() 81 | assert uproot3.open("tests/samples/HZZ-zlib.root")["events"].array("Electron_Px").tolist() == array 82 | assert uproot3.open("tests/samples/HZZ-lzma.root")["events"].array("Electron_Px").tolist() == array 83 | assert uproot3.open("tests/samples/HZZ-lz4.root")["events"].array("Electron_Px").tolist() == array 84 | assert uproot3.open("tests/samples/HZZ-zstd.root")["events"].array("Electron_Px").tolist() == array 85 | -------------------------------------------------------------------------------- /tests/test_http.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | import pytest 6 | import mock 7 | HTTPError = pytest.importorskip('requests.exceptions').HTTPError 8 | 9 | import uproot3 10 | 11 | FILE = "foriter" 12 | LOCAL = "tests/samples/{FILE}.root".format(FILE=FILE) 13 | URL = "http://scikit-hep.org/uproot3/examples/{FILE}.root".format(FILE=FILE) 14 | URL_AUTH = "http://scikit-hep.org/uproot3/authentication/{FILE}.root".format(FILE=FILE) 15 | AUTH = ("scikit-hep", "uproot3") 16 | 17 | def mock_get_local_instead_of_http(url="", headers={}, auth=None, **kwargs): 18 | class MockResponse: 19 | def __init__(self, status_code): 20 | self.status_code = status_code 21 | if self.status_code == 200: 22 | with open(LOCAL, "rb") as f: 23 | self.content = f.read() 24 | self.headers = {"Content-Range": str(len(self.content))} 25 | 26 | def raise_for_status(self): 27 | if self.status_code == 401: # Authentication Error 28 | raise HTTPError 29 | elif self.status_code == 200: # Ok 30 | pass 31 | 32 | if url == URL: 33 | return MockResponse(200) 34 | elif url == URL_AUTH and auth == None: 35 | return MockResponse(401) 36 | elif url == URL_AUTH and auth == AUTH: 37 | return MockResponse(200) 38 | elif url == URL_AUTH: 39 | return MockResponse(401) 40 | 41 | @mock.patch("requests.get", mock_get_local_instead_of_http) 42 | class Test(object): 43 | def test_no_auth_needed_no_auth(self): 44 | f = uproot3.open(URL) 45 | assert type(f) == uproot3.rootio.ROOTDirectory 46 | 47 | def test_no_auth_needed_with_auth(self): 48 | f = uproot3.open(URL, httpsource={"auth": AUTH}) 49 | assert type(f) == uproot3.rootio.ROOTDirectory 50 | 51 | def test_auth_needed_no_auth(self): 52 | with pytest.raises(HTTPError): 53 | f = uproot3.open(URL_AUTH) 54 | 55 | def test_auth_needed_correct_auth(self): 56 | f = uproot3.open(URL_AUTH, httpsource={"auth": AUTH}) 57 | assert type(f) == uproot3.rootio.ROOTDirectory 58 | 59 | def test_auth_needed_wrong_auth(self): 60 | with pytest.raises(HTTPError): 61 | f = uproot3.open(URL_AUTH, httpsource={"auth": ("", "")}) 62 | -------------------------------------------------------------------------------- /tests/test_jagged.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | import pytest 6 | 7 | import uproot3 8 | 9 | 10 | class Test(object): 11 | @property 12 | def sample(self): 13 | pytest.importorskip("pandas") 14 | try: 15 | self._sample 16 | except AttributeError: 17 | self._sample = uproot3.open("tests/samples/sample-6.10.05-uncompressed.root")["sample"] 18 | return self._sample 19 | 20 | def test_flatten_False(self): 21 | df = self.sample.pandas.df(flatten=False) 22 | assert len(df.keys()) == 57 23 | assert "Af8" in df 24 | assert len(df.at[0, "Af8"]) == 0 25 | assert len(df.at[1, "Af8"]) == 1 26 | assert len(df.at[2, "Af8"]) == 2 27 | 28 | def test_flatten_None(self): 29 | df = self.sample.pandas.df(flatten=None) 30 | assert len(df.keys()) == 46 31 | assert "Af8" not in df 32 | 33 | def test_flatten_True(self): 34 | df = self.sample.pandas.df(flatten=True) 35 | assert len(df.keys()) == 57 36 | assert "Af8" in df 37 | -------------------------------------------------------------------------------- /tests/test_rntuple.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | import os 6 | 7 | import numpy 8 | import pytest 9 | 10 | import awkward0 11 | import uproot3 12 | 13 | class Test(object): 14 | def test_read_anchor(self): 15 | f = uproot3.open("tests/samples/ntpl001_staff.root") 16 | rntuple = f["Staff"] 17 | assert rntuple._fVersion == 0 18 | assert rntuple._fSize == 48 19 | assert rntuple._fSeekHeader == 854 20 | assert rntuple._fNBytesHeader == 537 21 | assert rntuple._fLenHeader == 2495 22 | assert rntuple._fSeekFooter == 72369 23 | assert rntuple._fNBytesFooter == 285 24 | assert rntuple._fLenFooter == 804 25 | assert rntuple._fReserved == 0 26 | -------------------------------------------------------------------------------- /uproot3/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | """Uproot -- ROOT I/O in pure Python and Numpy. 6 | 7 | Basic cheat-sheet 8 | ----------------- 9 | 10 | Open ROOT files with uproot3.open (for reading) or uproot3.create (for read-write). 11 | 12 | file = uproot3.open("/path/to/my/file.root") 13 | file = uproot3.open("root://path/to/my/file.root") 14 | file = uproot3.open("http://path/to/my/file.root") 15 | writeable = uproot3.create("/new/local/file.root") 16 | 17 | These file objects act like dicts; get objects like TTrees from them with square 18 | brackets. 19 | 20 | tree = file["path/to/events"] 21 | tree = file["path/to/events;2"] # optional cycle number 22 | # write to files by assignment (histograms only) 23 | writeable["name"] = numpy.histogram(...) 24 | 25 | TTree objects also act like dicts; get branches with square brackets or list them 26 | with keys(). 27 | 28 | tree.keys() 29 | tree.allkeys() # recursive branches-of-branches 30 | tree.show() # display view 31 | tree["mybranch"] # searches recursively 32 | 33 | Get data as arrays with an array(...) or arrays(...) call. 34 | 35 | tree["mybranch"].array() 36 | tree.array("mybranch") 37 | tree.arrays(["branch1", "branch2", "branch3"]) 38 | tree.arrays(["Muon_*"]) 39 | 40 | Variable numbers of objects per entry (particles per event) are handled by 41 | Awkward Array: 42 | 43 | https://github.com/scikit-hep/awkward-0.x 44 | 45 | The arrays(...) call returns a dict from branch name (bytes) to data 46 | (Numpy array) by default. 47 | Change this by passing an outputtype class (e.g. dict, tuple, pandas.DataFrame). 48 | 49 | x, y, z = tree.arrays(["x", "y", "z"], outputtype=tuple) 50 | 51 | For more idiomatic Pandas defaults, use tree.pandas.df(). 52 | 53 | df = tree.pandas.df() 54 | 55 | If the desired branches do not fit into memory, iterate over chunks of entries 56 | with iterate(). The interface is the same as above: you get the same 57 | dict/tuple/DataFrame with fewer entries. 58 | 59 | for x, y, z in tree.iterate(["x", "y", "z"], outputtype=tuple): 60 | do_something(x, y, z) 61 | 62 | To iterate over many files (like TChain), do uproot3.iterate(...). 63 | 64 | for arrays in uproot3.iterate("files*.root", "path/to/events", ["Muon_*"]): 65 | do_something(arrays) 66 | 67 | Intermediate cheat-sheet 68 | ------------------------ 69 | 70 | Each call to array/arrays/iterate reads the file again. For faster access after 71 | the first time, pass a dict-like object to the cache parameter and Uproot will 72 | try the cache first. 73 | 74 | cache = {} 75 | arrays = tree.arrays(["Muon_*"], cache=cache) # slow 76 | arrays = tree.arrays(["Muon_*"], cache=cache) # fast 77 | 78 | You control the cache object. If you're running out of memory, remove it or 79 | remove items from it. Or use one of the dict-like caches from cachetools (already 80 | installed) or another library. 81 | 82 | For parallel processing, pass a Python 3 executor. 83 | 84 | import concurrent.futures 85 | executor = concurrent.futures.ThreadPoolExecutor(32) 86 | arrays = tree.arrays(["Muon_*"], executor=executor) 87 | 88 | To get the number of entries per file in a a collection of files, use 89 | uproot3.numentries(). 90 | 91 | uproot3.numentries("tests/samples/sample*.root", "sample", total=False) 92 | 93 | For arrays that read on demand, use uproot3.lazyarray and uproot3.lazyarrays. 94 | For processing with Dask, use uproot3.daskarray, uproot3.daskarrays, or 95 | uproot3.daskframe. 96 | 97 | Advanced cheat-sheet 98 | -------------------- 99 | 100 | The standard bytes-to-arrays decoding is attached to each branch as 101 | 102 | tree["mybranch"].interpretation 103 | 104 | This can be overridden by passing a new interpretation to array/arrays/iterate. 105 | Most reinterpretations will produce wrong values (it's a reinterpret_cast<...>). 106 | 107 | Some, however, are useful: 108 | 109 | mybranch = tree["mybranch"] 110 | fill_me_instead = numpy.empty(big_enough) 111 | mybranch.array(mybranch.interpretation.toarray(fill_me_instead)) 112 | fill_me_instead # filled in place 113 | 114 | mybranch.array(uproot3.asdebug) # view raw bytes of each entry 115 | 116 | By default, local files are read as memory-mapped arrays. Change this by setting 117 | 118 | from uproot3 import FileSource 119 | open("...", localsource=lambda path: FileSource(path, **FileSource.defaults)) 120 | 121 | The same procedure sets options for uproot3.XRootDSource and uproot3.HTTPSource. 122 | """ 123 | 124 | from __future__ import absolute_import 125 | 126 | # high-level entry points 127 | from uproot3.rootio import open, xrootd, http 128 | from uproot3.tree import iterate, numentries, lazyarray, lazyarrays, daskarray, daskframe 129 | from uproot3.write.TFile import TFileCreate as create 130 | from uproot3.write.TFile import TFileRecreate as recreate 131 | from uproot3.write.TFile import TFileUpdate as update 132 | from uproot3.write.compress import ZLIB, LZMA, LZ4 133 | from uproot3.write.objects.TTree import newtree, newbranch 134 | 135 | from uproot3.source.memmap import MemmapSource 136 | from uproot3.source.file import FileSource 137 | from uproot3.source.xrootd import XRootDSource 138 | from uproot3.source.http import HTTPSource 139 | 140 | from uproot3.cache import ArrayCache, ThreadSafeArrayCache 141 | 142 | from uproot3.interp.auto import interpret 143 | from uproot3.interp.numerical import asdtype 144 | from uproot3.interp.numerical import asarray 145 | from uproot3.interp.numerical import asdouble32 146 | from uproot3.interp.numerical import asstlbitset 147 | from uproot3.interp.jagged import asjagged 148 | from uproot3.interp.objects import astable 149 | from uproot3.interp.objects import asobj 150 | from uproot3.interp.objects import asgenobj 151 | from uproot3.interp.objects import asstring 152 | from uproot3.interp.objects import SimpleArray 153 | from uproot3.interp.objects import STLVector 154 | from uproot3.interp.objects import STLMap 155 | from uproot3.interp.objects import STLString 156 | from uproot3.interp.objects import Pointer 157 | asdebug = asjagged(asdtype("u1")) 158 | 159 | from uproot3 import pandas 160 | 161 | # put help strings on everything (they're long, too disruptive to intersperse 162 | # in the code, and are built programmatically to avoid duplication; Python's 163 | # inline docstring method doesn't accept non-literals) 164 | import uproot3._help 165 | 166 | # convenient access to the version number 167 | from uproot3.version import __version__ 168 | 169 | # don't expose uproot3.uproot3; it's ugly 170 | del uproot3 171 | 172 | __all__ = ["open", "xrootd", "http", "iterate", "numentries", "lazyarray", "lazyarrays", "daskarray", "daskframe", "create", "recreate", "update", "ZLIB", "LZMA", "LZ4", "ZSTD", "newtree", "newbranch", "MemmapSource", "FileSource", "XRootDSource", "HTTPSource", "ArrayCache", "ThreadSafeArrayCache", "interpret", "asdtype", "asarray", "asdouble32", "asstlbitset", "asjagged", "astable", "asobj", "asgenobj", "asstring", "asdebug", "SimpleArray", "STLVector", "STLMap", "STLString", "Pointer", "pandas", "__version__"] 173 | -------------------------------------------------------------------------------- /uproot3/_connect/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | -------------------------------------------------------------------------------- /uproot3/_util.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | def _tobytes(x): 8 | if hasattr(x, "tobytes"): 9 | return x.tobytes() 10 | else: 11 | return x.tostring() 12 | -------------------------------------------------------------------------------- /uproot3/cache.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import math 8 | import threading 9 | try: 10 | from collections.abc import MutableMapping 11 | except ImportError: 12 | from collections import MutableMapping 13 | 14 | import cachetools 15 | 16 | class ArrayCache(MutableMapping): 17 | @staticmethod 18 | def getsizeof(obj): 19 | return getattr(obj, "nbytes", 1) 20 | 21 | def __init__(self, limitbytes, method="LRU"): 22 | from uproot3.rootio import _memsize 23 | m = _memsize(limitbytes) 24 | if m is not None: 25 | limitbytes = int(math.ceil(m)) 26 | if method == "LRU": 27 | self._cache = cachetools.LRUCache(limitbytes, getsizeof=self.getsizeof) 28 | elif method == "LFU": 29 | self._cache = cachetools.LFUCache(limitbytes, getsizeof=self.getsizeof) 30 | else: 31 | raise ValueError("unrecognized method: {0}".format(method)) 32 | 33 | def __contains__(self, where): 34 | return where in self._cache 35 | 36 | def __getitem__(self, where): 37 | return self._cache[where] 38 | 39 | def __setitem__(self, where, what): 40 | self._cache[where] = what 41 | 42 | def __delitem__(self, where): 43 | del self._cache[where] 44 | 45 | def __iter__(self): 46 | for x in self._cache: 47 | yield x 48 | 49 | def __len__(self): 50 | return len(self._cache) 51 | 52 | class ThreadSafeArrayCache(ArrayCache): 53 | def __init__(self, limitbytes, method="LRU"): 54 | super(ThreadSafeArrayCache, self).__init__(limitbytes, method=method) 55 | self._lock = threading.Lock() 56 | 57 | def __contains__(self, where): 58 | with self._lock: 59 | return where in self._cache 60 | 61 | def __getitem__(self, where): 62 | with self._lock: 63 | return self._cache[where] 64 | 65 | def __setitem__(self, where, what): 66 | with self._lock: 67 | self._cache[where] = what 68 | 69 | def __delitem__(self, where): 70 | with self._lock: 71 | del self._cache[where] 72 | 73 | def __iter__(self): 74 | with self._lock: 75 | for x in self._cache: 76 | yield x 77 | 78 | def __len__(self): 79 | with self._lock: 80 | return len(self._cache) 81 | -------------------------------------------------------------------------------- /uproot3/const.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | """ROOT constants used in deserialization.""" 6 | from __future__ import absolute_import 7 | 8 | import numpy 9 | 10 | # used in unmarshaling 11 | kByteCountMask = numpy.int64(0x40000000) 12 | kByteCountVMask = numpy.int64(0x4000) 13 | kClassMask = numpy.int64(0x80000000) 14 | kNewClassTag = numpy.int64(0xFFFFFFFF) 15 | 16 | kIsOnHeap = numpy.uint32(0x01000000) 17 | kIsReferenced = numpy.uint32(1 << 4) 18 | 19 | kMapOffset = 2 20 | 21 | # not used? 22 | kNullTag = 0 23 | kNotDeleted = numpy.uint32(0x02000000) 24 | kZombie = numpy.uint32(0x04000000) 25 | kBitMask = numpy.uint32(0x00FFFFFF) 26 | kDisplacementMask = numpy.uint32(0xFF000000) 27 | 28 | ################################################################ core/zip/inc/Compression.h 29 | 30 | kZLIB = 1 31 | kLZMA = 2 32 | kOldCompressionAlgo = 3 33 | kLZ4 = 4 34 | kZSTD = 5 35 | kUndefinedCompressionAlgorithm = 6 36 | 37 | ################################################################ constants for streamers 38 | 39 | kBase = 0 40 | kChar = 1 41 | kShort = 2 42 | kInt = 3 43 | kLong = 4 44 | kFloat = 5 45 | kCounter = 6 46 | kCharStar = 7 47 | kDouble = 8 48 | kDouble32 = 9 49 | kLegacyChar = 10 50 | kUChar = 11 51 | kUShort = 12 52 | kUInt = 13 53 | kULong = 14 54 | kBits = 15 55 | kLong64 = 16 56 | kULong64 = 17 57 | kBool = 18 58 | kFloat16 = 19 59 | kOffsetL = 20 60 | kOffsetP = 40 61 | kObject = 61 62 | kAny = 62 63 | kObjectp = 63 64 | kObjectP = 64 65 | kTString = 65 66 | kTObject = 66 67 | kTNamed = 67 68 | kAnyp = 68 69 | kAnyP = 69 70 | kAnyPnoVT = 70 71 | kSTLp = 71 72 | 73 | kSkip = 100 74 | kSkipL = 120 75 | kSkipP = 140 76 | 77 | kConv = 200 78 | kConvL = 220 79 | kConvP = 240 80 | 81 | kSTL = 300 82 | kSTLstring = 365 83 | 84 | kStreamer = 500 85 | kStreamLoop = 501 86 | 87 | ################################################################ constants from core/foundation/inc/ESTLType.h 88 | 89 | kNotSTL = 0 90 | kSTLvector = 1 91 | kSTLlist = 2 92 | kSTLdeque = 3 93 | kSTLmap = 4 94 | kSTLmultimap = 5 95 | kSTLset = 6 96 | kSTLmultiset = 7 97 | kSTLbitset = 8 98 | kSTLforwardlist = 9 99 | kSTLunorderedset = 10 100 | kSTLunorderedmultiset = 11 101 | kSTLunorderedmap = 12 102 | kSTLunorderedmultimap = 13 103 | kSTLend = 14 104 | kSTLany = 300 105 | 106 | ################################################################ IOFeatures 107 | 108 | kGenerateOffsetMap = 1 109 | -------------------------------------------------------------------------------- /uproot3/interp/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | -------------------------------------------------------------------------------- /uproot3/interp/interp.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import awkward0 8 | 9 | class Interpretation(object): 10 | # makes __doc__ attribute mutable before Python 3.3 11 | __metaclass__ = type.__new__(type, "type", (type,), {}) 12 | 13 | awkward = awkward0 14 | awkward0 = awkward0 15 | 16 | debug_reading = False 17 | 18 | def awkwardlib(self, lib): 19 | cls = type(self) 20 | out = cls.__new__(cls) 21 | out.__dict__.update(self.__dict__) 22 | out.awkward0 = lib 23 | return out 24 | 25 | @property 26 | def identifier(self): 27 | raise NotImplementedError 28 | 29 | @property 30 | def type(self): 31 | raise NotImplementedError # awkward0.type.Type 32 | 33 | def empty(self): 34 | raise NotImplementedError 35 | 36 | def compatible(self, other): 37 | raise NotImplementedError 38 | 39 | def numitems(self, numbytes, numentries): 40 | raise NotImplementedError 41 | 42 | def source_numitems(self, source): 43 | raise NotImplementedError 44 | 45 | def fromroot(self, data, byteoffsets, local_entrystart, local_entrystop, keylen): 46 | raise NotImplementedError 47 | 48 | def destination(self, numitems, numentries): 49 | raise NotImplementedError 50 | 51 | def fill(self, source, destination, itemstart, itemstop, entrystart, entrystop): 52 | raise NotImplementedError 53 | 54 | def clip(self, destination, itemstart, itemstop, entrystart, entrystop): 55 | raise NotImplementedError 56 | 57 | def finalize(self, destination, branch): 58 | raise NotImplementedError 59 | -------------------------------------------------------------------------------- /uproot3/interp/jagged.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import math 8 | 9 | import uproot3.interp.interp 10 | import uproot3.interp.numerical 11 | 12 | class _JaggedArrayPrep(object): 13 | def __init__(self, counts, content): 14 | self.counts = counts 15 | self.content = content 16 | 17 | def _destructive_divide(array, divisor, awkward0): 18 | if divisor == 1: 19 | pass 20 | elif divisor == 2: 21 | awkward0.numpy.right_shift(array, 1, out=array) 22 | elif divisor == 4: 23 | awkward0.numpy.right_shift(array, 2, out=array) 24 | elif divisor == 8: 25 | awkward0.numpy.right_shift(array, 3, out=array) 26 | else: 27 | awkward0.numpy.floor_divide(array, divisor, out=array) 28 | return array 29 | 30 | class asjagged(uproot3.interp.interp.Interpretation): 31 | # makes __doc__ attribute mutable before Python 3.3 32 | __metaclass__ = type.__new__(type, "type", (uproot3.interp.interp.Interpretation.__metaclass__,), {}) 33 | 34 | def __init__(self, content, skipbytes=0): 35 | self.content = content 36 | self.skipbytes = skipbytes 37 | 38 | def __repr__(self): 39 | return "asjagged({0}{1})".format(repr(self.content), "" if self.skipbytes == 0 else ", {0}".format(self.skipbytes)) 40 | 41 | def to(self, todtype=None, todims=None, skipbytes=None): 42 | if skipbytes is None: 43 | skipbytes = self.skipbytes 44 | return asjagged(self.content.to(todtype, todims), skipbytes) 45 | 46 | @property 47 | def identifier(self): 48 | return "asjagged({0}{1})".format(self.content.identifier, "" if self.skipbytes == 0 else ",{0}".format(self.skipbytes)) 49 | 50 | @property 51 | def type(self): 52 | return self.awkward0.type.ArrayType(self.awkward0.numpy.inf, self.content.type) 53 | 54 | def empty(self): 55 | return self.awkward0.JaggedArray(self.awkward0.numpy.empty(0, dtype=self.awkward0.JaggedArray.INDEXTYPE), self.awkward0.numpy.empty(0, dtype=self.awkward0.JaggedArray.INDEXTYPE), self.content.empty()) 56 | 57 | def compatible(self, other): 58 | return isinstance(other, asjagged) and self.content.compatible(other.content) 59 | 60 | def numitems(self, numbytes, numentries): 61 | return self.content.numitems(numbytes - numentries * self.skipbytes, numentries) 62 | 63 | def source_numitems(self, source): 64 | return self.content.source_numitems(source.content) 65 | 66 | def fromroot(self, data, byteoffsets, local_entrystart, local_entrystop, keylen): 67 | if local_entrystart == local_entrystop: 68 | return self.awkward0.JaggedArray.fromoffsets([0], self.content.fromroot(data, None, local_entrystart, local_entrystop, keylen)) 69 | else: 70 | if self.skipbytes == 0: 71 | offsets = _destructive_divide(byteoffsets, self.content.itemsize, self.awkward0) 72 | starts = offsets[local_entrystart : local_entrystop ] 73 | stops = offsets[local_entrystart + 1 : local_entrystop + 1] 74 | content = self.content.fromroot(data, None, starts[0], stops[-1], keylen) 75 | return self.awkward0.JaggedArray(starts, stops, content) 76 | 77 | else: 78 | bytestarts = byteoffsets[local_entrystart : local_entrystop ] + self.skipbytes 79 | bytestops = byteoffsets[local_entrystart + 1 : local_entrystop + 1] 80 | 81 | mask = self.awkward0.numpy.zeros(len(data), dtype=self.awkward0.numpy.int8) 82 | mask[bytestarts[bytestarts < len(data)]] = 1 83 | self.awkward0.numpy.add.at(mask, bytestops[bytestops < len(data)], -1) 84 | self.awkward0.numpy.cumsum(mask, out=mask) 85 | data = data[mask.view(self.awkward0.numpy.bool_)] 86 | 87 | content = self.content.fromroot(data, None, 0, bytestops[-1], keylen) 88 | 89 | itemsize = 1 90 | sub = self.content 91 | while hasattr(sub, "content"): 92 | sub = sub.content 93 | if isinstance(sub, uproot3.interp.numerical.asdtype): 94 | itemsize = sub.fromdtype.itemsize 95 | if isinstance(sub, uproot3.interp.numerical.asstlbitset): 96 | itemsize = sub.numbytes + 4 97 | 98 | counts = bytestops - bytestarts 99 | shift = math.log(itemsize, 2) 100 | if shift == round(shift): 101 | self.awkward0.numpy.right_shift(counts, int(shift), out=counts) 102 | else: 103 | self.awkward0.numpy.floor_divide(counts, itemsize, out=counts) 104 | 105 | offsets = self.awkward0.numpy.empty(len(counts) + 1, self.awkward0.JaggedArray.INDEXTYPE) 106 | offsets[0] = 0 107 | self.awkward0.numpy.cumsum(counts, out=offsets[1:]) 108 | 109 | return self.awkward0.JaggedArray(offsets[:-1], offsets[1:], content) 110 | 111 | def destination(self, numitems, numentries): 112 | content = self.content.destination(numitems, numentries) 113 | counts = self.awkward0.numpy.empty(numentries, dtype=self.awkward0.JaggedArray.INDEXTYPE) 114 | return _JaggedArrayPrep(counts, content) 115 | 116 | def fill(self, source, destination, itemstart, itemstop, entrystart, entrystop): 117 | self.content.fill(source.content, destination.content, itemstart, itemstop, entrystart, entrystop) 118 | destination.counts[entrystart:entrystop] = source.stops - source.starts 119 | 120 | def clip(self, destination, itemstart, itemstop, entrystart, entrystop): 121 | destination.content = self.content.clip(destination.content, itemstart, itemstop, entrystart, entrystop) 122 | destination.counts = destination.counts[entrystart:entrystop] 123 | return destination 124 | 125 | def finalize(self, destination, branch): 126 | content = self.content.finalize(destination.content, branch) 127 | leafcount = None 128 | if len(branch._fLeaves) == 1: 129 | leafcount = branch._fLeaves[0]._fLeafCount 130 | 131 | out = self.awkward0.Methods.maybemixin(type(content), self.awkward0.JaggedArray).fromcounts(destination.counts, content) 132 | out.leafcount = leafcount 133 | if self.debug_reading: 134 | print("reading {0}".format(repr(out))) 135 | return out 136 | -------------------------------------------------------------------------------- /uproot3/pandas.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | """Top-level functions for Pandas.""" 6 | from __future__ import absolute_import 7 | 8 | import uproot3.tree 9 | from uproot3.source.memmap import MemmapSource 10 | from uproot3.source.xrootd import XRootDSource 11 | from uproot3.source.http import HTTPSource 12 | 13 | def iterate(path, treepath, branches=None, entrysteps=None, namedecode="utf-8", reportpath=False, reportfile=False, flatten=True, flatname=None, awkwardlib=None, cache=None, basketcache=None, keycache=None, executor=None, blocking=True, localsource=MemmapSource.defaults, xrootdsource=XRootDSource.defaults, httpsource=HTTPSource.defaults, **options): 14 | import pandas 15 | return uproot3.tree.iterate(path, treepath, branches=branches, entrysteps=entrysteps, outputtype=pandas.DataFrame, namedecode=namedecode, reportpath=reportpath, reportfile=reportfile, reportentries=False, flatten=flatten, flatname=flatname, awkwardlib=awkwardlib, cache=cache, basketcache=basketcache, keycache=keycache, executor=executor, blocking=blocking, localsource=localsource, xrootdsource=xrootdsource, httpsource=httpsource, **options) 16 | -------------------------------------------------------------------------------- /uproot3/source/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | -------------------------------------------------------------------------------- /uproot3/source/chunked.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import math 8 | 9 | import numpy 10 | 11 | import uproot3.cache 12 | import uproot3.source.source 13 | 14 | 15 | class ChunkedSource(uproot3.source.source.Source): 16 | # makes __doc__ attribute mutable before Python 3.3 17 | __metaclass__ = type.__new__(type, "type", (uproot3.source.source.Source.__metaclass__,), {}) 18 | 19 | def __init__(self, path, chunkbytes, limitbytes, parallel): 20 | from uproot3.rootio import _memsize 21 | m = _memsize(chunkbytes) 22 | if m is not None: 23 | chunkbytes = int(math.ceil(m)) 24 | m = _memsize(limitbytes) 25 | if m is not None: 26 | limitbytes = int(math.ceil(m)) 27 | self.path = path 28 | self._chunkbytes = chunkbytes 29 | self._limitbytes = limitbytes 30 | if limitbytes is None: 31 | self.cache = {} 32 | else: 33 | self.cache = uproot3.cache.ThreadSafeArrayCache(limitbytes) 34 | self._source = None 35 | self._setup_futures(parallel) 36 | 37 | def parent(self): 38 | return self 39 | 40 | def threadlocal(self): 41 | return self 42 | 43 | def __del__(self): 44 | self.dismiss() 45 | 46 | def _read(self, chunkindex): 47 | raise NotImplementedError 48 | 49 | def close(self): 50 | super(ChunkedSource, self).close() 51 | self.cache.clear() 52 | 53 | def dismiss(self): 54 | if self._futures is not None: 55 | for future in self._futures.values(): 56 | future.cancel() 57 | self._futures = {} 58 | 59 | def _setup_futures(self, parallel): 60 | if parallel is not None and parallel > 1: 61 | try: 62 | import concurrent.futures 63 | except ImportError: 64 | raise ImportError("Install futures package (for parallel > 1) with:\n pip install futures\nor\n conda install -c conda-forge futures") 65 | self._executor = concurrent.futures.ThreadPoolExecutor(parallel) 66 | self._futures = {} 67 | else: 68 | self._executor = None 69 | self._futures = None 70 | 71 | def _preload(self, chunkindex): 72 | try: 73 | chunk = self.cache[chunkindex] 74 | except KeyError: 75 | return self._read(chunkindex) 76 | else: 77 | return chunk 78 | 79 | def preload(self, starts): 80 | self._open() 81 | limitnum = self._limitbytes // self._chunkbytes 82 | if self._executor is not None: 83 | for start in starts: 84 | if len(self._futures) > limitnum: 85 | break 86 | chunkindex = start // self._chunkbytes 87 | if chunkindex not in self._futures: 88 | self._futures[chunkindex] = self._executor.submit(self._preload, chunkindex) 89 | 90 | def data(self, start, stop, dtype=None): 91 | if dtype is None: 92 | thedtype = numpy.dtype(numpy.uint8) 93 | else: 94 | thedtype = dtype 95 | 96 | # assert start >= 0 97 | # assert stop >= 0 98 | # assert stop >= start 99 | 100 | chunkstart = start // self._chunkbytes 101 | if stop % self._chunkbytes == 0: 102 | chunkstop = stop // self._chunkbytes 103 | else: 104 | chunkstop = stop // self._chunkbytes + 1 105 | 106 | out = numpy.empty((stop - start) // thedtype.itemsize, dtype=thedtype) 107 | 108 | for chunkindex in range(chunkstart, chunkstop): 109 | chunk = None 110 | if self._futures is not None: 111 | future = self._futures.pop(chunkindex, None) 112 | if future is not None: 113 | chunk = future.result() 114 | 115 | if chunk is None: 116 | try: 117 | chunk = self.cache[chunkindex] 118 | except KeyError: 119 | self._open() 120 | chunk = self._read(chunkindex) 121 | 122 | cstart = 0 123 | cstop = self._chunkbytes 124 | gstart = chunkindex * self._chunkbytes 125 | gstop = (chunkindex + 1) * self._chunkbytes 126 | 127 | if len(chunk) > self._chunkbytes: 128 | if not numpy.array_equal(chunk[:4], list(b"root")): 129 | raise NotImplementedError("Expected {0} or fewer bytes but received {1} and data does not appear to be an entire ROOT file.".format(self._chunkbytes, len(chunk))) 130 | self.cache = {} 131 | for i in range(0, len(chunk), self._chunkbytes): 132 | self.cache[i // self._chunkbytes] = chunk[i:i+self._chunkbytes] 133 | chunk = self.cache[chunkindex] 134 | # Dismiss any pending futures as everything has already been loaded 135 | self.dismiss() 136 | else: 137 | self.cache[chunkindex] = chunk 138 | 139 | if gstart < start: 140 | cstart += start - gstart 141 | gstart += start - gstart 142 | if gstop > stop: 143 | cstop -= gstop - stop 144 | gstop -= gstop - stop 145 | 146 | if cstop - cstart > len(chunk): 147 | raise IndexError("indexes {0}:{1} are beyond the end of data source {2}".format(gstart + len(chunk), stop, repr(self.path))) 148 | 149 | if dtype is None: 150 | out[gstart - start : gstop - start] = chunk[cstart:cstop] 151 | else: 152 | out.view(numpy.uint8)[gstart - start : gstop - start] = chunk[cstart:cstop] 153 | 154 | return out 155 | -------------------------------------------------------------------------------- /uproot3/source/cursor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import struct 8 | import string 9 | 10 | import numpy 11 | 12 | from uproot3._util import _tobytes 13 | 14 | class Cursor(object): 15 | # makes __doc__ attribute mutable before Python 3.3 16 | __metaclass__ = type.__new__(type, "type", (type,), {}) 17 | 18 | def __init__(self, index, origin=0, refs=None): 19 | self.index = index 20 | self.origin = origin 21 | if refs is None: 22 | self.refs = {} 23 | else: 24 | self.refs = refs 25 | 26 | def copied(self, index=None, origin=None, refs=None): 27 | if index is None: 28 | index = self.index 29 | if origin is None: 30 | origin = self.origin 31 | if refs is None: 32 | refs = self.refs 33 | return Cursor(index, origin, refs) 34 | 35 | def skipped(self, numbytes, origin=None, refs=None): 36 | if origin is None: 37 | origin = self.origin 38 | if refs is None: 39 | refs = self.refs 40 | return Cursor(self.index + numbytes, origin, refs) 41 | 42 | def skip(self, numbytes): 43 | self.index += numbytes 44 | 45 | def fields(self, source, format): 46 | start = self.index 47 | stop = self.index = start + format.size 48 | return format.unpack(source.data(start, stop)) 49 | 50 | def field(self, source, format): 51 | return self.fields(source, format)[0] 52 | 53 | def bytes(self, source, length): 54 | start = self.index 55 | stop = self.index = start + length 56 | return source.data(start, stop) 57 | 58 | def array(self, source, length, dtype): 59 | if not isinstance(dtype, numpy.dtype): 60 | dtype = numpy.dtype(dtype) 61 | start = self.index 62 | stop = self.index = start + length*dtype.itemsize 63 | return source.data(start, stop, dtype) 64 | 65 | def string(self, source): 66 | start = self.index 67 | stop = self.index = start + 1 68 | length = source.data(start, stop)[0] 69 | if length == 255: 70 | start = self.index 71 | stop = self.index = start + 4 72 | length = source.data(start, stop, numpy.dtype(">u4"))[0] 73 | start = self.index 74 | stop = self.index = start + length 75 | return _tobytes(source.data(start, stop)) 76 | 77 | def cstring(self, source): 78 | char = None 79 | chars = [] 80 | while char != 0: 81 | char = source.data(self.index, self.index + 1) 82 | if char != 0: 83 | chars.append(chr(char[0]).encode("ascii")) 84 | self.index += 1 85 | return b"".join(chars) 86 | 87 | def skipstring(self, source): 88 | length = source.data(self.index, self.index + 1)[0] 89 | self.index += 1 90 | if length == 255: 91 | length = source.data(self.index, self.index + 4, numpy.dtype(">u4"))[0] 92 | self.index += 4 93 | self.index += length 94 | 95 | def hexdump(self, source, size=160, offset=0, format="%02x"): 96 | pos = self.index + offset 97 | out = [] 98 | for linepos in range(pos, pos + size, 16): 99 | data = source.data(linepos, min(linepos + 16, pos + size)) 100 | line = [format % x for x in data] 101 | text = [chr(x) if chr(x) in string.printable[:-5] else "." for x in data] 102 | if len(line) < 16: 103 | diff = 16 - len(line) 104 | line.extend([" "] * diff) 105 | text.extend([" "] * diff) 106 | out.append("{0:08o} {1} {2} |{3}|".format(linepos, " ".join(line[:8]), " ".join(line[8:]), "".join(text))) 107 | return "\n".join(out) 108 | -------------------------------------------------------------------------------- /uproot3/source/file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import multiprocessing 8 | import os.path 9 | import sys 10 | 11 | import numpy 12 | 13 | import uproot3.source.chunked 14 | 15 | class FileSource(uproot3.source.chunked.ChunkedSource): 16 | # makes __doc__ attribute mutable before Python 3.3 17 | __metaclass__ = type.__new__(type, "type", (uproot3.source.chunked.ChunkedSource.__metaclass__,), {}) 18 | 19 | defaults = {"chunkbytes": 8*1024, "limitbytes": 1024**2, "parallel": 8*multiprocessing.cpu_count() if sys.version_info[0] > 2 else 1} 20 | 21 | def __init__(self, path, *args, **kwds): 22 | self._size = None 23 | self._parallel = kwds['parallel'] 24 | super(FileSource, self).__init__(os.path.expanduser(path), *args, **kwds) 25 | 26 | def size(self): 27 | if self._size is None: 28 | self._size = os.path.getsize(self.path) 29 | return self._size 30 | 31 | def threadlocal(self): 32 | out = FileSource.__new__(self.__class__) 33 | out.path = self.path 34 | out._chunkbytes = self._chunkbytes 35 | out.cache = self.cache 36 | out._source = None # local file connections are *not shared* among threads (they're *not* thread-safe) 37 | out._setup_futures(self._parallel) 38 | return out 39 | 40 | def _open(self): 41 | if self._source is None or self._source.closed: 42 | self._source = open(self.path, "rb") 43 | 44 | def _read(self, chunkindex): 45 | self._source.seek(chunkindex * self._chunkbytes) 46 | return numpy.frombuffer(self._source.read(self._chunkbytes), dtype=numpy.uint8) 47 | 48 | def dismiss(self): 49 | if self._source is not None: 50 | self._source.close() # local file connections are *not shared* among threads 51 | -------------------------------------------------------------------------------- /uproot3/source/http.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import os.path 8 | import re 9 | import multiprocessing 10 | import sys 11 | 12 | import numpy 13 | 14 | import uproot3.source.chunked 15 | 16 | class HTTPSource(uproot3.source.chunked.ChunkedSource): 17 | # makes __doc__ attribute mutable before Python 3.3 18 | __metaclass__ = type.__new__(type, "type", (uproot3.source.chunked.ChunkedSource.__metaclass__,), {}) 19 | 20 | def __init__(self, path, auth=None, *args, **kwds): 21 | super(HTTPSource, self).__init__(path, *args, **kwds) 22 | self._size = None 23 | self.auth = auth 24 | 25 | defaults = {"chunkbytes": 1024**2, "limitbytes": 100*1024**2, "parallel": 8*multiprocessing.cpu_count() if sys.version_info[0] > 2 else 1} 26 | 27 | def _open(self): 28 | try: 29 | import requests 30 | except ImportError: 31 | raise ImportError("Install requests package (for HTTP) with:\n pip install requests\nor\n conda install -c anaconda requests") 32 | 33 | def size(self): 34 | return self._size 35 | 36 | _contentrange = re.compile("^bytes ([0-9]+)-([0-9]+)/([0-9]+)$") 37 | 38 | def _read(self, chunkindex): 39 | import requests 40 | while True: 41 | response = requests.get( 42 | self.path, 43 | headers={"Range": "bytes={0}-{1}".format(chunkindex * self._chunkbytes, (chunkindex + 1) * self._chunkbytes - 1)}, 44 | auth=self.auth, 45 | ) 46 | if response.status_code == 504: # timeout, try it again 47 | pass 48 | else: 49 | response.raise_for_status() # if it's an error, raise exception 50 | break # otherwise, break out of the loop 51 | data = response.content 52 | 53 | if self._size is None: 54 | m = self._contentrange.match(response.headers.get("Content-Range", "")) 55 | if m is not None: 56 | start_inclusive, stop_inclusive, size = int(m.group(1)), int(m.group(2)), int(m.group(3)) 57 | if size > (stop_inclusive - start_inclusive) + 1: 58 | self._size = size 59 | return numpy.frombuffer(data, dtype=numpy.uint8) 60 | -------------------------------------------------------------------------------- /uproot3/source/memmap.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import os.path 8 | 9 | import numpy 10 | 11 | import uproot3.source.source 12 | 13 | class MemmapSource(uproot3.source.source.Source): 14 | # makes __doc__ attribute mutable before Python 3.3 15 | __metaclass__ = type.__new__(type, "type", (uproot3.source.source.Source.__metaclass__,), {}) 16 | 17 | defaults = {} 18 | 19 | def __init__(self, path): 20 | self.path = os.path.expanduser(path) 21 | self._source = numpy.memmap(self.path, dtype=numpy.uint8, mode="r") 22 | self.closed = False 23 | 24 | @property 25 | def source(self): 26 | if self.closed: 27 | raise IOError("The file handler has already been closed.") 28 | return self._source 29 | 30 | def parent(self): 31 | return self 32 | 33 | def size(self): 34 | return len(self.source) 35 | 36 | def threadlocal(self): 37 | return self 38 | 39 | def dismiss(self): 40 | pass 41 | 42 | def close(self): 43 | self.source._mmap.close() 44 | self.closed = True 45 | 46 | def data(self, start, stop, dtype=None): 47 | # assert start >= 0 48 | # assert stop >= 0 49 | # assert stop >= start 50 | 51 | if stop > len(self.source): 52 | raise IndexError("indexes {0}:{1} are beyond the end of data source {2}".format(len(self.source), stop, repr(self.path))) 53 | 54 | if dtype is None: 55 | return self.source[start:stop] 56 | else: 57 | return self.source[start:stop].view(dtype) 58 | -------------------------------------------------------------------------------- /uproot3/source/source.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import numpy 8 | 9 | class Source(object): 10 | # makes __doc__ attribute mutable before Python 3.3 11 | __metaclass__ = type.__new__(type, "type", (type,), {}) 12 | 13 | def __init__(self, data): 14 | assert len(data.shape) == 1 and data.dtype == numpy.uint8 15 | self._source = data 16 | 17 | def parent(self): 18 | return self 19 | 20 | def size(self): 21 | return len(self._source) 22 | 23 | def threadlocal(self): 24 | return self 25 | 26 | def dismiss(self): 27 | pass 28 | 29 | def close(self): 30 | self.dismiss() 31 | 32 | def preload(self, starts): 33 | pass 34 | 35 | def data(self, start, stop, dtype=None): 36 | # assert start >= 0 37 | # assert stop >= 0 38 | # assert stop >= start 39 | 40 | if stop > len(self._source): 41 | raise IndexError("indexes {0}:{1} are beyond the end of data source of length {2}".format(start, stop, len(self._source))) 42 | 43 | if dtype is None: 44 | return self._source[start:stop] 45 | else: 46 | return self._source[start:stop].view(dtype) 47 | -------------------------------------------------------------------------------- /uproot3/source/xrootd.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import os 8 | import threading 9 | 10 | import numpy 11 | 12 | import uproot3.source.chunked 13 | 14 | class XRootDSource(uproot3.source.chunked.ChunkedSource): 15 | # makes __doc__ attribute mutable before Python 3.3 16 | __metaclass__ = type.__new__(type, "type", (uproot3.source.chunked.ChunkedSource.__metaclass__,), {}) 17 | 18 | def __init__(self, path, timeout=None, *args, **kwds): 19 | self._size = None 20 | self.timeout = timeout 21 | super(XRootDSource, self).__init__(path, *args, **kwds) 22 | 23 | defaults = {"timeout": None, "chunkbytes": 1024**2, "limitbytes": 100*1024**2, "parallel": False} 24 | 25 | def _open(self): 26 | try: 27 | os.environ["XRD_RUNFORKHANDLER"] = "1" # To make uproot3 + xrootd + multiprocessing work 28 | import pyxrootd.client 29 | except ImportError: 30 | raise ImportError("Install pyxrootd package with:\n conda install -c conda-forge xrootd\n(or download from http://xrootd.org/dload.html and manually compile with cmake; setting PYTHONPATH and LD_LIBRARY_PATH appropriately).") 31 | 32 | if self._source is None or not self._source.is_open(): 33 | self._source = pyxrootd.client.File() 34 | status, dummy = self._source.open(self.path, timeout=(0 if self.timeout is None else self.timeout)) 35 | if status.get("error", None): 36 | raise OSError(status["message"]) 37 | status, info = self._source.stat(timeout=(0 if self.timeout is None else self.timeout)) 38 | if status.get("error", None): 39 | raise OSError(status["message"]) 40 | self._size = info["size"] 41 | 42 | def size(self): 43 | if self._size is None: 44 | self._open() 45 | return self._size 46 | 47 | def threadlocal(self): 48 | out = XRootDSource.__new__(self.__class__) 49 | out.path = self.path 50 | out._chunkbytes = self._chunkbytes 51 | out.cache = self.cache 52 | out._source = None # XRootD connections are *not shared* among threads 53 | out._size = self._size 54 | out.timeout = self.timeout 55 | out._parallel = self._parallel 56 | out._executor = None 57 | out._futures = {} 58 | return out 59 | 60 | def _read(self, chunkindex): 61 | self._open() 62 | status, data = self._source.read(int(chunkindex * self._chunkbytes), int(self._chunkbytes), timeout=int(0 if self.timeout is None else self.timeout)) 63 | if status.get("error", None): 64 | raise OSError(status["message"]) 65 | return numpy.frombuffer(data, dtype=numpy.uint8) 66 | 67 | def _setup_futures(self, parallel): 68 | self._parallel = parallel 69 | self._executor = None 70 | self._futures = {} 71 | 72 | class _preload(object): 73 | def __init__(self, timeout): 74 | self.timeout = timeout 75 | self.out = None 76 | self.hold = threading.Event() 77 | 78 | def __call__(self, status, data, hostlist): 79 | if not status.get("error", None): 80 | self.out = numpy.frombuffer(data, dtype=numpy.uint8) 81 | self.hold.set() 82 | 83 | def result(self): 84 | if self.hold.wait(self.timeout): 85 | return self.out 86 | 87 | def preload(self, starts): 88 | if self._parallel: 89 | self._open() 90 | limitnum = self._limitbytes // self._chunkbytes 91 | timeout = int(0 if self.timeout is None else self.timeout) 92 | for start in starts: 93 | if len(self._futures) > limitnum: 94 | break 95 | chunkindex = start // self._chunkbytes 96 | try: 97 | self.cache[chunkindex] 98 | except KeyError: 99 | callback = self._preload(timeout) 100 | status = self._source.read(int(chunkindex * self._chunkbytes), int(self._chunkbytes), timeout=timeout, callback=callback) 101 | if status["ok"]: 102 | self._futures[chunkindex] = callback 103 | 104 | def __del__(self): 105 | if self._source is not None: 106 | self._source.close(timeout=(0 if self.timeout is None else self.timeout)) 107 | 108 | def dismiss(self): 109 | self._futures = {} 110 | -------------------------------------------------------------------------------- /uproot3/version.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import re 8 | 9 | __version__ = "3.14.4" 10 | version = __version__ 11 | version_info = tuple(re.split(r"[-\.]", __version__)) 12 | 13 | del re 14 | -------------------------------------------------------------------------------- /uproot3/write/TDirectory.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import collections 8 | import struct 9 | import uuid 10 | 11 | import uproot3.write.sink.cursor 12 | import uproot3.write.TKey 13 | import uproot3.write.util 14 | 15 | class TDirectory(object): 16 | def __init__(self, tfile, fName, fNbytesName, fSeekDir=100, fSeekParent=0, fSeekKeys=0, allocationbytes=128, growfactor=8): 17 | self.tfile = tfile 18 | self.fName = fName 19 | self.fNbytesName = fNbytesName 20 | self.fNbytesKeys = self._format2.size 21 | self.fSeekDir = fSeekDir 22 | self.fSeekParent = fSeekParent 23 | self.fSeekKeys = fSeekKeys 24 | self.fDatimeC = uproot3.write.util.datime() 25 | self.fUUID = b'\x00\x01' + uuid.uuid1().bytes 26 | 27 | self.allocationbytes = allocationbytes 28 | self.growfactor = growfactor 29 | 30 | self.headkey = uproot3.write.TKey.TKey(fClassName = b"TFile", 31 | fName = self.fName, 32 | fObjlen = self._format2.size, 33 | fSeekKey = self.fSeekKeys) 34 | self.keys = collections.OrderedDict() 35 | self.maxcycle = collections.Counter() 36 | 37 | def size(self): 38 | return uproot3.write.sink.cursor.Cursor.length_string(self.fName) + 1 + self._format1.size + len(self.fUUID) + 12 39 | 40 | def update(self): 41 | fVersion = 5 42 | fDatimeM = uproot3.write.util.datime() 43 | self.cursor.update_fields(self.sink, self._format1, fVersion, self.fDatimeC, fDatimeM, self.fNbytesKeys, self.fNbytesName, self.fSeekDir, self.fSeekParent, self.fSeekKeys) 44 | 45 | def write(self, cursor, sink): 46 | cursor.write_string(sink, self.fName) 47 | cursor.write_data(sink, b"\x00") 48 | 49 | self.cursor = uproot3.write.sink.cursor.Cursor(cursor.index) 50 | self.sink = sink 51 | self.update() 52 | 53 | cursor.skip(self._format1.size) 54 | cursor.write_data(self.sink, self.fUUID) 55 | cursor.write_data(sink, b"\x00" * 12) # FIXME! what is this? 56 | 57 | _format1 = struct.Struct(">hIIiiiii") 58 | _format2 = struct.Struct(">i") 59 | 60 | def _nbyteskeys(self): 61 | return self.headkey.fKeylen + self._format2.size + sum(x.fKeylen for x in self.keys.values()) 62 | 63 | def writekeys(self, cursor): 64 | self.fSeekKeys = cursor.index 65 | self.fNbytesKeys = self._nbyteskeys() 66 | 67 | self.tfile._expandfile(uproot3.write.sink.cursor.Cursor(self.fSeekKeys + self.allocationbytes)) 68 | 69 | self.keycursor = uproot3.write.sink.cursor.Cursor(self.fSeekKeys) 70 | self.headkey.write(self.keycursor, self.sink) 71 | self.nkeycursor = uproot3.write.sink.cursor.Cursor(self.keycursor.index) 72 | self.keycursor.write_fields(self.sink, self._format2, len(self.keys)) 73 | for key in self.keys.values(): 74 | key.write(self.keycursor, self.sink) 75 | 76 | self.update() 77 | 78 | def newcycle(self, name): 79 | self.maxcycle[name] += 1 80 | return self.maxcycle[name] 81 | 82 | def setkey(self, newkey): 83 | newcursor = None 84 | if (newkey.fName, newkey.fCycle) in self.keys: 85 | self.headkey.fObjlen -= self.keys[(newkey.fName, newkey.fCycle)].fKeylen 86 | newcursor = uproot3.write.sink.cursor.Cursor(self.fSeekKeys) 87 | 88 | self.headkey.fObjlen += newkey.fKeylen 89 | self.keys[(newkey.fName, newkey.fCycle)] = newkey 90 | 91 | self.fNbytesKeys = self._nbyteskeys() 92 | while self.fNbytesKeys > self.allocationbytes: 93 | self.allocationbytes *= self.growfactor 94 | newcursor = uproot3.write.sink.cursor.Cursor(self.tfile._fSeekFree) 95 | 96 | if newcursor is not None: 97 | self.writekeys(newcursor) 98 | else: 99 | newkey.write(self.keycursor, self.sink) 100 | self.headkey.update() 101 | self.nkeycursor.update_fields(self.sink, self._format2, len(self.keys)) 102 | self.update() 103 | 104 | def delkey(self, name, cycle): 105 | if cycle is None: 106 | for x in range(self.maxcycle[name]): 107 | self.delkey(name, x + 1) 108 | 109 | else: 110 | oldkey = self.keys[(name, cycle)] 111 | self.headkey.fObjlen -= oldkey.fKeylen 112 | del self.keys[(name, cycle)] 113 | 114 | self.fNbytesKeys = self._nbyteskeys() 115 | self.writekeys(uproot3.write.sink.cursor.Cursor(self.fSeekKeys)) 116 | -------------------------------------------------------------------------------- /uproot3/write/TFree.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import math 8 | import struct 9 | 10 | import numpy 11 | 12 | class TFree(object): 13 | def __init__(self, fEND): 14 | self.fFirst = fEND 15 | self.fLast = int(math.ceil(fEND / 2000000000.0)) * 2000000000 16 | 17 | _format_big = struct.Struct(">hqq") 18 | _format_small = struct.Struct(">hii") 19 | 20 | def write(self, cursor, sink): 21 | if self.fLast > numpy.iinfo(numpy.int32).max: 22 | cursor.write_fields(sink, self._format_big, 1001, self.fFirst, self.fLast) 23 | else: 24 | cursor.write_fields(sink, self._format_small, 1, self.fFirst, self.fLast) 25 | 26 | def size(self): 27 | if self.fLast > numpy.iinfo(numpy.int32).max: 28 | return TFree._format_big.size 29 | else: 30 | return TFree._format_small.size 31 | -------------------------------------------------------------------------------- /uproot3/write/TKey.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import struct 8 | 9 | import uproot3.write.sink.cursor 10 | import uproot3.write.util 11 | 12 | class BasketKey(object): 13 | def __init__(self, fName, fTitle, fNevBuf, fNevBufSize, fObjlen=0, fSeekKey=100, fSeekPdir=0, fBufferSize=0): 14 | self.fClassName = b"TBasket" 15 | self.fName = fName 16 | self.fTitle = fTitle 17 | 18 | self.fObjlen = fObjlen 19 | self.fSeekKey = fSeekKey 20 | self.fSeekPdir = fSeekPdir 21 | self.fCycle = 0 22 | self.fDatime = uproot3.write.util.datime() 23 | self.fNbytes = self.fObjlen + self.fKeylen 24 | self.fBufferSize = fBufferSize 25 | self.fNevBuf = fNevBuf 26 | self.fNevBufSize = fNevBufSize 27 | 28 | self.old_fLast = 0 29 | 30 | @property 31 | def fKeylen(self): 32 | return self._format1.size + uproot3.write.sink.cursor.Cursor.length_strings([self.fClassName, self.fName, self.fTitle]) + self._format_basketkey.size + 1 33 | 34 | @property 35 | def fLast(self): 36 | return self.fKeylen + self.fObjlen 37 | 38 | def update(self): 39 | self.cursor.update_fields(self.sink, self._format1, self.fNbytes, self._version, self.fObjlen, self.fDatime, self.fKeylen, self.fCycle, self.fSeekKey, self.fSeekPdir) 40 | 41 | def write(self, cursor, sink, isjagged=False): 42 | self.cursor = uproot3.write.sink.cursor.Cursor(cursor.index) 43 | self.sink = sink 44 | 45 | self.update() 46 | 47 | cursor.skip(self._format1.size) 48 | cursor.write_string(sink, self.fClassName) 49 | cursor.write_string(sink, self.fName) 50 | cursor.write_string(sink, self.fTitle) 51 | 52 | basketversion = 3 53 | if isjagged: 54 | if self.old_fLast == 0: 55 | raise Exception("isjagged flag should be False") 56 | cursor.write_fields(sink, self._format_basketkey, basketversion, self.fBufferSize, self.fNevBufSize, self.fNevBuf, self.old_fLast) 57 | else: 58 | cursor.write_fields(sink, self._format_basketkey, basketversion, self.fBufferSize, self.fNevBufSize, self.fNevBuf, self.fLast) 59 | self.old_fLast = self.fLast 60 | cursor.write_data(sink, b"\x00") 61 | 62 | _version = 1004 63 | _format1 = struct.Struct(">ihiIhhqq") 64 | _format_basketkey = struct.Struct(">Hiiii") 65 | 66 | class TKey(object): 67 | def __init__(self, fClassName, fName, fTitle=b"", fObjlen=0, fSeekKey=100, fSeekPdir=0, fCycle=1): 68 | self.fClassName = fClassName 69 | self.fName = fName 70 | self.fTitle = fTitle 71 | 72 | self.fObjlen = fObjlen 73 | self.fSeekKey = fSeekKey 74 | self.fSeekPdir = fSeekPdir 75 | self.fCycle = fCycle 76 | self.fDatime = uproot3.write.util.datime() 77 | self.fNbytes = self.fObjlen + self.fKeylen 78 | 79 | @property 80 | def fKeylen(self): 81 | return self._format1.size + uproot3.write.sink.cursor.Cursor.length_strings([self.fClassName, self.fName, self.fTitle]) 82 | 83 | def update(self): 84 | self.cursor.update_fields(self.sink, self._format1, self.fNbytes, self._version, self.fObjlen, self.fDatime, self.fKeylen, self.fCycle, self.fSeekKey, self.fSeekPdir) 85 | 86 | def write(self, cursor, sink, isjagged=False): 87 | if isjagged: 88 | raise Exception("isjagged flag should be False") 89 | self.cursor = uproot3.write.sink.cursor.Cursor(cursor.index) 90 | self.sink = sink 91 | 92 | self.update() 93 | 94 | cursor.skip(self._format1.size) 95 | cursor.write_string(sink, self.fClassName) 96 | cursor.write_string(sink, self.fName) 97 | cursor.write_string(sink, self.fTitle) 98 | 99 | _version = 1004 100 | _format1 = struct.Struct(">ihiIhhqq") 101 | 102 | class TKey32(TKey): 103 | _version = 4 104 | _format1 = struct.Struct(">ihiIhhii") 105 | -------------------------------------------------------------------------------- /uproot3/write/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | -------------------------------------------------------------------------------- /uproot3/write/compress.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import numbers 8 | import struct 9 | import copy 10 | 11 | import numpy 12 | 13 | import uproot3 14 | import uproot3.const 15 | 16 | class Compression(object): 17 | def __init__(self, level): 18 | self.level = level 19 | 20 | def __repr__(self): 21 | return "{0}({1})".format(type(self).__name__, self.level) 22 | 23 | @property 24 | def level(self): 25 | return self._level 26 | 27 | @level.setter 28 | def level(self, value): 29 | if not isinstance(value, (numbers.Integral, numpy.integer)): 30 | raise TypeError("Compression level must be an integer") 31 | if not 0 <= value <= 9: 32 | raise ValueError("Compression level must be between 0 and 9 (inclusive)") 33 | self._level = int(value) 34 | 35 | @property 36 | def pair(self): 37 | for const, cls in algo.items(): 38 | if type(self) is cls: 39 | return const, self.level 40 | else: 41 | raise AssertionError(type(self)) 42 | 43 | @property 44 | def code(self): 45 | algorithm, level = self.pair 46 | return algorithm * 100 + level 47 | 48 | class ZLIB(Compression): pass 49 | class LZMA(Compression): pass 50 | class LZ4(Compression): pass 51 | 52 | algo = {uproot3.const.kZLIB: ZLIB, 53 | uproot3.const.kLZMA: LZMA, 54 | uproot3.const.kLZ4: LZ4} 55 | 56 | def write(context, cursor, givenbytes, compression, key, keycursor, isjagged=False): 57 | retaincursor = copy.copy(keycursor) 58 | if compression is None: 59 | algorithm, level = 0, 0 60 | else: 61 | algorithm, level = compression.pair 62 | 63 | _header = struct.Struct("2sBBBBBBB") 64 | uncompressedbytes = len(givenbytes) 65 | 66 | if algorithm == 0 or level == 0: 67 | if isjagged: 68 | key.fObjlen += uncompressedbytes 69 | else: 70 | key.fObjlen = uncompressedbytes 71 | key.fNbytes = key.fObjlen + key.fKeylen 72 | key.write(keycursor, context._sink, isjagged) 73 | cursor.write_data(context._sink, givenbytes) 74 | return 75 | 76 | if uncompressedbytes > 2**24: 77 | uncompressedbytes = 2**24 - 1 78 | remainingbytes = givenbytes[2**24 - 1:] 79 | givenbytes = givenbytes[:2**24 - 1] 80 | 81 | key.fObjlen += uncompressedbytes 82 | 83 | u1 = (uncompressedbytes >> 0) & 0xff 84 | u2 = (uncompressedbytes >> 8) & 0xff 85 | u3 = (uncompressedbytes >> 16) & 0xff 86 | 87 | if algorithm == uproot3.const.kZLIB: 88 | algo = b"ZL" 89 | import zlib 90 | after_compressed = zlib.compress(givenbytes, level) 91 | compressedbytes = len(after_compressed) 92 | if (compressedbytes + 9) < uncompressedbytes: 93 | c1 = (compressedbytes >> 0) & 0xff 94 | c2 = (compressedbytes >> 8) & 0xff 95 | c3 = (compressedbytes >> 16) & 0xff 96 | method = 8 97 | cursor.write_fields(context._sink, _header, algo, method, c1, c2, c3, u1, u2, u3) 98 | cursor.write_data(context._sink, after_compressed) 99 | key.fNbytes += compressedbytes + 9 100 | key.write(keycursor, context._sink, isjagged) 101 | else: 102 | key.fNbytes += uncompressedbytes 103 | key.write(keycursor, context._sink, isjagged) 104 | cursor.write_data(context._sink, givenbytes) 105 | 106 | elif algorithm == uproot3.const.kLZ4: 107 | algo = b"L4" 108 | try: 109 | import xxhash 110 | except ImportError: 111 | raise ImportError("Install xxhash package with:\n pip install xxhash\nor\n conda install -c conda-forge python-xxhash") 112 | try: 113 | import lz4.block 114 | except ImportError: 115 | raise ImportError("Install lz4 package with:\n pip install lz4\nor\n conda install -c anaconda lz4") 116 | if level >= 4: 117 | after_compressed = lz4.block.compress(givenbytes, compression=level, mode="high_compression", store_size=False) 118 | else: 119 | after_compressed = lz4.block.compress(givenbytes, store_size=False) 120 | compressedbytes = len(after_compressed) + 8 121 | checksum = xxhash.xxh64(after_compressed).digest() 122 | if (compressedbytes + 9) < uncompressedbytes: 123 | c1 = (compressedbytes >> 0) & 0xff 124 | c2 = (compressedbytes >> 8) & 0xff 125 | c3 = (compressedbytes >> 16) & 0xff 126 | method = lz4.library_version_number() // (100 * 100) 127 | cursor.write_fields(context._sink, _header, algo, method, c1, c2, c3, u1, u2, u3) 128 | cursor.write_data(context._sink, checksum) 129 | cursor.write_data(context._sink, after_compressed) 130 | key.fNbytes += compressedbytes + 9 131 | key.write(keycursor, context._sink, isjagged) 132 | else: 133 | key.fNbytes += uncompressedbytes 134 | key.write(keycursor, context._sink, isjagged) 135 | cursor.write_data(context._sink, givenbytes) 136 | 137 | elif algorithm == uproot3.const.kLZMA: 138 | algo = b"XZ" 139 | try: 140 | import lzma 141 | except ImportError: 142 | try: 143 | from backports import lzma 144 | except ImportError: 145 | raise ImportError( 146 | "Install lzma package with:\n pip install backports.lzma\nor\n conda install -c conda-forge backports.lzma\n(or just use Python >= 3.3).") 147 | after_compressed = lzma.compress(givenbytes, preset=level) 148 | compressedbytes = len(after_compressed) 149 | if (compressedbytes + 9) < uncompressedbytes: 150 | c1 = (compressedbytes >> 0) & 0xff 151 | c2 = (compressedbytes >> 8) & 0xff 152 | c3 = (compressedbytes >> 16) & 0xff 153 | method = 0 154 | cursor.write_fields(context._sink, _header, algo, method, c1, c2, c3, u1, u2, u3) 155 | cursor.write_data(context._sink, after_compressed) 156 | key.fNbytes += compressedbytes + 9 157 | key.write(keycursor, context._sink, isjagged) 158 | else: 159 | key.fNbytes += uncompressedbytes 160 | key.write(keycursor, context._sink, isjagged) 161 | cursor.write_data(context._sink, givenbytes) 162 | 163 | elif algorithm == uproot3.const.kOldCompressionAlgo: 164 | raise ValueError("unsupported compression algorithm: 'old' (according to ROOT comments, hasn't been used in 20+ years!)") 165 | else: 166 | raise ValueError("Unrecognized compression algorithm: {0}".format(algorithm)) 167 | 168 | if "remainingbytes" in locals() and len(remainingbytes)>0: 169 | uproot3.write.compress.write(context, cursor, remainingbytes, compression, key, retaincursor) 170 | -------------------------------------------------------------------------------- /uproot3/write/objects/TObjString.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import struct 8 | from copy import copy 9 | 10 | import numpy 11 | 12 | import uproot3.const 13 | import uproot3.write.compress 14 | import uproot3.write.sink.cursor 15 | 16 | class TObjString(object): 17 | def __init__(self, string): 18 | if isinstance(string, bytes): 19 | self.value = string 20 | else: 21 | self.value = string.encode("utf-8") 22 | 23 | _fClassName = b"TObjString" 24 | _fTitle = b"Collectable string class" 25 | 26 | _format = struct.Struct(">IHHII") 27 | 28 | def _write(self, context, cursor, name, compression, key, keycursor, util): 29 | copy_cursor = copy(cursor) 30 | write_cursor = copy(cursor) 31 | cursor.skip(self._format.size) 32 | vers = 1 33 | buff = cursor.put_string(self.value) 34 | length = len(buff) + self._format.size 35 | cnt = numpy.int64(length - 4) | uproot3.const.kByteCountMask 36 | givenbytes = copy_cursor.put_fields(self._format, cnt, vers, 1, 0, uproot3.const.kNotDeleted) + buff 37 | uproot3.write.compress.write(context, write_cursor, givenbytes, compression, key, keycursor) 38 | -------------------------------------------------------------------------------- /uproot3/write/objects/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | -------------------------------------------------------------------------------- /uproot3/write/objects/util.py: -------------------------------------------------------------------------------- 1 | import struct 2 | from copy import copy 3 | 4 | import numpy 5 | 6 | import uproot3 7 | 8 | class Util(object): 9 | 10 | def __init__(self): 11 | self._written = {} 12 | self.tobjstring_count = 0 13 | 14 | _format_cntvers = struct.Struct(">IH") 15 | 16 | def _putclass(self, cursor, obj, keycursor, beg): 17 | start = cursor.index - keycursor.index 18 | beg = beg - keycursor.index 19 | buf = b"" 20 | objct, clsname = obj 21 | if id(objct) in self._written and clsname in self._written: 22 | buf += cursor.put_fields(self._format_putobjany1, numpy.uint32(self._written[id(objct)])) 23 | return buf 24 | if clsname in self._written: 25 | buf += cursor.put_fields(self._format_putobjany1, self._written[clsname] | uproot3.const.kClassMask) 26 | if clsname != "TBranch": 27 | self._written[id(objct)] = beg + uproot3.const.kMapOffset 28 | else: 29 | buf += cursor.put_fields(self._format_putobjany1, uproot3.const.kNewClassTag) 30 | buf += cursor.put_cstring(clsname) 31 | self._written[clsname] = numpy.uint32(start + uproot3.const.kMapOffset) | uproot3.const.kClassMask 32 | self._written[id(objct)] = beg + uproot3.const.kMapOffset 33 | if clsname == "THashList" or clsname == "TList": 34 | buf += self.parent_obj._put_tlist(cursor, objct) 35 | elif clsname == "TObjString": 36 | self.tobjstring_count += 1 37 | buf += self.parent_obj._put_tobjstring(cursor, objct, self.tobjstring_count) 38 | elif clsname == "TBranch": 39 | buf += objct.write(cursor) 40 | elif clsname == "TLeafI": 41 | buf += objct.put_tleafI(cursor) 42 | elif clsname == "TLeafB": 43 | buf += objct.put_tleafB(cursor) 44 | elif clsname == "TLeafD": 45 | buf += objct.put_tleafD(cursor) 46 | elif clsname == "TLeafF": 47 | buf += objct.put_tleafF(cursor) 48 | elif clsname == "TLeafL": 49 | buf += objct.put_tleafL(cursor) 50 | elif clsname == "TLeafO": 51 | buf += objct.put_tleafO(cursor) 52 | elif clsname == "TLeafS": 53 | buf += objct.put_tleafS(cursor) 54 | return buf 55 | 56 | _format_putobjany1 = struct.Struct(">I") 57 | def put_objany(self, cursor, obj, keycursor): 58 | class_buf = b"" 59 | objct, clsname = obj 60 | if id(objct) in self._written and clsname in self._written: 61 | class_buf = self._putclass(cursor, obj, keycursor, cursor.index) 62 | buff = b"" 63 | elif objct != [] and objct != None: 64 | copy_cursor = copy(cursor) 65 | beg = cursor.index 66 | cursor.skip(self._format_putobjany1.size) 67 | class_buf = self._putclass(cursor, obj, keycursor, beg) 68 | buff = copy_cursor.put_fields(self._format_putobjany1, numpy.uint32(len(class_buf)) | uproot3.const.kByteCountMask) 69 | else: 70 | copy_cursor = copy(cursor) 71 | cursor.skip(self._format_putobjany1.size) 72 | buff = copy_cursor.put_fields(self._format_putobjany1, len(class_buf)) 73 | buff += class_buf 74 | return buff 75 | 76 | def set_obj(self, parent_obj): 77 | self.parent_obj = parent_obj 78 | -------------------------------------------------------------------------------- /uproot3/write/sink/__init__.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | -------------------------------------------------------------------------------- /uproot3/write/sink/cursor.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import struct 8 | import sys 9 | 10 | from uproot3._util import _tobytes 11 | 12 | class Cursor(object): 13 | def __init__(self, index): 14 | self.index = index 15 | 16 | def skip(self, numbytes): 17 | self.index += numbytes 18 | 19 | def update_fields(self, sink, format, *args): 20 | sink.write(format.pack(*args), self.index) 21 | 22 | def write_fields(self, sink, format, *args): 23 | self.update_fields(sink, format, *args) 24 | self.index += format.size 25 | 26 | def put_fields(self, format, *args): 27 | self.index += format.size 28 | return format.pack(*args) 29 | 30 | @staticmethod 31 | def length_string(string): 32 | if len(string) < 255: 33 | return len(string) + 1 34 | else: 35 | return len(string) + 5 36 | 37 | @staticmethod 38 | def length_strings(strings): 39 | return sum(Cursor.length_string(x) for x in strings) 40 | 41 | _format_byte = struct.Struct("B") 42 | _format_byteint = struct.Struct(">Bi") 43 | def update_string(self, sink, data): 44 | if len(data) < 255: 45 | sink.write(self._format_byte.pack(len(data)), self.index) 46 | sink.write(data, self.index + 1) 47 | else: 48 | sink.write(self._format_byteint.pack(255, len(data)), self.index) 49 | sink.write(data, self.index + 5) 50 | 51 | def write_string(self, sink, data): 52 | self.update_string(sink, data) 53 | self.index += self.length_string(data) 54 | 55 | def put_string(self, data): 56 | self.index += self.length_string(data) 57 | if len(data) < 255: 58 | return self._format_byte.pack(len(data)) + data 59 | else: 60 | return self._format_byteint.pack(255, len(data)) + data 61 | 62 | def update_cstring(self, sink, data): 63 | sink.write(data, self.index) 64 | sink.write(b"\x00") 65 | 66 | def write_cstring(self, sink, data): 67 | self.update_cstring(sink, data) 68 | self.index += len(data) + 1 69 | 70 | def put_cstring(self, data): 71 | self.index += len(data) + 1 72 | return data.encode("utf-8") + b"\x00" 73 | 74 | def update_data(self, sink, data): 75 | sink.write(data, self.index) 76 | 77 | def write_data(self, sink, data): 78 | self.update_data(sink, data) 79 | self.index += len(data) 80 | 81 | def put_data(self, data): 82 | self.index += len(data) 83 | return data 84 | 85 | def put_array(self, data): 86 | self.index += data.nbytes 87 | return _tobytes(data) 88 | 89 | def update_array(self, sink, data): 90 | sink.write(_tobytes(data), self.index) 91 | 92 | def write_array(self, sink, data): 93 | self.update_array(sink, data) 94 | self.index += data.nbytes 95 | -------------------------------------------------------------------------------- /uproot3/write/sink/file.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | class Sink(object): 8 | pass 9 | 10 | class FileSink(Sink): 11 | def __init__(self, path): 12 | self._path = path 13 | self._sink = open(path, "wb+") 14 | # self._pos = 0 15 | 16 | def write(self, data, pos): 17 | self._sink.seek(pos) 18 | self._sink.write(data) 19 | 20 | # def write(self, data, pos): 21 | # if self._sink.tell() != pos: 22 | # self._sink.seek(pos) 23 | # self._sink.write(data) 24 | 25 | # def write(self, data, pos): 26 | # if self._pos != pos: 27 | # self._sink.seek(pos) 28 | # self._sink.write(data) 29 | # self._pos += len(data) # needs self._pos 30 | 31 | @property 32 | def closed(self): 33 | return self._sink.closed 34 | 35 | def close(self): 36 | if not self._sink.closed: 37 | self._sink.close() 38 | 39 | def flush(self): 40 | if not self._sink.closed: 41 | self._sink.flush() 42 | -------------------------------------------------------------------------------- /uproot3/write/util.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # BSD 3-Clause License; see https://github.com/scikit-hep/uproot3/blob/master/LICENSE 4 | 5 | from __future__ import absolute_import 6 | 7 | import datetime 8 | 9 | def datime(when=None): 10 | if when is None: 11 | when = datetime.datetime.now() 12 | return (when.year - 1995) << 26 | when.month << 22 | when.day << 17 | when.hour << 12 | when.minute << 6 | when.second 13 | --------------------------------------------------------------------------------