diff --git a/demo/node/rntuple_selector.js b/demo/node/rntuple_selector.js index 0d9caa8fb..c7a1d3d1b 100644 --- a/demo/node/rntuple_selector.js +++ b/demo/node/rntuple_selector.js @@ -5,8 +5,18 @@ import { TSelector } from '../../modules/tree.mjs'; const selector = new TSelector(); selector.sum = 0; selector.count = 0; -selector.addBranch('Nation'); +selector.addBranch('Category'); +selector.addBranch('Flag'); +selector.addBranch('Age'); +selector.addBranch('Service'); +selector.addBranch('Children'); +selector.addBranch('Grade'); selector.addBranch('Step'); +selector.addBranch('Hrweek'); +selector.addBranch('Cost'); +selector.addBranch('Division'); +selector.addBranch('Nation'); + selector.Begin = function() { console.log('Begin processing'); }; @@ -23,7 +33,7 @@ selector.Terminate = function() { }; if (typeof window === 'undefined') { - openFile('./ntpl001_staff.root') + openFile('https://jsroot.gsi.de/files/tmp/ntpl001_staff.root') .then(file => file.readObject('Staff')) .then(rntuple => { if (!rntuple) throw new Error('myNtuple not found'); diff --git a/modules/rntuple.mjs b/modules/rntuple.mjs index 3584ad6ca..87b0d9f87 100644 --- a/modules/rntuple.mjs +++ b/modules/rntuple.mjs @@ -200,7 +200,10 @@ function recontructUnsplitBuffer(blob, columnDescriptor) { coltype === ENTupleColumnType.kSplitReal32 || coltype === ENTupleColumnType.kSplitReal64 || coltype === ENTupleColumnType.kSplitIndex32 || - coltype === ENTupleColumnType.kSplitIndex64 + coltype === ENTupleColumnType.kSplitIndex64 || + coltype === ENTupleColumnType.kSplitInt16 || + coltype === ENTupleColumnType.kSplitInt32 || + coltype === ENTupleColumnType.kSplitInt64 ) { const byteSize = getTypeByteSize(coltype), splitView = new DataView(blob.buffer, blob.byteOffset, blob.byteLength), @@ -245,6 +248,15 @@ function recontructUnsplitBuffer(blob, columnDescriptor) { case ENTupleColumnType.kSplitReal64: newColtype = ENTupleColumnType.kReal64; break; + case ENTupleColumnType.kSplitInt16: + newColtype = ENTupleColumnType.kInt16; + break; + case ENTupleColumnType.kSplitInt32: + newColtype = ENTupleColumnType.kInt32; + break; + case ENTupleColumnType.kSplitInt64: + newColtype = ENTupleColumnType.kInt64; + break; default: throw new Error(`Unsupported split coltype for reassembly: ${coltype}`); } @@ -279,6 +291,32 @@ function DecodeDeltaIndex(blob, coltype) { return { blob: result, coltype }; } +/** + * @summary Decode a reconstructed signed integer buffer using ZigZag encoding + */ +function DecodeZigZag(blob, coltype) { + let zigzag, result; + + if (coltype === ENTupleColumnType.kInt16) { + zigzag = new Uint16Array(blob.buffer || blob, blob.byteOffset || 0, blob.byteLength / 2); + result = new Int16Array(zigzag.length); + } else if (coltype === ENTupleColumnType.kInt32) { + zigzag = new Uint32Array(blob.buffer || blob, blob.byteOffset || 0, blob.byteLength / 4); + result = new Int32Array(zigzag.length); + } else if (coltype === ENTupleColumnType.kInt64) { + zigzag = new BigUint64Array(blob.buffer || blob, blob.byteOffset || 0, blob.byteLength / 8); + result = new BigInt64Array(zigzag.length); + } else + throw new Error(`DecodeZigZag: unsupported column type ${coltype}`); + + for (let i = 0; i < zigzag.length; ++i) { + // ZigZag decode: (x >>> 1) ^ (-(x & 1)) + const x = zigzag[i]; + result[i] = (x >>> 1) ^ (-(x & 1)); + } + + return { blob: result, coltype }; +} // Envelope Types // TODO: Define usage logic for envelope types in future @@ -722,6 +760,12 @@ class RNTupleDescriptorBuilder { processedBlob = decodedArray; } + // Handle Split Signed Int types + if (originalColtype === ENTupleColumnType.kSplitInt16 || originalColtype === ENTupleColumnType.kSplitInt32 || originalColtype === ENTupleColumnType.kSplitInt64) { + const { blob: decodedArray } = DecodeZigZag(processedBlob, coltype); + processedBlob = decodedArray; + } + const byteSize = getTypeByteSize(coltype), reader = new RBufferReader(processedBlob), values = [];