TEntryList AND

I have two TEntryLists that I can associate with a TTree, and I want to loop over events only if the event (row) is present in both of the TEntryLists. For this purpose void TEntryList::Add(TEntryList*) appears to be a logical OR, whereas I want a logical AND. Does anybody have an idea what the best way to do this is?

Thanks in advance!

According to root.cern.ch/root/htmldoc/TEntryList.html it looks like does an AND if the two lists are from the same tree.

I don’t have a working toy example to demonstrate but the documentation states:

If list A contains events 2, 4, 6, 10 and list B contains 4, 6, 12, 20 then I want the logical AND to return ONLY events 4 and 6 because they are in both A&B.

Thanks,
Ben

I was wrong… reading the doc it does a logical OR, i.e,: It takes all the events in list A and all the events in list B … yes that’s a logical OR indeed …

I apologize for digging up an old thread, but I’m also interested in the functionality described here. Was a solution ever identified?

I’ve written a simple function, but it only works for lists that select in a single TTree, i.e., not TChains.

Thanks,
–Chad

I haven’t found an elegant solution yet, but it sounds like you might have. Would you care to attach your function? Maybe it could be expanded to work on TChains.

As I said, this is a really simple, brute force solution to the problem, and it only seems to work for a single tree.

/*
 * and_entry_lists(TEntryList * l1, TEntryList * l2, TTree * t, 
 *                 const char * name = 0, const char * title = 0)
 * creates a new TEntryList containing only the entries that appear in both 
 * l1 and l2.
 *
 * we have to pass the TTree to associate the list with the tree.
 *
 */
TEntryList * and_entry_lists(TEntryList * l1, TEntryList * l2, TTree * t,
		                       const char * name = 0, const char * title = 0){
	// create the name and title strings for the list to be created
	char nbuf[265], tbuf[256];
	if (name) strncpy(nbuf, name, 256);
	else sprintf(nbuf, "%s_and_%s", l1->GetName(), l2->GetName());
	if (title) strncpy(tbuf, title, 256);
	else sprintf(tbuf, "%s and %s", l1->GetName(), l2->GetName());

	// I don't know if this has any actual effect, but I was getting 
	// strange results so I figured it couldn't hurt.
	t->SetEntryList(0); 
	
	// check the current directory to see if a list with this name already exists
	TEntryList * l; gDirectory->GetObject(nbuf, l);
	if (l) l->Reset(); // if the list already exists, reset it. We're overwriting it.
	else l = new TEntryList(nbuf, tbuf, t); // if not, create a new list
	
	// loop over all of the entries of l1
	for (int i(0); i < l1->GetN(); i++)
		// check if l2 contains the l1 entry with index i
		if (l2->Contains(l1->GetEntry(i),t)) 
			// if l2 contains the entry, add it to the new list.
			l->Enter(l1->GetEntry(i), t);
	return l;
}

I’ve tried another method similar to this, and had similar results. In that method, I cloned l1 and then removed any entry from the clone that is not present in l2.

When these functions operate on TChains, it seems as though they only look at the entries into the first TTree. The first tree’s worth of entries get and-ed, but then it just seems to skip the rest so that the result contains all of the remaining entries in l1 whether they appear in l2 or not. However, looking at the header and source for the TEntryList class, I’m not sure why it doesn’t work. GetN() returns the value of the variable fN, which is always incremented when a new entry is added to the list from any tree, so it should be the total number of entries including entries from all of the associated trees. Supplying a TChain as the second argument to the Contains and Enter functions should make the index relative to the TChain, not a particular TTree in the chain.

(As a side note, I haven’t really tested this theory in great detail. I’ve looked at the number of entries that are in the lists for different trees and done some arithmetic, and it seems about right. I haven’t actually created a minimum example and explicitly verified that this is what is happening.)

The trouble, I think, stems from TEntryList being both a class that contains a list of entries for a TTree, but also a container class for a list of TEntryLists (that are each associated with specific trees) when it is associated with a TChain.

I think that in order to do this properly, one would have to create a function that operates more like the Subtract member function of the TEntryList class (https://root.cern.ch/root/html/src/TEntryList.cxx.html#JrDxj), but this seems to be a lot more effort. The Subtract function searches each list of TEntryLists for TEntryLists that correspond to the same tree, and then operate on those sublists.

I don’t really need a proper solution for my particular problem because both of my lists are derived from the same TChain, so I was really hoping that my quick hack would work.

Any ideas?
–Chad