Faster than looping TGraph?

I have a piece of code that works reliably, but tremendously slowly. I am updating a graph reading new values for the array (that do not have a fixed size). Something like:

TCanvas *canv = new TCanvas("canv","Pulse processing",200,10,800,560);
canv->SetFillColor(42);
canv->SetGrid();
canv->Divide(2,1);

for (i=0;i<n_times;i++)
  {
  win_len=length[i];
  t_win = new double [win_len];
  x_win = new double [win_len];
  for (jt=0;jt<win_len;jt++)
    {
    t_win[jt]=jt;
    x_win[jt]=data[jt];
    }
    if (switch==0)
      {
      TGraph *g1 = new TGraph(win_len,t_win,x_win);
      canv->cd(1);
      g1->SetTitle("Graph 1");
      g1->SetLineColor(kRed);
      g1->SetLineWidth(2);
      g1->Draw("AL");
      }
    if (switch==1)
      {
      TGraph *g2 = new TGraph(win_len,t_win,x_win);
      canv->cd(2);
      g2->SetTitle("Graph 2");
      g2->SetLineColor(kBlue);
      g2->SetLineWidth(2);
      g2->Draw("AL");
      }
  }

I’d need to speed that up by a factor 10 or more, any suggestions?

Thank you in advance
Giovanni

Hi,

Compile it with AClic:

.L myCode.C+
myCode()

Cheers,
Charles

I should have mentioned: I am not using ROOT as interpreter, I compile the code with this Makefile:

include $(ROOTSYS)/test/Makefile.arch

SRCS    := myCode.$(SrcSuf) myCodeDict.$(SrcSuf)
OBJS    := $(SRCS:.$(SrcSuf)=.$(ObjSuf)) myCodeDict.$(ObjSuf)
EXE      = MYCODE$(ExeSuf)

PROGRAMS      = $(EXE)

.SUFFIXES: .$(SrcSuf) .$(ObjSuf)

all:        $(PROGRAMS)

$(EXE):  $(OBJS)
        $(LD) $(LDFLAGS) $^ $(ROOTGLIBS) $(OutPutOpt)$@
        @echo "$@ done"

myCodeDict.cxx: myCode.h LinkDef.h
                @echo "Generating dictionary $@..."
                @rootcint -f $@ -c $^

clean:
                rm -f *.o *.d *Dict.*

.$(SrcSuf).$(ObjSuf):
        $(CXX) $(CXXFLAGS) $(EXTRAFLAGS) -c $<

Maybe I can update the plots in a faster way than redefining the TGraph?
Thanks
Giovanni

Hi,

Did you try:[code]TCanvas *canv = new TCanvas(“canv”,“Pulse processing”,200,10,800,560);
canv->SetFillColor(42);
canv->SetGrid();
canv->Divide(2,1);

TGraph *g1 = 0;
TGraph *g2 = 0;
for (i=0;i<n_times;i++) {
win_len=length[i];
if (i==0) {
if (switch==0) {
g1 = new TGraph(win_len);
canv->cd(1);
g1->SetTitle(“Graph 1”);
g1->SetLineColor(kRed);
g1->SetLineWidth(2);
g1->Draw(“AL”);
} else if (switch==1) {
g2 = new TGraph(win_len);
canv->cd(2);
g2->SetTitle(“Graph 2”);
g2->SetLineColor(kBlue);
g2->SetLineWidth(2);
g2->Draw(“AL”);
}
} else {
if (switch==0) {
g1->Set(win_len);
} else if (switch==1) {
g2->Set(win_len);
}
}
if (switch==0) {
for (jt=0;jt<win_len;jt++) {
g1->SetPoint(jt,jt,data[jt])
}
} else if (switch==0) {
for (jt=0;jt<win_len;jt++) {
g2->SetPoint(jt,jt,data[jt])
}
}
canv->Modified();
canv->Update();
}[/code]

Cheers,
Philippe

