Problems of TSelector with std::vectors

Hi,

developing my own code I found two “strange” behavior of TSelector.

I’m using ROOT 5.21/05 (trunk@26187, Nov 14 2008, 11:39:28 on linux)

It seems to me that TSelector loop over entries of std::vectors and it relates those at the same position in the vector.

Would it be better if vectors entries were not related to each others? In principle vectors in different branches are different collections of not-related values.

I provide an example here:

I have “muonPt” and “channels” and “missingEt” stored in std::vectors in branches.

muon and missingEt are stored in ROOT.std::vector, while channels in ROOT.std::vectorROOT.std::string.

I know that in the event 32 I have 2 muons and that the event has been marked as “m” (for “muon”).

If I do:

SUSYTree->Scan("muonPt")

I get for the event 32:

*************************************
*    Row   * Instance *    muonPt
*************************************
....
*       32 *        0 * 118.02722 *
*       32 *        1 * 29.424480 *
....

Hence I get my 2 muons.

But if I add this selection:

SUSYTree->Scan("muonPt:channels","channels==\"m\"")
***********************************************
*    Row   * Instance *    muonPt *  channels *
***********************************************
*        0 *        0 *  31.84408 *         m *
*        4 *        0 * 22.013584 *         m *
*       14 *        0 * 257.73138 *         m *
*       21 *        0 * 82.784736 *         m *
*       22 *        0 * 121.78731 *         m *
*       23 *        0 * 164.72784 *         m *
*       32 *        0 * 118.02722 *         m *
*       45 *        0 * 11.715974 *         m *
*       50 *        0 * 66.464714 *         m *

As you see for the same event 32, I get only the muon in the position (0) of the vector, because it’s in the same position of the ‘m’ in the ‘channels’ vector.
In fact if I plot only ‘channels’ I get this:

SUSYTree->Scan("channels")
***********************************
*    Row   * Instance *  channels *
***********************************
*       32 *        0 *         m *
*       32 *        1 *         e *

I can get the right result only doing this:

SUSYTree->Scan("muonPt:channels","@channels.at(0)==\"m\"")
***********************************************
*    Row   * Instance *    muonPt *  channels *
***********************************************
*        0 *        0 *  31.84408 *         m *
*        0 *        1 *           *      jjjj *
*        0 *        2 *           *       jjj *
*        4 *        0 * 22.013584 *         m *
*       14 *        0 * 257.73138 *         m *
*       21 *        0 * 82.784736 *         m *
*       21 *        1 * 37.393188 *        jj *
*       21 *        2 *           *       jjj *
*       22 *        0 * 121.78731 *         m *
*       22 *        1 * 16.788520 *       jjj *
*       23 *        0 * 164.72784 *         m *
*       32 *        0 * 118.02722 *         m *
*       32 *        1 * 29.424480 *         e *
.....

But in principle I could not know at which vector position the value I want it’s stored.

I have the same relation between vector entries if I use std::vector< float >, for example for missingEt; but in this case the solution I found for “strings” does not work, as shown below. I have to use the operator [] like for arrays:

SUSYTree->Scan("muonPt:metEt","metEt>10")
***********************************************
*    Row   * Instance *    muonPt *     metEt *
***********************************************
*        0 *        0 *  31.84408 * 53.592227 *
*        4 *        0 * 22.013584 * 19.632848 *
*       14 *        0 * 257.73138 * 367.09536 *
*       21 *        0 * 82.784736 * 170.56951 *
*       22 *        0 * 121.78731 * 455.43817 *
*       23 *        0 * 164.72784 * 499.25253 *
*       32 *        0 * 118.02722 * 234.44812 *
*       45 *        0 * 11.715974 * 143.87825 *


SUSYTree->Scan("muonPt:metEt","@metEt.at(0)>10")
***********************************************
*    Row   * Instance *    muonPt *     metEt *
***********************************************
***********************************************
==> 0 selected entries
(Long64_t)0



SUSYTree->Scan("muonPt:metEt","metEt[0] > 10")
***********************************************
*    Row   * Instance *    muonPt *     metEt *
***********************************************
.....
*       32 *        0 * 118.02722 * 234.44812 *
*       32 *        1 * 29.424480 *           *
*       33 *        0 *           * 228.68380 *
.....

So there is a different in the behavior of TSelector (I guess) if values are stored in a vector or vector.

Thanks for your help,

and have a nice day,

Ric.

P.S. I wanted to report this on savannah but I did not know which part of ROOT TSelector belongs to. Maybe “Core libs”?

Hi,

[quote]It seems to me that TSelector loop over entries of std::vectors and it relates those at the same position in the vector[/quote]This is the intended behavior. Note that TSelector is a generic framework that allow any analysis, the part of ROOT that you are using here is ‘using’ a TSelector but introduce additional feature and restriction; For the detailed documentation see the reference guide for TTree:Scan and TTree::Draw.

So in your case you should try:SUSYTree->Scan("muonPt:channels","Sum$(channels==\"m\")");

Cheers,
Philippe.

Thank you very much Philippe for your clear explanation and suggestions :slight_smile:

Indeed I did not think about the use-case you pointed out, it’s my fault. Thanks for that as well. And you are right, the use-case with the three vectors related is a very common use-case, indeed.

Thanks a lot,

Ric.