Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/workflows/jsroot-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ jobs:
node demo/node/rntuple_bitset_test.js demo/node/rntuple_bitset_test.root
node demo/node/tree_int64_test.js demo/node/tree_int64_test.root
node demo/node/tree_lzma_test.js demo/node/tree_lzma_test.root
node demo/node/tree_tobject_test.js demo/node/tree_tobject_test.root
node demo/node/tree_draw_range.js demo/node/rntuple_test.root
node demo/node/rntuple_test32.js demo/node/rntuple_test32.root demo/node/rntuple_test32.json

Expand Down Expand Up @@ -192,6 +193,7 @@ jobs:
node demo/node/rntuple_bitset_test.js demo/node/rntuple_bitset_test.root
node demo/node/tree_int64_test.js demo/node/tree_int64_test.root
node demo/node/tree_lzma_test.js demo/node/tree_lzma_test.root
node demo/node/tree_tobject_test.js demo/node/tree_tobject_test.root
node demo/node/tree_draw_range.js demo/node/rntuple_test.root
node demo/node/rntuple_test32.js demo/node/rntuple_test32.root demo/node/rntuple_test32.json

Expand Down Expand Up @@ -249,6 +251,7 @@ jobs:
node demo/node/rntuple_bitset_test.js demo/node/rntuple_bitset_test.root
node demo/node/tree_int64_test.js demo/node/tree_int64_test.root
node demo/node/tree_lzma_test.js demo/node/tree_lzma_test.root
node demo/node/tree_tobject_test.js demo/node/tree_tobject_test.root
node demo/node/tree_draw_range.js demo/node/rntuple_test.root
node demo/node/rntuple_test32.js demo/node/rntuple_test32.root demo/node/rntuple_test32.json

34 changes: 34 additions & 0 deletions demo/node/tree_tobject_test.cxx
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// macro to create tree_tobject_test.root used by tree_tobject_test.js
// root -l -b -q tree_tobject_test.cxx

#include <TFile.h>
#include <TTree.h>
#include <TLorentzVector.h>
#include <TVector3.h>
#include <TGraph.h>
#include <TDatime.h>

void tree_tobject_test()
{
TFile f("tree_tobject_test.root", "RECREATE");

TTree t("t", "Objects with custom streamers");
TLorentzVector *lv = new TLorentzVector;
TVector3 *v3 = new TVector3;
TGraph *gr = new TGraph(3);
TDatime *dt = new TDatime;
// classes with custom streamers are not split by ROOT
t.Branch("lv", &lv);
t.Branch("v3", &v3);
t.Branch("gr", &gr);
t.Branch("dt", &dt);
for (Int_t i = 0; i < 100; ++i) {
lv->SetPxPyPzE(i, 2 * i, 3 * i, 4 * i + 1);
v3->SetXYZ(i, -i, 0.5 * i);
for (Int_t j = 0; j < 3; ++j)
gr->SetPoint(j, j, i + j);
dt->Set(2026, 1, 1, 0, 0, i % 60);
t.Fill();
}
t.Write();
}
65 changes: 65 additions & 0 deletions demo/node/tree_tobject_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
import { version, openFile } from 'jsroot';
import { TSelector, treeProcess } from 'jsroot/tree';

// test reading of objects with custom streamers, file created with tree_tobject_test.cxx

console.log(`JSROOT version ${version}`);

const nentries = 100;

let filename = './tree_tobject_test.root',
any_error = false,
err_cnt = 0;

if (process?.argv && process.argv[2])
filename = process.argv[2];

function failure(msg) {
any_error = true;
if (err_cnt++ < 10)
console.error(`FAILURE: ${msg}`);
}

const file = await openFile(filename),
tree = await file.readObject('t'),
selector = new TSelector();

let cnt = 0;

selector.addBranch('lv');
selector.addBranch('v3');
selector.addBranch('gr');
selector.addBranch('dt');

selector.Process = function() {
const i = cnt++, { lv, v3, gr, dt } = this.tgtobj;

if ((lv?.fP?.fX !== i) || (lv.fP.fY !== 2 * i) || (lv.fP.fZ !== 3 * i) || (lv.fE !== 4 * i + 1))
failure(`entry ${i} wrong TLorentzVector ${JSON.stringify(lv)}`);

if ((v3?.fX !== i) || (v3.fY !== -i) || (v3.fZ !== 0.5 * i))
failure(`entry ${i} wrong TVector3 ${JSON.stringify(v3)}`);

if ((gr?.fNpoints !== 3) || (gr.fX?.[2] !== 2) || (gr.fY?.[2] !== i + 2))
failure(`entry ${i} wrong TGraph npoints ${gr?.fNpoints} x ${gr?.fX?.[2]} y ${gr?.fY?.[2]}`);

// TDatime has no version header, seconds are stored in lower 6 bits
const sec = Number.isInteger(dt?.fDatime) ? dt.fDatime & 0x3f : -1;
if (sec !== i % 60)
failure(`entry ${i} wrong TDatime seconds ${sec}`);
};

try {
await treeProcess(tree, selector);
} catch (err) {
failure(`exception when reading tree: ${err.message}`);
}

if (cnt !== nentries)
failure(`expected ${nentries} tree entries but got ${cnt}`);

if (any_error) {
console.error('\nFAILURE when reading objects with custom streamers');
process.exit(1);
} else
console.log(`OK: tree with ${cnt} entries\n\nTest OK`);
Binary file added demo/node/tree_tobject_test.root
Binary file not shown.
6 changes: 6 additions & 0 deletions modules/tree.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -2142,6 +2142,12 @@ async function treeProcess(tree, selector, args) {
obj[this.name] = res;
}
};
// object written by custom streamer of the class, it has version and bytecount
if (branch.fType === -1) {
member.func = function(buf, obj) {
obj[this.name] = buf.classStreamer({}, this.typename);
};
}
}
}

Expand Down
Loading