From a1a17de126cd086e6354c0e3dddabbc97a5c6f50 Mon Sep 17 00:00:00 2001 From: Pere Mato Date: Mon, 3 Jun 2024 17:34:37 +0200 Subject: [PATCH 1/5] Replacing xrootdgo by XRootD.jl (#340) * Replace xrootdgo_jll by XRootD.jl --- Project.toml | 4 ++-- src/root.jl | 6 +----- src/streamsource.jl | 42 ++++++++++++++++-------------------------- test/runtests.jl | 42 ++++++++++++++++++++++-------------------- 4 files changed, 41 insertions(+), 53 deletions(-) diff --git a/Project.toml b/Project.toml index 5be877dc..162ec744 100644 --- a/Project.toml +++ b/Project.toml @@ -27,8 +27,8 @@ StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" StructArrays = "09ab397b-f2b6-538f-b94a-2f83cf4a842a" TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76" Tables = "bd369af6-aec1-5ad0-b16a-f7cc5008161c" +XRootD = "164e3b87-dc46-4cbc-97a6-5b310108fce0" XXHashNative = "e5d8e439-e7fa-4681-9c12-1c64bda517be" -xrootdgo_jll = "9d84c17e-11f2-50ef-8cc9-e9701362097f" [compat] AbstractTrees = "^0.4" @@ -61,9 +61,9 @@ StructArrays = "0.6" TOML = "^1.0" Tables = "^1.9" Test = "^1.0" +XRootD = "^0.1" XXHashNative = "^1.0.1" julia = "^1.7" -xrootdgo_jll = "=0.32.1, =0.34.1" [extras] Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595" diff --git a/src/root.jl b/src/root.jl index e4273bc6..a65f5659 100644 --- a/src/root.jl +++ b/src/root.jl @@ -66,11 +66,7 @@ function ROOTFile(filename::AbstractString; customstructs = Dict("TLorentzVector fobj = if startswith(filename, r"https?://") HTTPStream(filename) elseif startswith(filename, "root://") - length(findall("//", filename)) < 2 && error("The xrootd URL is illegal: missing the '//' separator between the server and the path (e.g. 'root://server:1234//path/to/file.root')") - sep_idx = findall("//", filename)[2] - baseurl = filename[8:first(sep_idx)-1] - filepath = filename[last(sep_idx):end] - XRDStream(baseurl, filepath, "go") + XRDStream(filename) else !isfile(filename) && throw(SystemError("opening file $filename", 2)) MmapStream(filename) diff --git a/src/streamsource.jl b/src/streamsource.jl index 048cafb0..65ef3d9b 100644 --- a/src/streamsource.jl +++ b/src/streamsource.jl @@ -1,8 +1,8 @@ -using xrootdgo_jll +using XRootD.XrdCl import HTTP mutable struct XRDStream - gofile_id::Cstring # used as key to a global `map` on the Go side + file::File # encapsulates a XRootD.XrdCl!File object seekloc::Int size::Int end @@ -130,50 +130,40 @@ function Base.read(fobj::SourceStream) read(fobj, fobj.size - fobj.seekloc + 1) end -function XRDStream(urlbase::AbstractString, filepath::AbstractString, username::AbstractString) - file_id = @ccall xrootdgo.Open(urlbase::Cstring, filepath::Cstring, username::Cstring)::Cstring - if unsafe_string(file_id) == "error" - error("xrootd Go library errored.") - end - # file_id = @threadcall((:Open, xrootdgo), Cstring, (Cstring, Cstring, Cstring), urlbase, filepath, username) - size = @ccall xrootdgo.Size(file_id::Cstring)::Int - XRDStream(file_id, 0, size) +function XRDStream(url::AbstractString) + file = File() + st, _ = open(file, url, OpenFlags.Read) + isError(st) && error("XRootD file open error: $st") + st, statinfo = stat(file) + isError(st) && error("XRootD file stat error: $st") + XRDStream(file, 0, statinfo.size) end function Base.close(fobj::XRDStream) - xrootdgo.Close(fobj.gofile_id) + close(fobj.file) end function read_seek_nb(fobj::XRDStream, seek, nb) - buffer = Vector{UInt8}(undef, nb) - # @threadcall((:ReadAt, xrootdgo), Cvoid, (Ptr{UInt8}, Cstring, Clong, Clong), buffer, fobj.gofile_id, nb, seek) - @ccall xrootdgo.ReadAt(buffer::Ptr{UInt8}, fobj.gofile_id::Cstring, nb::Clong, seek::Clong)::Cvoid + st, buffer = read(fobj.file, nb, seek) + isError(st) && error("XRootD file read error: $st") return buffer end -function _read!(ptr, fobj, nb, seekloc) - @ccall xrootdgo.ReadAt(ptr::Ptr{UInt8}, - fobj.gofile_id::Cstring, nb::Clong, seekloc::Clong)::Cvoid -end - -function _read!(ptr, fobj, nb) - _read!(ptr, fobj, nb, fobj.seekloc) -end function Base.read(fobj::XRDStream, ::Type{T}) where T @debug @show T, sizeof(T) nb = sizeof(T) output = Ref{T}() tko = Base.@_gc_preserve_begin output - po = Ptr{UInt8}(pointer_from_objref(output)) - _read!(po, fobj, nb, fobj.seekloc) + po = pointer_from_objref(output) + unsafe_read(fobj.file, po, nb, fobj.seekloc) Base.@_gc_preserve_end tko fobj.seekloc += nb return output[] end function Base.read(fobj::XRDStream, nb::Integer) - buffer = Vector{UInt8}(undef, nb) - GC.@preserve buffer _read!(buffer, fobj, nb, fobj.seekloc) + st, buffer = read(fobj.file, nb, fobj.seekloc) + isError(st) && error("XRootD file read error: $st") fobj.seekloc += nb return buffer end diff --git a/test/runtests.jl b/test/runtests.jl index 14315a6f..0221f962 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,27 +4,29 @@ using UnROOT nthreads = UnROOT._maxthreadid() nthreads == 1 && @warn "Running on a single thread. Please re-run the test suite with at least two threads (`julia --threads 2 ...`)" -include("Aqua.jl") -include("bootstrapping.jl") -include("compressions.jl") -include("jagged.jl") -include("lazy.jl") -include("histograms.jl") -include("views.jl") -include("multithreading.jl") -include("remote.jl") -include("displays.jl") -include("type_stability.jl") -include("utils.jl") -include("misc.jl") +@testset "UnROOT tests" verbose = true begin + include("Aqua.jl") + include("bootstrapping.jl") + include("compressions.jl") + include("jagged.jl") + include("lazy.jl") + include("histograms.jl") + include("views.jl") + include("multithreading.jl") + include("remote.jl") + include("displays.jl") + include("type_stability.jl") + include("utils.jl") + include("misc.jl") -include("type_support.jl") -include("custom_bootstrapping.jl") -include("lorentzvectors.jl") -include("NanoAOD.jl") + include("type_support.jl") + include("custom_bootstrapping.jl") + include("lorentzvectors.jl") + include("NanoAOD.jl") -include("issues.jl") + include("issues.jl") -if VERSION >= v"1.9" - include("rntuple.jl") + if VERSION >= v"1.9" + include("rntuple.jl") + end end From 01969242f7006350ba0f194e615be63fd448df48 Mon Sep 17 00:00:00 2001 From: Jerry Ling Date: Tue, 4 Jun 2024 08:24:41 -0400 Subject: [PATCH 2/5] bump to 0.10.31 (#341) Release for XRootD.jl --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 162ec744..c264a955 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "UnROOT" uuid = "3cd96dde-e98d-4713-81e9-a4a1b0235ce9" authors = ["Tamas Gal", "Jerry Ling", "Johannes Schumann", "Nick Amin"] -version = "0.10.30" +version = "0.10.31" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c" From dd2f9dbd28d112fd63d5706ea3460d95c7f02418 Mon Sep 17 00:00:00 2001 From: Jerry Ling Date: Fri, 5 Jul 2024 21:30:10 -0400 Subject: [PATCH 3/5] fix reading `TLeafC` (#342) * fix reading TLeafC * add test sample and tests --- src/root.jl | 15 ++++++++++++--- test/issues.jl | 5 +++++ test/samples/TLeafC_pr342.root | Bin 0 -> 28262 bytes 3 files changed, 17 insertions(+), 3 deletions(-) create mode 100644 test/samples/TLeafC_pr342.root diff --git a/src/root.jl b/src/root.jl index a65f5659..4070e288 100644 --- a/src/root.jl +++ b/src/root.jl @@ -247,6 +247,11 @@ function interped_data(rawdata, rawoffsets, ::Type{Bool}, ::Type{Nojagg}) # specialized case to get Vector{Bool} instead of BitVector return map(ntoh,reinterpret(Bool, rawdata)) end +function interped_data(rawdata, rawoffsets, ::Type{String}, ::Type{Nojagg}) + rawoffsets .= rawoffsets .+ 1 + vov_bytes = VectorOfVectors(rawdata, rawoffsets) + return [readtype(IOBuffer(v), String) for v in vov_bytes] +end function interped_data(rawdata, rawoffsets, ::Type{T}, ::Type{J}) where {T, J<:JaggType} # there are two possibility, one is the leaf is just normal leaf but the title has "[...]" in it # magic offsets, seems to be common for a lot of types, see auto.py in uproot3 @@ -481,12 +486,16 @@ function leaf_jaggtype(leaf, _jaggtype) _fTitle = replace(leaf.fTitle, "[$(leafLen)]" => "") # looking for more `[var]` m = match(r"\[\D+\]", _fTitle) - _type = FixLenVector{Int(leafLen), _type} + _vtype = FixLenVector{Int(leafLen), _type} if isnothing(m) - return _type, Nojagg + if leaf isa TLeafC + return String, Nojagg + else + return _vtype, Nojagg + end else #FIXME this only handles [var][fix] case - return Vector{_type}, Nooffsetjagg + return Vector{_vtype}, Nooffsetjagg end end _type = _jaggtype === Nojagg ? _type : Vector{_type} diff --git a/test/issues.jl b/test/issues.jl index 98c01bf7..7bab1231 100644 --- a/test/issues.jl +++ b/test/issues.jl @@ -94,3 +94,8 @@ end @test length(tree.PandoraPFOs_energy[1]) == 79 @test length(tree.var"PandoraPFOs_covMatrix[10]"[1]) == 790 end + +@testset "PR 342 TLeafC" begin + df = LazyTree(UnROOT.samplefile("TLeafC_pr342.root"), "G4Sim") + @test all(df.Process[1:10] .== ["Radioactivation", "msc", "eIoni", "Transportation", "ionIoni", "Radioactivation", "msc", "eIoni", "ionIoni", "Radioactivation"]) +end diff --git a/test/samples/TLeafC_pr342.root b/test/samples/TLeafC_pr342.root new file mode 100644 index 0000000000000000000000000000000000000000..59ff77573e91b2a33a3712f6fecf73cb226a7a77 GIT binary patch literal 28262 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 TasIzxrEgfMgQYu965M|PgjO|b literal 0 HcmV?d00001 From c933c7b8a81dd69c05ad001c432a6d957e8737e9 Mon Sep 17 00:00:00 2001 From: Jerry Ling Date: Tue, 30 Jul 2024 13:34:13 -0400 Subject: [PATCH 4/5] fix parsing histograms filled with no weights (#345) --- src/utils.jl | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/utils.jl b/src/utils.jl index 042fe803..ef47e860 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -114,6 +114,9 @@ function parseTH(th::Dict{Symbol, Any}; raw=true) counts = th[:fN] nentries = th[:fEntries] sumw2 = th[:fSumw2] + if isempty(sumw2) + sumw2 = counts + end dimension = th[:fYaxis_fNbins] if dimension > 1 ymin = th[:fYaxis_fXmin] From ccd83664bf0c9bedbc4431e747cc43e55af87787 Mon Sep 17 00:00:00 2001 From: Jerry Ling Date: Tue, 30 Jul 2024 13:34:49 -0400 Subject: [PATCH 5/5] bump to 0.10.32 --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index c264a955..3aab73fe 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "UnROOT" uuid = "3cd96dde-e98d-4713-81e9-a4a1b0235ce9" authors = ["Tamas Gal", "Jerry Ling", "Johannes Schumann", "Nick Amin"] -version = "0.10.31" +version = "0.10.32" [deps] AbstractTrees = "1520ce14-60c1-5f80-bbc7-55ef81b5835c"