Skip to content

Feature/add branch code #353

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 22, 2025
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
2 changes: 1 addition & 1 deletion demo/node/rntuple_selector.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { TSelector, openFile } from 'jsroot';
const selector = new TSelector();
selector.sum = 0;
selector.count = 0;

selector.addBranch('myDouble');
selector.Begin = function() {
console.log('Begin processing');
};
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am getting the right result for the file called simple.root .ie
Screenshot 2025-07-21 174725

But when i am checking for the ntuple001_staff.root, I am getting very suspecious result for its fields , i.e very big numbers for field category either i am not using the correct file
Screenshot 2025-07-21 164730

If you have any other root file with the known fields please send me i will check my code for that file too

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Which branch are you querying in ntuple001_staff.root?

Copy link
Collaborator Author

@Krmjn09 Krmjn09 Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Category and age I checked both but values are very large and in the end they are comming to be 0 (some last values)

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe I am using corrupted version of ntuple001_staff.root file

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In theory that file is compressed and the integer values have column type SplitInt, which you cannot deserialize yet; in fact I would expect your program to throw an exception inside deserializePage()...

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Deserializing column with coltype: 19 (0x13)

Getting this value for Category which matches with this in the enum (kUInt32: 0x13),

Something is not going correct

Copy link
Contributor

@silverweed silverweed Jul 21, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

0x13 is actually kSplitInt32 (see table here). I think you assigned the wrong values to the constants.

Edit: I see, you took the values from the enum index in RNTupleUtil.hxx, but that's not the same values that they are encoded with on disk. You need to use the ones in the table above if you want it to work.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok so just enum needs to be changed that can be done easily then ,
Thankyou very much for help

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Changed the constants value and now its working as expected
Below is the result of simple.root working fine and giving mean value
Screenshot 2025-07-21 203133

Next is the result of ntuple001_staff result and throwing the exception successfully
Screenshot 2025-07-21 203138

Then I also tried the code for another root file i created had splitReal value and that too throwing exception as required
Screenshot 2025-07-21 203143

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this pr can be merged @silverweed if you feel its correct and good to go!

Expand Down
104 changes: 65 additions & 39 deletions modules/rntuple.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -111,39 +111,39 @@ class RBufferReader {
}

const ENTupleColumnType = {
kUnknown: 0x00,
kIndex64: 0x01,
kIndex32: 0x02,
kSwitch: 0x03,
kByte: 0x04,
kChar: 0x05,
kBit: 0x06,
kBit: 0x00,
kByte: 0x01,
kChar: 0x02,
kInt8: 0x03,
kUInt8: 0x04,
kInt16: 0x05,
kUInt16: 0x06,
kInt32: 0x07,
kUInt32: 0x08,
kInt64: 0x09,
kUInt64: 0x0A,
kReal16: 0x0B,
kReal32: 0x0C,
kReal64: 0x0D,
kReal32: 0x0E,
kReal16: 0x0F,
kInt64: 0x10,
kUInt64: 0x11,
kInt32: 0x12,
kUInt32: 0x13,
kInt16: 0x14,
kUInt16: 0x15,
kInt8: 0x16,
kUInt8: 0x17,
kSplitIndex64: 0x18,
kSplitIndex32: 0x19,
kSplitReal64: 0x1A,
kSplitReal32: 0x1B,
kSplitInt64: 0x1C,
kSplitUInt64: 0x1D,
kSplitInt32: 0x1E,
kSplitUInt32: 0x1F,
kSplitInt16: 0x20,
kSplitUInt16: 0x21,
kReal32Trunc: 0x22,
kReal32Quant: 0x23,
kMax: 0x24
kIndex32: 0x0E,
kIndex64: 0x0F,
kSwitch: 0x10,
kSplitInt16: 0x11,
kSplitUInt16: 0x12,
kSplitInt32: 0x13,
kSplitUInt32: 0x14,
kSplitInt64: 0x15,
kSplitUInt64: 0x16,
kSplitReal16: 0x17,
kSplitReal32: 0x18,
kSplitReal64: 0x19,
kSplitIndex32: 0x1A,
kSplitIndex64: 0x1B,
kReal32Trunc: 0x1C,
kReal32Quant: 0x1D
};


// Determine byte size per value based on column type
function getTypeByteSize(coltype) {
switch (coltype) {
Expand All @@ -163,7 +163,7 @@ function getTypeByteSize(coltype) {
case ENTupleColumnType.kByte:
return 1;
default:
throw new Error(`Unsupported coltype for byte size: ${coltype}`);
throw new Error(`Unsupported coltype for byte size: ${coltype} (0x${coltype.toString(16).padStart(2, '0')})`);
}
}

Expand Down Expand Up @@ -724,19 +724,40 @@ function readNextCluster(rntuple, selector) {
clusterIndex = selector.currentCluster,
clusterSummary = builder.clusterSummaries[clusterIndex],

// Gather all pages for this cluster from all columns
pages = [];
// Gather all pages for this cluster from selected fields only
pages = [],

// Collect only selected field names from selector
selectedFields = [];
for (let i = 0; i < selector.numBranches(); ++i)
selectedFields.push(selector.nameOfBranch(i));

// For each selected field, collect its columns' pages
for (const fieldName of selectedFields) {
const columns = rntuple.fieldToColumns[fieldName];
if (!columns)
throw new Error(`Selected field '${fieldName}' not found in RNTuple`);

for (const columns of Object.values(rntuple.fieldToColumns)) {
for (const colDesc of columns) {
const colPages = builder.pageLocations[clusterIndex][colDesc.index].pages;
for (const page of colPages)
const colEntry = builder.pageLocations[clusterIndex]?.[colDesc.index];

// When the data is missing or broken
if (!colEntry || !colEntry.pages)
throw new Error(`No pages for column ${colDesc.index} in cluster ${clusterIndex}`);

for (const page of colEntry.pages)
pages.push({ page, colDesc });
}
}

selector.currentCluster++;

// Early exit if no pages to read (i.e., no selected fields matched)
if (pages.length === 0) {
selector.Terminate();
return Promise.resolve();
}

// Build flat array of [offset, size, offset, size, ...] to read pages
const dataToRead = pages.flatMap(p =>
[Number(p.page.locator.offset), Number(p.page.locator.size)]
Expand All @@ -759,8 +780,8 @@ function readNextCluster(rntuple, selector) {
colDesc
} = pages[i],
field = builder.fieldDescriptors[colDesc.fieldId],
values = rntuple.builder.deserializePage(unzipBlobs[i], colDesc, field);
values = builder.deserializePage(unzipBlobs[i], colDesc, field);

// TODO: Handle fields with multiple columns (e.g., data + metadata).
// For now, we only store the first column's data to avoid overwriting.
if (!rntuple._clusterData[field.fieldName])
Expand All @@ -769,8 +790,13 @@ function readNextCluster(rntuple, selector) {

const numEntries = clusterSummary.numEntries;
for (let i = 0; i < numEntries; ++i) {
for (const [fieldName, values] of Object.entries(rntuple._clusterData))
for (let b = 0; b < selector.numBranches(); ++b) {
const fieldName = selector.nameOfBranch(b),
values = rntuple._clusterData[fieldName];
if (!values)
throw new Error(`Missing values for selected field: ${fieldName}`);
selector.tgtobj[fieldName] = values[i];
}
selector.Process();
}

Expand Down
Loading