How to search for a value in ntuple and get the index?

Hi!

As stated in the title I’m looking for a way to extract the index of a specified value from a ntuple. For example:

root [0] TNtuple *test = new TNtuple("test", "Test", "a:b")
(TNtuple *) 0x56218ea17880
root [1] Float_t a,b;
root [2] test->SetBranchAddress("a", &a);
root [3] test->SetBranchAddress("b", &b);
root [4] a = 0;
root [5] b = 1;
root [6] for (Int_t i = 0; i < 10; i++) {
[7]a+=2;
[8]b+=2;
[9]test->Fill(a,b);
[10]}

How do I find the value a=4 or b=5 in the ntuple and get their indexes?


_ROOT Version: 6.14/08
_Platform: gentoo
_Compiler: gcc-7.3.0-r3


Okay, so I found that I can search in the ntuple by using Scan


root [39] test->Scan("a", "a==4")
************************
*    Row   *         a *
************************
*        1 *         4 *
************************
==> 1 selected entry
(long long) 1
root [40] test->Scan("b", "b==5")
************************
*    Row   *         b *
************************
*        1 *         5 *
************************
==> 1 selected entry
(long long) 1
root [41]

Now my problem is extracting the row number (1 for both in this example).
Any suggestions?

Just loop over the ntuple and print out the index of the loop:
for (Int_t i = 0; i < 10; i++) {
test->GetEntry(i);
if (a==4) cout << i << endl;
}

That is a solution, and it would work well for a small ntuple. But, I forgot to write it in the first post, I will need this “search and get index” feature for a bigger code with large ntuples.
With the solution you suggested I would have to loop twice over a ~4400 ntuple inside another loop over ~1500 elements. So I wonder if there is a faster way to achieve my goal using the TTree/TNtuple functions.

See “Saving the result of Draw to a TEventList, a TEntryList or a TEntryListArray” and then " Using a TEventList, TEntryList or TEntryListArray as Input" in the TTree::Draw method description.

Sorry for the late response.
Your suggestion was exactly what I needed, thank you very much!

Now I have another small issue with my code, not completely unrelated to searching in ntuples, but it has more to do with the way ROOT stores the values read from a file.
The file has the following values

390 0.003769647 0.0004146161 0.0184726
390.1 0.003839806 0.0004227277 0.01881624
390.2 0.003911263 0.0004309905 0.01916627
390.3 0.003984042 0.0004394068 0.01952283
390.4 0.004058164 0.0004479791 0.01988602
390.5 0.004133652 0.0004567101 0.02025596
[…]

When I scan the ntuple in which they are imported I get

cie_cmf->Scan()


  • Row * cie_wave * cie_x * cie_y * cie_z *

  •    0 *       390 * 0.0037696 * 0.0004146 * 0.0184726 *
    
  •    1 * 390.10000 * 0.0038398 * 0.0004227 * 0.0188162 *
    
  •    2 * 390.20001 * 0.0039112 * 0.0004309 * 0.0191662 *
    
  •    3 * 390.29998 * 0.0039840 * 0.0004394 * 0.0195228 *
    
  •    4 * 390.39999 * 0.0040581 * 0.0004479 * 0.0198860 *
    
  •    5 *     390.5 * 0.0041336 * 0.0004567 * 0.0202559 *
    

[…]

As you can see the values in the first column are not what is inside my file
The ntuple is defined and filled by the following code

  TNtuple *cie_cmf = new TNtuple("cie_cmf", "cie_cmf", "cie_wave:cie_x:cie_y:cie_z");
  Float_t cie_wave, cie_wave_inter, cie_x, cie_y, cie_z;
  cie_cmf->SetBranchAddress("cie_wave", &cie_wave);
  cie_cmf->SetBranchAddress("cie_x", &cie_x);
  cie_cmf->SetBranchAddress("cie_y", &cie_y);
  cie_cmf->SetBranchAddress("cie_z", &cie_z);

  ifstream cie_file;
  cie_file.open("cie-cmf_2006");
  
  while (1){
    cie_file >> cie_wave >> cie_x >> cie_y >> cie_z;
    if (!cie_file.good()) break;
    cie_cmf->Fill(cie_wave, cie_x, cie_y, cie_z);
  }

Now if I have to search a the value “390.2” from the first column I get nothing.

root [28] cie_cmf->Draw(">>t1", "cie_wave==390.2");
root [29] t1->Print("All")
EventList:t1/cie_wave==390.2, number of entries =0, size=1000

Is there a way to fix this issue?

{
  TTree *cie_cmf = new TTree("cie_cmf", "cie_cmf");
  cie_cmf->ReadFile("cie-cmf_2006", "cie_wave/D:cie_x:cie_y:cie_z"); // "Double_t"
  // cie_cmf->Print();
  cie_cmf->Scan("*", "cie_wave==390.2");
  std::cout << 390.2 - ((Float_t)390.2) << std::endl;
}

Thank you very much again! It worked perfectly.

And happy new year.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.