dataesr/scientific-paragraphs-categorization huggingface dataset:
Delegating the loop to an underlying compiled library (in our case the ROOT library) is not sufficient to achieve good performance with Python: the RDataFrame python implementation is 2. 2 (resp. 2. 8) times slower than the Julia data frame (resp. for-loop) implementation. The C ++ RDataFrame implementations are slower than the Julia and C ++ for-loop implementations by a factor from 1. 4 to 2. 1 depending on the implementations we compare. The dimuon spectrum obtained with the Julia code is shown in Fig. 4. The data frame benchmark includes the insertion of a column in the data frame with the dimuon mass. In the Julia case, the insertion is not needed for the analysis itself, but keeping it is interesting for benchmark purpose. The data frame returned by UnROOT does not allow direct insertion and the selected rows are copied to a DataFrames.
3). The implementation using Awkward Arrays operating on a vector of all events runs faster than the Python RDataFrame implementation and is only 1. 6 times slower than with the Julia for-loop. We note that the Python's performance is highly dependent on the algorithm implementation: the time ratio with respect to the Julia for-loop goes up to 63 for a vectorized implementation using Pandas data frames and to 1200 with the event loop. Running on a 61. 5 million event file shows that the for-loop and RDataFrame implementations scale well with larger input files with no penalty on the event throughput as we could have expected. The other implementations would require modifications in the code in order to process events in chunks and reduce the memory usage. The awkward array implementation requires 14.
5 GiB, at the limit of 15 GiB available on the machine used for the measurement, while the Pandas and Julia data frame versions exceed this limit. We see in this example that Julia is performing similar or better than C ++ frameworks. For an event loop, Python is slower by three-ordersof-magnitude than Julia. Vectorization of event processing serves as a mitigation of Python's slowness by delegating the event loop to underlying compiled libraries and sacrifice flexibility, without achieving the performance of C ++ and Julia 6.
5. The CxxWrap package  [41]  can be used to add Julia bindings to C ++ libraries. Once bound, the library is accessed transparently from Julia as if it was a native Julia package. The object. method(args. ) and object_ptr->method(args. ) C ++ like method calls translate into the Julia-like call function compute_dot(DX::Vector{Float64}, DY::Vector{Float64}) @assert length(DX) == length(DY) n = length(DX) incx = incy = 1 product = ccall((:ddot_, "libLAPACK"), Float64, (Ref{Int32}, Ptr{Float64}, Ref{Int32}, Ptr{Float64}, Ref{Int32}), n, DX, incx, DY, incy) return product end Listing 1: Example of call from Julia of a function implemented in Fortran  [40]  path = ccall(:getenv, Cstring, (Cstring,), "SHELL") println(unsafe_string(path)) Listing 2: Example of call of a function of a Clibrary from Julia  [40]  function getenv(var::AbstractString) val = ccall(:getenv, Cstring, (Cstring,), var) if val == C_NULL error("getenv: undefined variable: ", var) end return unsafe_string(val) end Execute some code written in Julia.
The variable x dened in the Python space is accessible from Julia. method(object, args. ). The package philosophy is similar to Boost. Python  [42]  and Pybind11  [43] : the bindings are produced with few lines of C ++ code, one line per class and one line per method, which must be compiled as a shared library. The package provides all the flexibility to expose a different Julia interface to the C ++ one, for instance to adapt it to the Julia context and style of programming. CxxWrap internally uses the built-in Julia-C interface, used for the interface between shared libraries and Julia. The C ++ standard template library vectors and val_arrays are mapped to Julia Vectors with zero copy. The WrapIt project  [44]  has demonstrated that binding code can be generated automatically from a library's header files, which would make the process of adding Julia bindings to C ++ libraries very easy.
Automation of this Julia binding has been tested on the ROOT libraries, and we have been able to produce, draw, and fit histograms and graphs (TGraph class). The fit has been tested with both functions defined in ROOT and functions defined in Julia, demonstrating a perfect integration. Unlike direct calls into C or Fortran libraries via the ccall function, calls between C ++ and Julia have to go through the intermediate layer created by the wrapper code. We perform several measurements to estimate the overhead from the C ++ -Julia interface. The measurement is performed on a call to the ROOT TH1D::Fill method, that adds a value to a histogram: we time a loop of 1 million calls and average the result to get the time per call. First, we create a shared library, that exports C functions, we call from Julia with the ccall method.
Parallel computing Apart from having memory shared multi-threading, Julia also ships with out-of-core distributed computing capability as a standard library (Distributed). In fact, it is as easy to command an array of heterogeneous nodes in real-time via packages such as ClusterManagers. jl  [56] , which can mimic Dask's experience  [57]  with a fraction of the code. For more advanced features, such as building out-of-core computation graphs, Dagger. jl  [58]  provides facilities. While these libaries allow distribution of execution within the Julia code, parallelization can be also done, as with C ++ and Python, by running parallel jobs of the same executable using commands of a batch processing system, like HTCondor  [59, 60] , typically used in computer cluster facilities.
Those who prefer plotly to matplot, can use the PlotlyJS. jl, a Julia interface to plotly. The high-level grammar of interactive graphics Vega-Lite  [87]  is also supported, thanks to the VegaLite. jl  [88]  package that supports exports to bitmap and vector image files, including the PDF format, which is convenient to include in papers written with L A T E X. Plotting can also be done on a text terminal, using the UnicodePlots. jl  [89]  package, supported by the Plot front end. The visualization tool ecosystem for Julia is rich, with the added benefit of staying in the same environment as the analysis and enabling an interactive workflow.
Notebook support A computational notebook is an interface for literate programming that allows embedding calculations within text. Notebooks have been made popular by Mathematica  [90] , which has supported notebooks starting from its first version, 1. 0, released in 1988. In HEP, notebooks are widely used by theoreticians for symbolic calculation e. g. , with Mathematica, and by experimentalists, for data analysis, and plotting using Python or C ++ as programming language. The notebook system used with Python, Jupyter, fully supports Julia. The "ju" of Jupyter stands for Julia, while "py" stands for Python and "er" for the R language. The ROOT analysis framework brings C ++ support to Jupyter. The notebook support for Julia is richer than for Python and C++. In addition to Jupyter, Pluto.
Interoperability with libraries written in C, C ++ , or Fortran, as discussed in the "Interoperability with legacy code" section, it is essential not to have to re-write all the external libraries in Julia. Simulation and reconstruction is compute intensive and therefore good performance is essential: performance has a direct impact on the computing infrastructure cost. We have seen in the previous section that Julia meets the C/C ++ performance and sometimes surpasses it. Code parallelization and efficient use of single instruction multiple data (SIMD) vectorization features of CPUs is essential at the LHC and for HL-LHC to efficiently use current hardware resources, with a high density of computing cores, including accelerators (e. g. , GPU) that can count tens of thousands core  [6]. The Julia language provides a very good support for multi-threading: a loop can be parallelized by a single macro (@threads), an operation can be made atomic by prefixing it with @atomic, a more general lock mechanism is provided, asynchronous tasks, with distribution of tasks to different threads, is natively supported.
Julia supports distributed computing, using its own communication mechanism but also using MPI  [93, 94]. It is possible to use Julia's compiler to vectorize loops by using the @simd macro or the more advanced @turbo from the LoopVectorization. jl package  [95]. Due to its effective metaprogramming capabilities, Julia has great support for running code on heterogeneous architectures, Julia code can be compiled for Nvidia (CUDA), AMD (ROC) and Intel (oneAPI) GPUs via compiler written in Julia 8 , without dependency on, for example, C ++ CUDA or HIP library. Packages like GPUArrays. jl and KernelAbstractions. jl allow the use of exactly the same core algorithm written in Julia to be executed across different vendor platforms with 8 https://github. com/JuliaGPU/GPUCompiler. jl minimal boilerplate code, which is a currently a unique feature among languages.
On the more user-facing front, libraries such as Tullio. jl  [96]  combine metaprogramming and kernel programming ability to allow users to express tensor operation with Einstein notations regardless of whether the array lives on RAM or GPU VRAM. This is very relevant for data preservation and for unifying effort to write algorithms once and run them everywhere. The ability to run native Julia code on both CPUs and GPUs, combined with the support for automatic differentiation in Julia, makes Julia an excellent platform for machine learning (ML) research. This is especially true for advanced scientific machine learning that goes beyond combining conventional matrix-crunching ML-primitives/layers and uses physical/semantic models or mixes them with generic ML constructs.
Symbolic Calculations in Julia Julia is a fast, solid and reliable programming language with a well developed Computer Algebra System (CAS) such as Symbolics. jl  [97] , a language for symbolic calculations such as Symata. jl  [98] , and an interface to Mathematica such as MathLink. jl [99], that could be widely used in HEP, considering the advantages Julia has. Symbolics. jl  [100]  is a CAS written in pure Julia, which is developed by the SciML community [101] who also maintain the state-of-the-art differential equations ecosystem  [102]. The package has scalable performance and integrates with the rest of Julia ecosystem thanks to its non-OOP design and multiple dispatch  [97]. Some of the main features of Symbolics. jl include pattern matching, simplification, substitution, logical and boolean expressions, symbolic equation solving, support for non-standard algebras with non-commutative symbols, automatic conversion of Julia code to symbolic code and generation of high performance and parallel functions from symbolic expressions  [103] , which make it even more interesting for possible applications in HEP.
At the heart of Symbolics. jl, we find ModelingToolkit. jl, a symbolic equation-based modeling system  [104] , and SymbolicUtils. jl, a rule-based rewrite system [105]. Symata. jl  [98]  is a language for symbolic computations in which some features, such as evaluation, pattern matching and flow control, are written in Julia, and symbolic calculations are developed by wrapping Sympy, a python library for symbolic mathematics. MathLink. jl [99] is a Julia language interface for the Wolfram Symbolic Transfer Protocol (WSTP) (this requires the installation of Mathematica or the free Wolfram Engine to run properly). The interface is a W"" string macro used to define Mathematica symbols. MathLinkExtras. jl [106] adds extra functionalities such as W2Mstr, which allows the conversion of Julia MathLink expressions into Mathematica expressions, and W2Tex which converts Julia MathLink.
Event Generators To be prepared for future needs for event generation  [107] , it is conceivable to rewrite parts of the existing event generators in Julia and making use of modern parallelisation technologies. One of the most demanding tasks in event generation is the evaluation of matrix elements and cross sections, where Julia provides several useful tools. The package Dagger. jl is a framework for outof-core and parallel computing written in pure Julia. It is similar to the python library Dask and provides a scheduler for parallelized execution of computing tasks represented as a directed acyclic graphs (DAGs). Such DAGs could be used to represent the evaluation of matrix elements in terms of elementary building blocks, similar to HELASlike functions in Madgraph4GPU (see e. g. ,  [108] ).
Packaging Julia comes with a built-in package manager, Pkg. jl. It builds on the experience of package managers in other ecosystems, and it can be used to install packages and manage "environments", similar to the concept of virtual environments in Python. A Julia environment is defined by two files: • Project. toml: this file records version and UUID of the current project, it also contains the list of direct dependencies of this project, as well as the compatibility bounds with these packages and Julia itself. Moreover, all Julia packages follow semantic versioning (semVer  [110] ): version numbers are composed of three parts, major, minor and patch numbers, and breaking changes can only be introduced in versions which change the left-most non-zero component (e. g. , going from 0. 0. 2 to 0.
Pkg. jl is able to deal with multiple registries at the same time, which can be both public and private, in case there is a need to provide packages relevant only to a single group or collaboration. Because there is only one package manager and only one way to record package dependency, the Julia package registry simply records the dependency and compatibility metadata separately from package's source code. It allows a local resolver to correctly resolve compatibility in a short amount of time. Users can interact with the package manager either by using its programmatic API (useful for scripting) or an interactive REPL mode, which can be entered by typing the closing square bracket ] in Julia's REPL. The package manager can also be used to run the tests for packages with a single command (Pkg.
Automatic differentiation The multiple dispatch system and the native speed of Julia eliminated the need for many specialized libraries to implement the same interface (e. g NumPy-interface in JAX [114], TensorFlow [115], PyTorch [116]). Instead, package maintainers only have to focus on providing rules for the built-in functions as they are fast already and downstream packages are mostly pure-Julia too, see ChainRules. jl  [117]. A dedicated organization, JuliaDiff [118] collects all the packages and efforts regarding what each autodiff engine is good at. Foundation HEP-specific libraries to be developed or consolidated Integration in the ROOT framework Because of the ubiquity of ROOT in HEP, a Julia interface to this framework, similar to the existing Python one and that will allow people familiar to it to find their way easily, is essential for the development of Julia in the HEP community.
Just-in-time compilation latency While applications written in Julia run faster than with an interpreted language, the first execution requires additional time to perform the just-in-time (JIT) compilation. In order to limit this overhead, the intermediate results of the compilation, called precompiled code, is cached on disk. The precompilation of a package code is typically performed in parallel at installation time, and the cached content includes, but is not limited to: lowered code, type inference result, etc. ; but at the time of writing, Julia does not yet cache compiled machine code 10. The latency is often called "time-to-first-plot". The JIT compilation latency has been improved from version-to-version, in particular with versions 1. 5, 1. 6, 1. 8, and 1. 9 by reducing the number of required recompilations.
The various sources of latency have been studied extensively  [152, 153]  and the reduction of the time-to-first-plot is a high priority for the compiler team. Besides improvements coming from the compiler, following the general guidelines of Julia code style for performance  [40] , which ensure that the compiler can easily infer variable types, should reduce such 9 https://juliacon. org/ 10 Progress is being made, see https://github. com/JuliaLang/ julia/pull/44527 latency  [152]. At the same time, tools have been developed to both help "hunt" down unnecessary recompilation (SnoopCompile. jl [154]), as well as help precompile known common user routinges at installation time (PrecompileTools. jl  [155] ). The latency can also be drastically reduced by preparing a custom system image: the system image contains cached machine code for a set of precompiled packages and past executions.
jl for an interactive session or for a short batch script much more convenient. To measure the improvement brought by the efforts of Julia developers, the measurement is repeated with the older long-term-support release 1. 6. 7. With this older release the result is 29. 0±0. 1 s for Makie. jl, showing an improvement larger than a factor of 4. The start-up time could be a concern for large HEP experiment simulation and reconstruction software. As an example of software size, the CMS experiment software, CMSSW  [157] , totals more than 2 million of lines of C ++ code. The assessment was done with release 12. 3. 5 and the number of lines of code was defined as the number of semicolons contained in the code. In lieu of a similar sized HEP software package written in Julia, we have measured the start-up time on the relatively large package OrdinaryDiffEq, using its version 6.
The reaction of these students has been uniformly positive. Master and PhD theses that used Julia as the primary language have resulted in very positive experience for both students and supervisors. Students who use Julia in longer-term projects not only become very proficient in the language, but also gain a lower-level understanding of computing, data structures and performance implications of modern hardware in general, compared to students who work in Python. This is because Julia makes it very easy the move between higher-level and lower-level programming, in contrast to the Python-plus-C ++ two-language approach. More code reuse and transfer has been observed across student generations in Julia, compared to C ++. This is due to the combination of an excellent package management with the use of multiple dispatch as a foundation.
Conclusions The Julia programming language has been presented and compared with C ++ and Python. To study the potential of Julia for HEP, a list of requirements for offline and software-based-trigger HEP applications, covering both the language and its ecosystem, has been established. The compatibility of Julia with these requirements has been studied. Julia and its ecosystem are impressively fulfilling all these requirements. Moreover, Julia brings other features-integrated packaging system with reproducibility support, multiple dispatch and automatic differentiation-from which HEP applications would benefit. The capacity to provide, at the same time, ease of programming and performance makes Julia the ideal programming language for HEP data analysis and is more generally an important asset for all the considered HEP applications.
The dynamic multiple dispatch paradigm of Julia has proven to ease code reuse. This property will greatly benefit HEP community applications that involve code developed by many people from many different groups. Using a single and easy programming language will facilitate training. Experience has shown students with either a C ++ or Python background learn the language very quickly, being productive after a few days. Using Julia as mainstream language in a collaboration allows students on short-term projects to use the common programming language, while in case of C ++ , using a simpler language as Python is often needed. This eases the reuse of the code developed in such context. We have measured the performance provided by the language in the context of HEP data analysis. The measurements show excellent runtime performance, competitive with C ++ : 11% faster for the simple LHC event analysis example used as benchmark.
When compared to Python, in addition to being faster, it is much less sensitive to implementation choices. The Python implementation was shown to be three orders of magnitude slower than Julia when the event loop is performed in Python. Vectorization techniques can be used to move the event loop by using underlying compiled libraries and this reduces the gap in performance. One difference with C ++ and Python is that Julia is younger and has a smaller community. The Julia community is very collaborative and, despite its lower popularity, information for developing with this language is easy to find on the Internet. Julia's rapid growth in academia and industry gives us confidence on the long term continuity of the Julia language, which is essential for HEP projects, because of their large time span.
In this work, we propose a model-based deep learning reconstruction algorithm for optical projection tomography (ToMoDL), to greatly reduce acquisition and reconstruction times. The proposed method iterates over a data consistency step and an image domain artefact removal step achieved by a convolutional neural network. A preprocessing stage is also included to avoid potential misalignments between the sample center of rotation and the detector. The algorithm is trained using a database of wild-type zebrafish (Danio rerio) at different stages of development to minimise the mean square error for a fixed number of iterations. Using a cross-validation scheme, we compare the results to other reconstruction methods, such as filtered backprojection, compressed sensing and a direct deep learning method where the pseudo-inverse solution is corrected by a U-Net.
Implementation details As described in the previous section, each iteration in the unrolled model-based approach can be separated in two stages: a data consistency step DC , ensuring consistency between the acquired data and the measurements generated with the forward model, and a trainable denoising block D θ. Source code for the presented work can be found on GitHub at https:// github. com/ marco so96/ ToMoDL and Zenodo at https:// doi. org/ 10. 5281/ zenodo. 10056 893. While MoDL theory for regularised reconstruction has been recently developed and implemented within the field of MRI imaging  9, 17  , its potential for tomographic reconstruction is essentially constrained by the computational burden that the Radon transform poses when applied iteratively. To overcome this limitation, our proposed method, ToMoDL, incorporates TorchRadon 18 , a fast differentiable routine for computed tomography reconstruction developed as a PyTorch extension.
Zebrafish OPT imaging Projection data of wild-type zebrafish (Danio rerio) at different stages of development ranging from 1 to 5 days post fertilisation were obtained as described in 3 using 4x objective projections. Using a rotatory cylinder, transmitted projections images were acquired with an angle step of 0. 5 degrees. The acquired projections had 700× 700 pixels with a resolution of 1. 3 μm per pixel. These projections were resampled and normalised so that the FBP projections would have a resolution of 100 × 100 pixels in order to reduce the computational complexity of the training phase. For the reconstruction task, we chose 12 volumes from different specimen sections. Tomographic artefacts due to rotation axis misalignment, such as ' double-wall'  22  , were corrected by maximising the variance of the reconstructed images from sinograms modified via rigid registration to different locations of the centre of rotation (Fig.