JSROOT Branch to Javascript Array

Hi, I’m new to JSROOT and javascript in general and I have what is likely an easy question:
I’m trying to write a function that will turn a branch into a javascript array.

function branchToArray(filename, branchName) {

    let branchArray = [];

    //use JSROOT to get arrays                                                           
    JSROOT.OpenFile(filename, function(file) {                                            
                file.ReadObject('mytree;1', function(tree) {

                    //create selector object, add branches                                           
                    let selector = new JSROOT.TSelector();
                    selector.AddBranch(branchName, 'myBranch');
                    
                    let nPoints = 0;

                    //start the analysis                                                             
                    selector.Begin = function(){};
                    //run the loop                                                                   
		            selector.Process = function(){
			            branchArray.push(this.tgtobj.myBranch);
                        nPoints ++;
                    }
                    //kill the loop                                                                  
                    selector.Terminate = function(){};

                    tree.Process(selector);
           });
    });
    return branchArray;
}

This returns an empty array at first, and then proceeds to fill it due to asynchronous behaviors I don’t fully understand, thus messing with my code. How would I make it so that my function fills the array before outputting it?

Hi,

When you returns branchArray, reading of TTree object is not yet started.
While it done fully assynchronous.
Actual result one obtaines only when selector.Terminate function is called.
Most easy solution - create callback function, which can be invoked there. Like:

function branchToArray(filename, branchName, resultCallback) {
...

selector.Terminate = function(){
   resultCallback(branchArray);
}

}

Regards,
Sergey

Hi Sergey,
Thank you!

So how exactly would I call branchToArray if I only wanted it to return the javascript array? I tried like below, but this is returning undefined due to function scope.

branchToArray('myfile.root', 'mybranch', function(input){return input});

Normally I would just put what I wanted to do with the branch inside the callback function, but I want to be able to plot branches from different trees and even root files against each other, so it’s much more convenient to just have the javascript array sitting around to do stuff to (like transform, push into a TGraph etc)

Hi,

Either you try to code asynchronosely. Like:

var cnt = 0, output = {};
function AddToOutput(name, arr) {
   cnt++;
   output[name] = arr;
   if (cnt == 2) {
      // all data there, do somethng
   }
}

branchToArray('myfile.root', 'mybranch', function(arr1){ AddToOutput("mybranch", arr1); });
branchToArray('myfile2.root', 'mybranch2', function(arr2){ AddToOutput("mybranch2", arr2); });

Or you can try work with Promise, await and async as described here. Final code look simpler, but it could be, that Promise will not work with XMLHttpRequest used in JSROOT - I never tried before.

Regards,
Sergey

Hi Sergey,

I played around with async/await a little. The issue is that even if I can force my function to wait until the array is full before returning it, the rest of my code isn’t quite so patient, and will try to pull the result returned by the array even if it isn’t finished, resulting in ‘undefined’ errors.

Therefore it looks like your other solution to embrace the asynchronous nature of javascript is my solution.

Thank you for your help!