Re: [ROOT] ROOT & Qt, Swing, GUIs, Graphics Abstraction

From: Rene Brun (Rene.Brun@cern.ch)
Date: Wed Oct 31 2001 - 19:09:39 MET


Hi Brett,

I agree with your analysis about the transformations.
For people who may have some difficulties to understand what we are talking
about, you will find in attachment a macro "FittingDemo.C". Simply do;
   root > .x FittingDemo.C
Now using the mouse, select, eg in the TCanvas context menu the SetLogY option,
then again go to linear scale. You see that the same objects understand
the log transformation. However, the legend stays at the same place. It is drawn
in the NDC (Normalized Device Coordinate) independently of the lin/log scale.
Now you may imagine all possible combinations lin/logx/lin/logy, etc in
a 2-d plot or 3-d plot. And obviously, if you print on Postscript, you expect
the same picture but with a higher resolution.
There are several transformations involved in this simple example:
  - two user (World Coordinate) systems (lin & log)
  - NDC coordinate system
  - screen coordinate system

There are more transformations involved. Eg, when drawing a 2-d plot,
you can select a cartesian, polar, cylindrical or spherical coordinate system.

The ROOT graphics has been developed for serious data analysis and high quality
graphs, not to do games in pixel coordinates with fancy animations.

Now to Valery, I will say the following:
Four years ago, Fons and myself could not convince you to implement a TVirtualX
interface under Windows. You were making the point that Microsoft had developed
a powerful browser, etc and that we should make an interface with the MS
browser.
We lost many years of effort in this exercise. It would have been better to
develop a solid TVirtualX interface on Windows together with stdin/stdout
support that requires threads.
It is my feeling that you are proposing to embark again into one more high
level interface to Qt (the one who is fashionable today). May be we will meet
again
in 4 years to discuss, yet, one more high level interface with Super_Sexy_G ::)

Rene Brun


Brett Viren wrote:
> 
> Valeri Fine writes:
>  >      Qt provides very attractive base class QCanvasItem:
>  >
>  >      http://doc.trolltech.com/3.0/qcanvasitemlist.html
>  >      http://doc.trolltech.com/3.0/qcanvasitem.html
> 
> I get a little nervous when QCanvas is suggested as something to
> emulate.  I works okay for some things but the fact that it is integer
> pixel based makes it difficult to use for things like event displays.
> The user must take care of the world coordinate abstraction.
> 
> As an alternative, I think GnomeCanvas is a better role model.  It
> treats objects as a heirarchy of items and groups (similar to how TPad
> can hold TPads and other TObjects) each with their own affine
> transformation and either world or absolute pixel drawing.  You can
> also put Gtk Widgets into a GnomeCanvas (although, I am not sure if
> that means one can have postscript output of the widget).
> 
> Some reading:
> 
> GnomeCanvas white paper:
> http://developer.gnome.org/doc/whitepapers/canvas/canvas.html
> Chapter from GGAD book:
> http://developer.gnome.org/doc/GGAD/cha-canvas.html
> 
> Another thing I haven't mentioned in my Gnome/Gtk/Gdk cheer-leading is
> that since all the underlying libraries are C, but follow an object
> oriented design, they lend themselves to easy wrapping in other
> languages.  For example, the Gnome--/Gtk--/Gdk-- effort.  I mention
> this because one could consider writing ROOT/CINT wrappers for the
> underlying C libraries as well.  But, another big long project....
> 
> GnomeCanvas does lack some things that QCanvas supplies, such as the
> setting an item's "velocity" to provide default movement.  This is not
> so useful for event displays but probably good for 2D games, and
> arguably better handled by the user.
> 
>  >   Qt provides the base QPaintDevice class with some subclasses like
>  >   QPrinter, QWidget, QPixmap,  QPicture etc
>  >
>  >   http://doc.trolltech.com/3.0/qpaintdevice.html
>  >   http://doc.trolltech.com/3.0/qpicture.html#details
>  >   http://doc.trolltech.com/3.0/qprinter.html
>  >
>  >
>  >    I'd like to call your attention to QPrinter / QPicture classes.
>  >    That is what one needs for  the batch job.
>  >
>  >   See:  http://doc.trolltech.com/3.0/qprinter.html#setOutputToFile
> 
> The QPainter idea is interesting.  To put it in ROOT terms, it
> essentially lets you swap out the implimentation of TVirtualX at run
> time from paint-to-X11 to paint-to-Postscript.  I used this when I
> tried to make Qt widgets draw themselves to postscript, along with the
> QCanvas for a proto-MIDAD event display.  It worked fairly well,
> although not perfect, I think due to internal Qt bugs (some widgets
> drew themselves wrong in Postscript).  I didn't get enough help from
> the Qt guys to find it desirable to get it working 100% and in the
> end, due to the QCanvas limitations, the QCanvas based display was
> abandoned for TCanvas based one.
> 
> -Brett.

