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
1 change: 1 addition & 0 deletions changes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@


## Changes in dev
1. Support std::vector in `RNtuple`
1. Resort order of ranges in http request, fixing several long-standing problems #374
1. Implement for `TPie` 3d, text, title drawing including interactivity
1. Implement `TCanvas` support in `build3d` function #373
Expand Down
8 changes: 5 additions & 3 deletions modules/draw/RNTuple.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ async function drawRNTuple(dom, obj, opt) {
const args = {};
let tuple;

if (obj?.$tuple) {
if (obj?.$tuple && obj.$field) {
// case of fictional ROOT::RNTupleField
tuple = obj.$tuple;
args.expr = obj._name;
if (isStr(opt) && opt.indexOf('dump') === 0)
if (isStr(opt) && opt.indexOf('dump') === 0) {
args.expr += '>>' + opt;
else if (opt)
args.branch = obj.$field;
args.copy_fields = false; // no need to copy fields, reading is simple
} else if (opt)
args.expr += opt;
} else {
tuple = obj;
Expand Down
103 changes: 86 additions & 17 deletions modules/rntuple.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -851,9 +851,20 @@ class RNTupleDescriptorBuilder {
}
}

/** @summary Return all childs of specified field */
findChildFields(field) {
const indx = this.fieldDescriptors.indexOf(field), res = [];
for (let n = 0; n < this.fieldDescriptors.length; ++n) {
const fld = this.fieldDescriptors[n];
if ((fld !== field) && (fld.parentFieldId === indx))
res.push(fld);
}
return res;
}

/** @summary Return array of columns for specified field */
findColumns(name) {
const res = [], field = this.findField(name);
findColumns(field) {
const res = [];
if (!field)
return res;
for (const colDesc of this.columnDescriptors) {
Expand All @@ -863,6 +874,7 @@ class RNTupleDescriptorBuilder {
return res;
}


} // class RNTupleDescriptorBuilder


Expand Down Expand Up @@ -1105,6 +1117,7 @@ class ReaderItem {
/** @summary identify if this item used as offset for std::string or similar */
is_offset_item() { return this.item1; }

/** @summary implements reading of std::string where item1 provides offsets */
assignStringReader(item1) {
this.item1 = item1;
this.off0 = 0;
Expand All @@ -1130,14 +1143,52 @@ class ReaderItem {

this.shift = function(entries) {
if (entries > 0) {
this.item1.shift0(entries);
this.item1.shift0(entries - 1);
this.item1.func0(this.$tgt);
this.off0 = Number(this.$tgt[this.name]);
this.shift_o(this.off0);
}
};
}

/** @summary implement reading of std::vector where item1 provides elements numbers */
assignVectorReader(item1) {
this.item1 = item1;
this.off0 = 0;
this.$tgt = {};

item1.func0 = item1.func;
item1.shift0 = item1.shift;
// assign noop
item1.func = item1.shift = () => {};

// remember own read function - they need to be used
this.func0 = this.func;
this.shift0 = this.shift;

this.func = function(tgtobj) {
this.item1.func0(this.$tgt);
const off = Number(this.$tgt[this.name]);
let len = off - this.off0;
const arr = [], tmp = {};
while (len-- > 0) {
this.func0(tmp);
arr.push(tmp[this.name]);
}
tgtobj[this.name] = arr;
this.off0 = off;
};

this.shift = function(entries) {
if (entries > 0) {
this.item1.shift0(entries - 1);
this.item1.func0(this.$tgt);
this.off0 = Number(this.$tgt[this.name]);
this.shift0(this.off0);
}
};
}

collectPages(cluster_locations, dataToRead, itemsToRead, pagesToRead, emin, emax, elist) {
const pages = cluster_locations[this.id].pages;

Expand Down Expand Up @@ -1304,29 +1355,47 @@ async function rntupleProcess(rntuple, selector, args = {}) {
});
}

function addFieldReading(field, tgtname) {
const columns = rntuple.builder.findColumns(field);
if (!columns?.length)
throw new Error(`No columns found for field '${field.fieldName}' in RNTuple`);

let item = new ReaderItem(columns[0], tgtname);
item.assignReadFunc();
handle.arr.push(item);

if ((columns.length === 2) && (field.typeName === 'std::string')) {
const item2 = new ReaderItem(columns[1], tgtname);
item2.assignStringReader(item);
handle.arr.push(item2);
item = item2; // second item performs complete reading of the string
}

const childs = rntuple.builder.findChildFields(field);
if ((childs.length === 1) && (field.typeName.indexOf('std::vector') === 0)) {
const item2 = addFieldReading(childs[0], tgtname);
item2.assignVectorReader(item);
item = item2; // second item makes actual reading of vector
}

return item;
}

return readHeaderFooter(rntuple).then(res => {
if (!res)
throw new Error('Not able to read header for the RNtuple');

for (let i = 0; i < selector.numBranches(); ++i) {
const name = getSelectorFieldName(selector, i);
const name = getSelectorFieldName(selector, i),
tgtname = selector.nameOfBranch(i);
if (!name)
throw new Error(`Not able to extract name for field ${i}`);

const columns = rntuple.builder.findColumns(name);
if (!columns?.length)
throw new Error(`No columns found for field '${name}' in RNTuple`);
const field = rntuple.builder.findField(name);
if (!field)
throw new Error(`Field ${name} not found`);

const tgtname = selector.nameOfBranch(i),
item = new ReaderItem(columns[0], tgtname);
item.assignReadFunc();
handle.arr.push(item);

if (columns.length === 2) {
const item2 = new ReaderItem(columns[1], tgtname);
item2.assignStringReader(item);
handle.arr.push(item2);
}
addFieldReading(field, tgtname);
}

// calculate number of entries
Expand Down
2 changes: 1 addition & 1 deletion modules/tree.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -1128,7 +1128,7 @@ class TDrawSelector extends TSelector {
this.leaf = args.leaf;

// branch object remains, therefore we need to copy fields to see them all
this.copy_fields = ((args.branch.fLeaves?.arr.length > 1) || args.branch.fBranches?.arr.length) && !args.leaf;
this.copy_fields = args.copy_fields ?? (((args.branch.fLeaves?.arr.length > 1) || args.branch.fBranches?.arr.length) && !args.leaf);

this.addBranch(branch, 'br0', args.direct_branch); // add branch

Expand Down