Thank you, your method is interesting and it works, but it is as slow as mine.
I’d need a factor 10 in speed in order to be competitive with labview in that respect - for all the rest, ROOT is way better!

[quote=“gtardini”]Thank you, your method is interesting and it works, but it is as slow as mine.
I’d need a factor 10 in speed in order to be competitive with labview in that respect - for all the rest, ROOT is way better![/quote]

Just one quick question: You are running in batch mode, right? If not, that could be your order of magnitude right there…

Good luck! Charles

Sounds interesting, but… what do you mean by batch mode? I want plots, updated in time (sort of “animation”). For the calculation only, the program is already MUCH faster than I could dream of.
If you simply mean “not in intepreter mode”, than yes, it is already the case.

last_len = i == 0 : 0 ? length[i-1];
win_len=length[i];

if (switch==0) {
for (jt=last_len;jt<win_len;jt++) {
g1->SetPoint(jt,jt,data[jt])
}
} else if (switch==0) {
for (jt=last_len;jt<win_len;jt++) {
g2->SetPoint(jt,jt,data[jt])
}
}[/code]If this does not help … then there is something essential about what you are trying to do (and/or what you are doing with labview) that I am missing …

Cheers,
Philippe.

ROOT does plot fast, but I’d need it ultra-fast: it does 15000 updates in less than 5 minutes, so more than 50 plots per second, each plot being on a 40-50 points (variable) x-grid. Unfortunately I have cases with ~1e6 plots to be done and I cannot afford to wait 5 hours.
I have not the labview source, just the executable.

[quote=“gtardini”]Sounds interesting, but… what do you mean by batch mode? I want plots, updated in time (sort of “animation”). For the calculation only, the program is already MUCH faster than I could dream of.
If you simply mean “not in intepreter mode”, than yes, it is already the case.[/quote]

When you run, is it popping up the individual plots in (X) windows? If so, that’s what slowing you down. If you can figure out a way to have Root just make the plots and view them when they’re done, the execution time is usually MUCH shorter.

All of this being said, explaining exactly what you are trying to do and how it works better for you in MatLab instead of Root as Phillipe suggests is going to get you the best mileage.

Cheers,
Charles

[quote]. Unfortunately I have cases with ~1e6 plots to be done and I cannot afford to wait 5 hours.[/quote]Humm … so the difference is probably in the handling of large graphs … If you limit the plotting to only the graphs that are less than 1000 points (or less than 200, etc.), is the performance now reaching what you need (yes, I realize this is not completely what you are looking for but this would tell us where the problem is).

Cheers,
Philippe.

There is a canvas which gets updated, so not every update produces a new X-window.
My plots are all of the same size (roughly f(x) with 40-50 x-grid points). I simply have to produce 1e6 plots, i.e. in my piece of code, n_times=1e6.
I think this is a question of rather general interest, how to get a fast animation in root.

[quote=“gtardini”]There is a canvas which gets updated, so not every update produces a new X-window.
My plots are all of the same size (roughly f(x) with 40-50 x-grid points). I simply have to produce 1e6 plots, i.e. in my piece of code, n_times=1e6.
I think this is a question of rather general interest, how to get a fast animation in root.[/quote]

Even with only 1 canvas, actually drawing the plot on the screen slows things down considerably. If you’re really producing 1e6 plots, you clearly can’t see them all anyway (I do get the “animation” effect however). Changing your code around so that it only displays a fraction of the plots it makes should really speed things up.

ok so there’s basically no solution. I know, for most applications 50 plot/s is actually fast. Sampling down the amount of plots is certainly an option.

Hi,

I actually tried the code I sketched above and on my local station (physically attached to the screen) I get 83 (simple) graphs per second with graph having between 50 to 60 points. If I run on a remote node this number goes down 16 per seconds. So you might be encountering more of a limitation of the X11 protocol than ROOTs’ graph itself (i.e. being victim to latency).

Also could it make sense to skip the drawing of a fraction of the graphs in order to go through all of them in the required time?

Philippe.