Uploaded image for project: 'ROOT'
  1. ROOT
  2. ROOT-9312

[TTreeReader] "w.v.a" is preferred to "v/a" when reading "v.a"

    XMLWordPrintable

Details

    • Bug
    • Status: Closed (View Workflow)
    • High
    • Resolution: Fixed
    • master
    • None
    • None
    • None
    • any

    Description

      If a TTree contains

      1. a branch "v" with a leaf "a", created with t.Branch("v", &a, "a/I")
      2. a branch "w" containing a split struct that has a datamember "v" with a datamember "a"

      constructing TTreeReaderValue<int>(r, "v.a") attaches the reader to "w.v.a" instead of "v.a". Note that in this scenario there is no way to access "v.a", because constructing TTreeReaderValue<int>(r, "v") attaches to "w.v" (and anyway, if it attached to the top level branch "v", it would yield the following error message:

      Error in <TTreeReaderValueBase::GetBranchDataType()>: The branch v was created using a leaf list and cannot be represented as a C++ type. Please access one of its siblings using a TTreeReaderArray:
      Error in <TTreeReaderValueBase::GetBranchDataType()>:    v.a
      

      The reproducer requires two files:

      // test_read_leaves.h
      struct V {
         int a = 42;
      };
       
      struct W {
         int b;
         V v;
      };
      

      #include <TTree.h>
      #include <TFile.h>
      #include <TTreeReader.h>
      #include <TTreeReaderValue.h>
      #include <TROOT.h>
      #include <iostream>
       
      #include "test_read_leaves.h"
       
      using namespace ROOT::Experimental;
       
      int main()
      {
         // create input file
         {
            TFile f("test_read_leaves.root", "RECREATE");
            TTree t("t", "t");
       
            V v;
            v.a = 1;
            t.Branch("v", &v, "a/I");
       
            // comment these three lines to read the correct value
            gROOT->ProcessLine(".L test_read_leaves.h+");
            W w;
            t.Branch("w", &w);
       
            t.Fill();
            t.Write();
         }
       
         // read "v.a"
         TFile f("test_read_leaves.root");
         TTreeReader r("t", &f);
         TTreeReaderValue<int> rv(r, "v.a");
         r.Next();
         if (*rv == 1)
            std::cout << "v.a was read" << std::endl;
         else if (*rv == 42)
            std::cout << "w.v.a was read" << std::endl;
       
         return 0;
      }
      

      Attachments

        Issue Links

          Activity

            People

              dpiparo Danilo Piparo
              eguiraud Enrico Guiraud
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Actual Start:
                Actual End: