Help with TObjArray sorting

Hi,

I have a TObjArray of objects I have created, but I can’t get them to sort even though IsSortable is set. Can someone see why this won’t work?

[code]#include <TROOT.h>
#include <Rtypes.h>
#include <TObject.h>
#include <TObjArray.h>

class EventCat: public TObject
{

public:
Int_t date;
Int_t time;
Double_t energy;

EventCat();
Int_t Compare(const TObject *obj) const;
void Dump() const;
Bool_t IsEqual(const TObject *obj) const
  {return TMath::Abs(energy - ((EventCat*)obj)->energy) < 1.e-6;}
Bool_t IsSortable() const {return kTRUE;}

};

EventCat::EventCat()
{
date = 0;
time = 0;
energy = 0.;
}

Int_t EventCat::Compare(const TObject *obj) const
{
EventCat ec = (EventCat)obj;
if (ec->energy < energy)
return -1;
else if (ec->energy > energy)
return 1;
else
return 0;
}

void EventCat::Dump() const
{
cout << date << " " << time << " " << energy << endl;
}

void dataCatalog()
{

TObjArray shwaEvent(3);
EventCat *cat1 = new EventCat();
EventCat *cat2 = new EventCat();
EventCat *cat3 = new EventCat();

cat1->date = 19991201;
cat1->time = 100;
cat1->energy = 1.e19;

cout << "sortable: " << cat1->IsSortable() << endl;

cat2->date = 20060101;
cat2->time = 600;
cat2->energy = 31.e20;

cat3->date = 19991202;
cat3->time = 55;
cat3->energy = 2.e19;

cout << "cat3->Compare(cat1) " << cat3->Compare(cat1) << endl;
cout << "cat3->Compare(cat2) " << cat3->Compare(cat2) << endl;
cout << "cat3->Compare(cat3) " << cat3->Compare(cat3) << endl;
cout << "cat1->Compare(cat3) " << cat1->Compare(cat3) << endl;

shwaEvent.Add(cat1);
shwaEvent.Add(cat2);
shwaEvent.Add(cat3);

for (Int_t i = 0; i < shwaEvent.GetEntriesFast(); i++)
{
EventCat c;
cout << "i: " << i << ": ";
c = (EventCat
)shwaEvent.At(i);
c->Dump();
Bool_t g = c->IsSortable();
cout << "isSortable: " << g << endl;
}

cout << “Now sort” << endl;
shwaEvent.Sort();

for (Int_t i = 0; i < shwaEvent.GetEntriesFast(); i++)
{
EventCat c;
cout << "i: " << i << ": ";
c = (EventCat
)shwaEvent.At(i);
c->Dump();
}

}[/code]

Here’s the output:

sortable: 1
cat3->Compare(cat1) -1
cat3->Compare(cat2) 1
cat3->Compare(cat3) 0
cat1->Compare(cat3) 1
i: 0: 19991201 100 1e+19
isSortable: 1
i: 1: 20060101 600 3.1e+21
isSortable: 1
i: 2: 19991202 55 2e+19
isSortable: 1
Now sort
Error in TObjArray::Sort: objects in array are not sortable
i: 0: 19991201 100 1e+19
i: 1: 20060101 600 3.1e+21
i: 2: 19991202 55 2e+19

Simple build a shared library with ACLiC (and slightly modify your code).

[code]#include // add
#include <TROOT.h>


Bool_t IsSortable() const {return kTRUE;}
ClassDef(EventCat, 1) // add
};

[/code][quote]root [0] .L dataCatalog.C+
Info in TUnixSystem::ACLiC: creating shared library /home/mucha/./dataCatalog_C.so
root [1] dataCatalog()
sortable: 1
cat3->Compare(cat1) -1
cat3->Compare(cat2) 1
cat3->Compare(cat3) 0
cat1->Compare(cat3) 1
i: 0: 19991201 100 1e+19
isSortable: 1
i: 1: 20060101 600 3.1e+21
isSortable: 1
i: 2: 19991202 55 2e+19
isSortable: 1
Now sort
i: 0: 20060101 600 3.1e+21
i: 1: 19991202 55 2e+19
i: 2: 19991201 100 1e+19
root [2] [/quote]
I hope this help, Jan

Hi,

Jan is correct. You must compile. This is due to the fact that an interpret class can not overload virtual function of a compiled class in a way that these overload are actually seen by C++ compiled code (aka the Sort function being compiled in C++ can not see your interpret sorting code).

Cheers,
Philippe

Excellent. That works. Thank you very much.