#include "TH1.h"
#include "TF1.h"
#include "TLegend.h"
#include "TCanvas.h"

// Quadratic background function
Double_t background(Double_t *x, Double_t *par) {
   return par[0] + par[1]*x[0] + par[2]*x[0]*x[0];
}


// Lorenzian Peak function
Double_t lorentzianPeak(Double_t *x, Double_t *par) {
  return (0.5*par[0]*par[1]/TMath::Pi()) / 
    TMath::Max( 1.e-10,(x[0]-par[2])*(x[0]-par[2]) + .25*par[1]*par[1]);
}

// Sum of background and peak function
Double_t fitFunction(Double_t *x, Double_t *par) {
  return background(x,par) + lorentzianPeak(x,&par[3]);
}

void FittingDemo() {
 //Bevington Exercise by Peter Malzacher, modified by Rene Brun
 
   const int nBins = 60;
   
   Stat_t data[nBins] = { 6, 1,10,12, 6,13,23,22,15,21,
                         23,26,36,25,27,35,40,44,66,81,
                         75,57,48,45,46,41,35,36,53,32,
                         40,37,38,31,36,44,42,37,32,32,
                         43,44,35,33,33,39,29,41,32,44,
                         26,39,29,35,32,21,21,15,25,15};
   TCanvas *c1 = new TCanvas("c1","Fitting Demo",10,10,700,500);
   c1->SetFillColor(33);
   c1->SetFrameFillColor(41);
   c1->SetGrid();
   
   TH1F *histo = new TH1F("histo","Lorentzian Peak on Quadratic Background",60,0,3);
   histo->SetMarkerStyle(21);
   histo->SetMarkerSize(0.8);
   histo->SetStats(0);
       
   for(int i=0; i < nBins;  i++) histo->SetBinContent(i+1,data[i]);
   
   // create a TF1 with the range from 0 to 3 and 6 parameters
   TF1 *fitFcn = new TF1("fitFcn",fitFunction,0,3,6);
   fitFcn->SetNpx(500);
   fitFcn->SetLineWidth(4);
   fitFcn->SetLineColor(kMagenta);
    
   // first try without starting values for the parameters
   // This defaults to 1 for each param. 
   // this results in an ok fit for the polynomial function
   // however the non-linear part (lorenzian) does not 
   // respond well.
   histo->Fit("fitFcn","0");
   
   // second try: set start values for some parameters
   fitFcn->SetParameter(4,0.2); // width
   fitFcn->SetParameter(5,1);   // peak
 
   histo->Fit("fitFcn","V+","ep");
   
   // improve the picture:
   TF1 *backFcn = new TF1("backFcn",background,0,3,3);
   backFcn->SetLineColor(kRed);
   TF1 *signalFcn = new TF1("signalFcn",lorentzianPeak,0,3,3);
   signalFcn->SetLineColor(kBlue);
   signalFcn->SetNpx(500);
   Double_t par[6];
  
   // writes the fit results into the par array
   fitFcn->GetParameters(par);
    
   backFcn->SetParameters(par);
   backFcn->Draw("same");
 
   signalFcn->SetParameters(&par[3]);
   signalFcn->Draw("same"); 
   
   // draw the legend
   TLegend *legend=new TLegend(0.6,0.65,0.88,0.85);
   legend->SetTextFont(72);
   legend->SetTextSize(0.04);
   legend->AddEntry(histo,"Data","lp");
   legend->AddEntry(backFcn,"Background fit","l");
   legend->AddEntry(signalFcn,"Signal fit","l");
   legend->AddEntry(fitFcn,"Global Fit","l");
   legend->Draw();
   
}



This archive was generated by hypermail 2b29 : Tue Jan 01 2002 - 17:51:05 MET