JSROOT (JavaScript ROOT)

repository·master·Indexed 42 days ago

https://github.com/root-project/jsroot

JavaScript ROOT (JSROOT) provides interactive, ROOT-like graphics capabilities for web browsers and Node.js environments. It enables reading and visualizing data from ROOT binary and JSON files, including TTree data processing and SVG generation. Version 7.11.99 supports custom draw functions via addDrawFunc, integration with OpenUI5, and 3D rendering via three.js.

Tokens
41.3K
Snippets
148
Records
189
Agent score
53%

What's inside JSROOT

  1. Overview of JavaScript ROOT capabilities

    master

    JavaScript ROOT (JSROOT) enables interactive, ROOT-like graphics directly within web browsers. It is designed to handle high-energy physics data visualization through several key capabilities:

    • Data Visualization: Displays data read from both binary ROOT files and JSON ROOT files.
    • Interactive Graphics: Provides interactive interfaces for common ROOT graphics (e.g., TTree::Draw(), THStack, TGeo models).
    • Server Integration: Implements a user interface for the THttpServer class, allowing for remote data interaction.
  2. Configure JSROOT layouts via URL

    master

    The layout parameter controls how multiple objects are arranged on the screen. Supported layouts include:

    • simple: Uses available space for a single object (default).
    • flex: Creates frames that can be individually moved or enlarged.
    • tabs: Provides tabs for each drawn object.
    • gridNxM: A fixed-size grid with $N imes M$ frames.
    • vertN: $N$ frames arranged vertically.
    • horizN: $N$ frames arranged horizontally.
    • vert121: 3 vertical frames where the second frame is divided into two sub-frames.
    • horiz32_12: 2 horizontal frames, with the first containing 3 sub-frames and the second containing 2 sub-frames (using relative sizing).
  3. Use ROOT macros to configure JSROOT geometry

    master

    JSROOT can execute a subset of standard ROOT C++ macro commands to configure the viewer. When providing a macro via opt=macro:name.C, only the following types of calls are executed:

    • gGeoManager->DefaultColors()
    • gGeoManager->GetVolume("NAME")->InvisibleAll()
    • gGeoManager->GetVolume("NAME")->SetTransparency(N)
    • gGeoManager->GetVolume("NAME")->SetLineColor(N)
    • gGeoManager->GetVolume("NAME")->Draw("ogl")

    Other standard ROOT commands (like new TBrowser) are ignored.

    https://root.cern/js/latest/?file=https://root.cern/files/alice2.root&item=Geometry;1&opt=macro:https://root.cern/js/files/geomAlice.C
  4. Rendering transparent volumes

    master

    Rendering transparent volumes correctly is computationally expensive. JSROOT provides several approximation methods to determine the rendering order (which volumes are drawn on top of others). All opaque volumes are always rendered first.

    Use the following options in the opt parameter to select a method:

    • dray: Use raycasting to sort volumes (most accurate, most expensive).
    • dbox: Use distance to the nearest point from the bounding box (default).
    • dpnt: Use distance from the camera view to the volume center.
    • dsize: Use volume size as the rendering order (useful for centered volumes with many shells).
    • ddflt: Use the default Three.js rendering order method.
  5. Integrate THttpServer with existing applications

    master

    By default, THttpServer automatically scans opened files, canvases, and histograms. You can also manually register objects using THttpServer::Register().

    To ensure the server can access data from a running application, you must manage how the server processes requests, especially in compiled code that lacks gSystem->ProcessEvents() calls.

  6. Use JSROOT with THttpServer

    master

    JSROOT can act as a web interface for a running ROOT application via THttpServer. This allows you to browse and display objects directly from a live server.

    • The layout is similar to the standard JSROOT page.
    • You can use standard URL parameters to configure items and drawing options.
    • To display a single specific item, use the following URL pattern: https://<server>/<path_to_file>/<item>/draw.htm?opt=<options>
    https://root.cern/js/latest/httpserver.C/Files/job1.root/hpxpy/draw.htm?opt=colz
  7. Read and process TTree data in Node.js

    master

    JSROOT allows you to read arbitrary TTree data directly in Node.js without requiring any native ROOT installation.

    Key capabilities include:

    • Data Dumping: Simple extraction of TTree data.
    • Tree Drawing: Implementing extensive tree-draw functionality.
    • TSelector Support: Reading TTree data using the TSelector class pattern.
  8. Communicate using JSON with JSROOT

    master

    Using JSON is the recommended way to communicate between ROOT applications and JSROOT.

    • Generating JSON: In C++, use obj->SaveAs("file.json"); or use TBufferJSON via THttpServer.
    • Fetching JSON: Use httpRequest(url, 'object') to retrieve a parsed object from a remote server.
    • Parsing JSON: If you have a raw JSON string, use the parse(json_string) function.
    • Converting to JSON: In Node.js or JS environments, use toJSON(obj) to convert a JS object into a ROOT JSON string.
    import { httpRequest, parse, toJSON } from 'https://root.cern/js/latest/modules/main.mjs';
    
    // Fetch from remote server
    let obj = await httpRequest("http://your_root_server:8080/Canvases/c1/root.json", "object");
    
    // Parse a raw string
    let objFromStr = parse(json_string);
    
    // Convert object to JSON string
    let json = await toJSON(obj);
  9. Configure user access and authentication

    master

    By default, the THttpServer is open for anonymous access. To restrict access, use the htdigest utility to create a password file and configure the server.

    1. Create a password file:

    htdigest -c .htdigest domain_name user_name

    2. Start the server with authentication:

    auto serv = new THttpServer("http:8080?auth_file=.htdigest&auth_domain=domain_name");

    3. Restrict access to specific objects: Use Restrict() to hide folders or objects based on user accounts or to control method execution.

    • Hide a folder from a specific user: serv->Restrict("/Folder", "hidden=guest");
    • Make a folder visible only to an admin: serv->Restrict("/Folder", "visible=admin");
    • Allow specific methods on an object: serv->Restrict("/Folder/histo1", "allow_method=GetTitle");
    • Combine options: serv->Restrict("/Folder/histo1", "allow_method=GetTitle&hide=guest");
    serv->Restrict("/Folder/histo1", "allow_method=GetTitle&hide=guest");
  10. Manage THttpServer request processing

    master

    If your application is running in compiled code without gSystem->ProcessEvents(), use one of the following two methods to handle requests:

    Configure an asynchronous timer using SetTimer. This allows the server to run without modifying your main application loop, but it provides no control over when data is accessed. This can lead to reading incomplete objects (e.g., during a TH1::Fill() call).

    serv->SetTimer(100, kFALSE);

    Manually call ProcessRequests() within your application's main loop. This gives you full control over when the server accesses application data. When using this method, you should disable the automatic timer.

    // In your main loop
    serv->ProcessRequests();
    
    // Setup: Disable the timer
    serv->SetTimer(0, kTRUE);
    // Recommended approach for compiled applications
    serv->SetTimer(0, kTRUE); // Disable automatic timer
    
    while (app_running) {
        // ... your application logic ...
        serv->ProcessRequests();
    }
  11. Implement Websockets support in THttpServer

    master

    To add Websocket support to your ROOT HTTP server, you must create a subclass of THttpWSHandler and register it with your THttpServer instance.

    Websocket support requires ROOT v6.12 or later.

    Key steps:

    1. Subclass THttpWSHandler.
    2. Override GetDefaultPageContent() to specify the HTML page served at the handler's address.
    3. Override ProcessWS(THttpCallArg *arg) to handle the four primary Websocket event types: WS_CONNECT, WS_READY, WS_DATA, and WS_CLOSE.
    4. Register the handler instance using THttpServer::Register().

    Once registered, the websocket connection can be established at ws://host_name:port/handler_name/root.websocket.

    #include "THttpWSHandler.h"
    
    class TUserHandler : public THttpWSHandler {
    public:
       TUserHandler(const char *name, const char *title) : THttpWSHandler(name, title) {}
    
       // provide custom HTML page when open correspondent address
       TString GetDefaultPageContent() override { return "file:ws.htm"; }
    
       Bool_t ProcessWS(THttpCallArg *arg) override;
    };
    
    // Implementation of ProcessWS
    Bool_t TUserHandler::ProcessWS(THttpCallArg *arg)
    {
       if (arg->IsMethod("WS_CONNECT")) {
          return kTRUE; // accept all connections
       }
    
       if (arg->IsMethod("WS_READY")) {
          // arg->GetWSId() provides the websocket ID
          SendCharStartWS(arg->GetWSId(), "Init"); 
          return kTRUE;
       }
    
       if (arg->IsMethod("WS_CLOSE")) {
          return kTRUE;
       }
    
       if (arg->IsMethod("WS_DATA")) {
          TString str = arg->GetPostDataAsString();
          printf("Client msg: %s\n", str.Data());
          SendCharStarWS(arg->GetWSId(), "Confirm");
          return kTRUE;
       }
    
       return kFALSE;
    }
    
    // Registration
    THttpServer *serv = new THttpServer("http:8080");
    TUserHandler *handler = new TUserHandler("name1","title");
    serv->Register(handler);