Sorting ntuple by branch values

Dear ROOTers,

I have ntuples containing information about a particle detector event, with branches for x,y,z postion, energy etc. and I’d like to sort it in ascending order according to the branch “time”.
How do I go about doing that?
I’ve tried reading guides for TTrees but I can’t seem to apply it to my code.

Below is my attempt that doesnt work:

void sort() {

	Int_t nentries = (Int_t)ntuple->GetEntries();

	ntuple->Draw("time","","goff");
	Int_t *index = new Int_t[nentries];

	TMath::Sort(nentries,ntuple->GetV1(),index);
	TNtuple *sorted = (TNtuple*)ntuple->CloneTree(0);
	for (Int_t i=0;i<nentries;i++) {
		ntuple->GetEntry(index[i]);
		sorted->Fill();
	}
	sorted->Write();
	delete [] index;
  }
 sorted->Print();
}

Thanks! :slight_smile:

Hi,

this can be achieved with RDataFrame and VecOps:

   // Create dataframe with two columns
   int idx = 0;
   auto rdf = ROOT::RDataFrame(64);
   auto rdfwcols = rdf.Define("c0", [](){return gRandom->Uniform();})
                      .Define("c1", [&idx](){return idx++;});

   // Extract columns
   auto c0rs = rdfwcols.Take<double, ROOT::RVec<double>>("c0");
   auto c1rs = rdfwcols.Take<int, ROOT::RVec<int>>("c1");

   auto c0 = *c0rs;
   auto c1 = *c1rs;

   // Get the RVec of indices which sorts c0
   auto c0idxs = Argsort(c0);

   // Print c1 content in order
   for (auto idx : c0idxs) {
      cout << c1[idx] << " -  c0 value is " << c0[idx] << endl;
   }

a possible output is:

1 -  c0 value is 0.16291
15 -  c0 value is 0.168572
4 -  c0 value is 0.231657
2 -  c0 value is 0.282618
12 -  c0 value is 0.315638
5 -  c0 value is 0.484974
14 -  c0 value is 0.519672
8 -  c0 value is 0.540044
11 -  c0 value is 0.658637
9 -  c0 value is 0.739953
7 -  c0 value is 0.744305
10 -  c0 value is 0.759944
13 -  c0 value is 0.804403
3 -  c0 value is 0.947201
6 -  c0 value is 0.957477
0 -  c0 value is 0.999742

I hope this helps.

Cheers,
D

Note for this:

	Int_t nentries = (Int_t)ntuple->GetEntries();

	ntuple->Draw("time","","goff");
	Int_t *index = new Int_t[nentries];

	TMath::Sort(nentries,ntuple->GetV1(),index);

to work you need to also do (first)

  ntuple->SetEstimate(nentries);

other GetV1() contains only a subset of the entries.