TTree does NOT know “int8_t” or “uint8_t” as variables’ “fundamental types”.
It only knows “Char_t” (“signed char”) and “UChar_t” (unsigned char), where “char” is assumed to be 8-bits wide.
BTW. I think, ROOT unconditionally expects that a “char” is a “signed char”.
Error in <TTreeReaderArrayBase::CreateContentProxy()>: The branch Jet_idx contains data of type float. It cannot be accessed by a TTreeReaderArray<signed char>
TTree::Draw does not like it, I suppose it interprets the branch as float:
This is how branches are filled in the CMS NanoAODs, and I don’t think we can easily change that… I was simply looking into replacing the 32-bit integers currently used to store collection sizes, indices, charges, discrete IDs, …, by 8-bit integers, as it seemed like we could gain a few % on disk by doing that (despite compression). However I don’t want people using those files to have to do tricks like Jet_idx+0 when drawing branches… If it’s not possible, so be it, but it’s really unfortunate.
If you define the branch using the “t.Branch("Jet_idx", &(temp.front()), "Jet_idx[nJet]")” syntax then you are again limited to the predefined variables’ “fundamental types”. The default is “Float_t” (i.e., ROOT thinks it’s a "Jet_idx[nJet]/F", so you get the error).
BTW. Why don’t you simply try (no need for the “nJet” at all): auto br = t.Branch("Jet_idx", &temp);
Yes, I know this problem since years ago here.
It’s time you fix it.
The current statement is clear: The leaf referred to by nelem **MUST** be an int (/I)
Or you ask @pcanal and/or @Axel to finally support “unsigned integers” as [nelem] variable-size lengths.
A “std::vector” is by definition “variable-size”, too.
I’m only now learning about this… I’ll put it on the my list. Why is it such a problem if it’s been working fine for years?
Ah yes, OK. That means changing from arrays to STL vectors, this is really a change in the NanoAOD format which would potentially break many things downstream, so it’s not something we would do lightly.
@pcanal and/or @Axel … is there any chance that other types of variables will be supported as [nelem] variable-size lengths (at least “unsigned int”, but maybe also other integer types would be useful in a long run).
Same for the TTreeReader, of course:
Internally, TTree will use the counter as a signed integer independently of what you specified. This could be a problem for very large value of the counter. In particular terms as mentioned by Wile, there are some code path and code pattern that reject or misuse the unsigned integer and some that don’t. So even-though it seems to work in most case, it is better to avoid the mismatch (and unfortunately updating to properly support other type is non-trivial).
Why can’t int8_t be interpreted as a number by default?
Because for a long time, this was the only way to store textual labels (and the TBrowser can not tell what is the semantic of the fields, i.e. label or value ).
This, implicitly, request the branch to be create to hold floats. Since the 2 have the same size, it might still appear to work but the automatic tool will definitively get it wrong (Draw, Browser, etc.)
However I don’t want people using those files to have to do tricks like Jet_idx+0 when drawing branches…
You have 2 potential options. Either use an unsigned char or a signed short (yes, at double the storage cost but automatic tools will work properly and some of the extra storage space will be recovered by compression).
Thanks for the clarifications @pcanal ! We will switch to signed integers for the counters in nanoAOD. Using 16 bit integers instead of 8 bit could be an intereting middle ground indeed, I’ll give it a try.