Re: [ROOT] Paint

From: Rene Brun (Rene.Brun@cern.ch)
Date: Fri May 26 2000 - 08:39:25 MEST


OK, I understand now what you want. You should have been more explicit
in your first mail.
In attachment, you will see two files:
 -ATLFParticle.cxx
 -AliDisplay.cxx

In the first file, look at function ATLFParticle::ExecuteEvent
for a very short example illustrating how to highlight the picked track.

In the second file, look at AliDisplay::ExecuteEvent to see a more elaborated
example showing how to draw a "rubber band box" to select an area to be zoomed.
The first example is from the ATLASfast program, the second from the Alice
event display.

You can also look in Root at TView::ExecuteRotateView for an example showing how
to draw the outline of a rotating cube.

Another example can be found in the new Root tutorials in
$ROOTSYS/tutorials/exec2.C

Rene Brun


jiangyong jia wrote:
> 
> Dear Brun,
> I will give you a more detailed explanation on the Xlib problem I have
> Posted on the Root digest(message:Xlib or root?), thanks for
> quick responding
> 
> now stuff related to this mail:
> For example, I have a list of thousands of tracks and 10 times more of
> hits on a canvas(As is the case for Phenix detector). I would like to have
> the ability to press and highlight the track under mouse point...
> But let the Canvas to do a update will be inefficient(redraw
> everything takes too much time)I want the canvas act as an accumulation buffer
> which I can continusly modify it.I thought I could use paint.
> 
> I run into this question also because I want to debug why my application
> freezes and sleeps in xlib call... as you already see in my yestoday's
> mail. I want to know a little more about the interaction between root and
> xlib
> 
> So, Repeat my problem:
> 
> Under root prompt:
> type:
> TCanvas * c1= new TCanvas("c1","c1",100,100);
> TLine *a = TLine(0,0,1,1) ;
> a->Paint();
> c1->Flush()[or gVirtualX->Update()]
> 
> Nothing have been drawn! But paint called from TPad will do the job!
> this also will not work even call from  shared library..
> 
> I can't Paint directly onto the canvas, faint......
> 
> thanks,
> Jiangyong
> 
> On Thu, 25 May 2000, Rene Brun wrote:
> 
> > You can call the Paint functions only during the Paint process.
> > See http://root.cern.ch/root/HowtoDraw.html
> > When the pad must be drawn/redrawn, the Paint function for all
> > objects in the list of primitives is called. In turn the Paint
> > functions call gVirtualX drawing functions to draw in the current
> > pixmap in memory. When the drawing is complete, the pixmap
> > in memory is copied to the screen memory.
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
>  which command?? XFulsh()??
> ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
> > Could you explain what is the problem you try to solve
> > and where the current tools are not sufficient?
> >
> > Rene Brun
> >
> > On Thu, 25 May 2000,
> > jiangyong jia wrote:
> >
> > >
> > > Hi,Rooters,
> > >
> > > Is there a way to use paint function directly from root prompt??
> > > I mean instead of Use Draw function and Append the TObject onto
> > > Primitive list of Current pad, I want to call Paint() function directly
> > > But I find out it is not working!!!, also gVirtualX will not work also.
> > > example:
> > > type gVirtualX->DrawLine(0,1,1,0) from root prompt will draw you nothing.
> > > cheers.
> > > Jiangyong
> > >
> > >
> > >
> > > ************************************************
> > >     jjia@rcf.rhic.bnl.gov
> > >         Jiangyong Jia
> > >             Department of Physics
> > >             State University New York at Stony Brook
> > >             Stony Brook, New York 11794-3800
> > >         Tel.631-344-5455
> > > *********************************************
> > >
> > >
> > >
> > >
> > >
> >
> >


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// ATLFParticle                                                         //
//                                                                      //
//  Graphics interface to event generators particle                     //
//////////////////////////////////////////////////////////////////////////

#include <TROOT.h>
#include "TMCParticle.h"
#include "TClonesArray.h"
#include "TPolyLine3D.h"
#include "TCanvas.h"
#include <TList.h>
#include <TMath.h>

#include "ATLFParticle.h"
#include "ATLFMCMaker.h"
#include "ATLFast.h"
#include "ATLFDisplay.h"

const Int_t kRECONS = BIT(16);

ClassImp(ATLFParticle)


//_____________________________________________________________________________
ATLFParticle::ATLFParticle(const char * name) :TNamed(name,name)
{
   // Create list to support list of particles
   m_Particles = new TList();
   m_Display   = (ATLFDisplay*)gATLFast->Display();
}

//_____________________________________________________________________________
ATLFParticle::~ATLFParticle()
{
   if (m_Particles) m_Particles->Delete();
   delete m_Particles;
}

//_____________________________________________________________________________
void ATLFParticle::Clear(Option_t *)
{
//    Delete graphics temporary objects

   m_Particles->Delete();

}

//_____________________________________________________________________________
void ATLFParticle::Delete(Option_t *)
{
//    Dummy

}

//_____________________________________________________________________________
Int_t ATLFParticle::DistancetoPrimitive(Int_t px, Int_t py)
{
    // scan list of particles
   TClonesArray *particles = gATLFast->MCMaker()->Fruits();
   Int_t uid, dist;
   TIter next(m_Particles);
   TPolyLine3D *line;
   while((line=(TPolyLine3D*)next())) {
      dist = line->DistancetoPrimitive(px, py);
      if (dist < 2) {
         uid = line->GetUniqueID();
         m_MCParticle = (TMCParticle*)particles->UncheckedAt(uid);
         if (!m_MCParticle) continue;
         m_Line = line;
         SetName(m_MCParticle->GetName());
         gPad->SetSelected(this);
         gPad->SetCursor(kCross);
         return 0;
      }
   }
   return 999;
}

//______________________________________________________________________________
void ATLFParticle::ExecuteEvent(Int_t event, Int_t , Int_t )
{
   switch (event) {

   case kButton1Down:
      gVirtualX->SetLineColor(-1);
      gPad->AbsCoordinates(kTRUE);
      m_Line->SetLineColor(6);
      m_Line->SetLineWidth(6);
      m_Line->Paint(); 
      break;

   case kMouseMotion:
      break;

   case kButton1Motion:
      break;

   case kButton1Up:
      gVirtualX->SetLineColor(-1);
      m_Line->SetLineColor(kYellow);
      m_Line->SetLineWidth(1);
      m_Line->Paint(); 
      gPad->AbsCoordinates(kFALSE);
   }
}

//______________________________________________________________________________
char *ATLFParticle::GetObjectInfo(Int_t , Int_t )
{
   static char info[100];
   sprintf(info,"px=%f, py=%f, pz=%f, E=%f",
            m_MCParticle->GetPx(),
            m_MCParticle->GetPy(),
            m_MCParticle->GetPz(),
            m_MCParticle->GetEnergy());
   return info;
}


//______________________________________________________________________________
TPolyLine3D *ATLFParticle::HelixCurve(Float_t field, Float_t pmom, Float_t *vin)
{
//    Estimate step size in function of field.
//    Create a 3-D polyline with points computed with this step size

   Float_t step = 10;
   const Int_t kMAXSTEP = 2000;
   Float_t sx[kMAXSTEP], sy[kMAXSTEP], sz[kMAXSTEP];
   if (pmom > 0)   step = 10*pmom;
   if (step > 100) step = 100;
   if (step <  .5) step = .5;

   Float_t vout[6];
   Int_t i,j;
   sx[0] = vin[0];
   sy[0] = vin[1];
   sz[0] = vin[2];
   Int_t nsteps = 1;
   Float_t rin  = Display()->Rin();
   Float_t zout = Display()->Zout();
   for (i=1;i<kMAXSTEP;i++) {
      HelixStep(field,step,pmom,vin,vout);
      if (TMath::Abs(vout[2]) > zout) break;
      if (vout[0]*vout[0] + vout[1]*vout[1] > 1.1*rin*rin) break;
      sx[nsteps] = vout[0];
      sy[nsteps] = vout[1];
      sz[nsteps] = vout[2];
      nsteps++;
      for (j=0;j<6;j++) vin[j] = vout[j];
   }
   if (nsteps < 2) return 0;
   TPolyLine3D *line = new TPolyLine3D(nsteps,sx, sy,sz);
   line->SetBit(kCanDelete);
   return line;
}

//______________________________________________________________________________
void ATLFParticle::HelixStep(Float_t field, Float_t step, Float_t pmom, Float_t *vin, Float_t *vout)
{
//     extrapolate track with parameters in vector vin in a constant field
//     oriented along Z axis (in tesla/meters).
//     Output in vector vout
//     vin[0-->6] = x,y,z,px,py,pz
//     translated to C++ from GEANT3 routine GHELX3

   Float_t sint, sintt, tsint, cos1t, sin2;
//      units are tesla,centimeters,gev/c
   const Float_t ec = 2.9979251e-3;
   Float_t h4  = field*ec;
   Float_t hp  = vin[2];
   Float_t tet = -h4*step/pmom;
   if (TMath::Abs(tet) > 0.15) {
      sint  = TMath::Sin(tet);
      sintt = sint/tet;
      tsint = (tet-sint)/tet;
      sin2  = TMath::Sin(0.5*tet);
      cos1t = 2*sin2*sin2/tet;
   } else {
      tsint = tet*tet/6;
      sintt = 1 - tsint;
      sint  = tet*sintt;
      cos1t = 0.5*tet;
   }
   Float_t f1 = step*sintt;
   Float_t f2 = step*cos1t;
   Float_t f3 = step*tsint*hp;
   Float_t f4 = -tet*cos1t;
   Float_t f5 = sint;
   Float_t f6 = tet*cos1t*hp;

   vout[0] = vin[0] + (f1*vin[3] - f2*vin[4]);
   vout[1] = vin[1] + (f1*vin[4] + f2*vin[3]);
   vout[2] = vin[2] + (f1*vin[5] + f3);

   vout[3] = vin[3] + (f4*vin[3] - f5*vin[4]);
   vout[4] = vin[4] + (f4*vin[4] + f5*vin[3]);
   vout[5] = vin[5] + (f4*vin[5] + f6);
}

//_____________________________________________________________________________
void ATLFParticle::Paint(Option_t *option)
{
//    Paint particles generated by ATLFMCMaker
//    Only particles above m_PTcut are drawn
//    Particle trajectory is computed along an helix in a constant field


   // clean list of particles
   m_Particles->Delete();

   TClonesArray *particles = gATLFast->MCMaker()->Fruits();
   Int_t nparticles = particles->GetEntriesFast();
   TMCParticle *part;
   Float_t pmom, vx, vy, vz, pt;
   Float_t vin[6];
   Float_t field = 2; // 2 tesla
   Int_t KF, aKF, charge;
   for (Int_t i=0;i<nparticles;i++) {
      part = (TMCParticle*)particles->UncheckedAt(i);     
      if (part->GetKS() != 1) continue;
      KF = part->GetKF();
      aKF = TMath::Abs(KF);
      charge = gATLFast->MCMaker()->Charge(KF);
      pt = TMath::Sqrt(part->GetPx()*part->GetPx() + part->GetPy()*part->GetPy());
      if (pt < gATLFast->Display()->PTcut()) continue;
      if (charge == 0 && pt < gATLFast->Display()->PTcutEGMUNU()) continue;
      pmom = TMath::Sqrt(part->GetPx()*part->GetPx() + part->GetPy()*part->GetPy() + part->GetPz()*part->GetPz());
      vx = part->GetVx();
      vy = part->GetVy();
      vz = part->GetVz();
      vin[0] = vx;
      vin[1] = vy;
      vin[2] = vz;
      vin[3] = part->GetPx()/pmom;
      vin[4] = part->GetPy()/pmom;
      vin[5] = part->GetPz()/pmom;
      TPolyLine3D *line = HelixCurve(charge*field/3, pmom, vin);
      if (line == 0) continue;
      m_Particles->Add(line);
      if (part->GetLineColor() == 1) {
         if (charge == 0) part->SetLineStyle(2);
         part->SetLineColor(kYellow);
         if (aKF == 11) part->SetLineColor(kRed);
         if (aKF == 13) part->SetLineColor(kMagenta);
         if (aKF == 22) part->SetLineColor(kGreen);
      }
      line->SetUniqueID(i);
      if (!part->TestBit(kRECONS)) {
         part->SetLineColor(7);
         part->SetLineWidth(1);
      }
      line->SetLineColor(part->GetLineColor());
      line->SetLineStyle(part->GetLineStyle());
      line->SetLineWidth(part->GetLineWidth());
      line->Paint(option);
   }
}

//______________________________________________________________________________
void ATLFParticle::SetLineAttributes()
{
//*-*-*-*-*-*-*-*-*Invoke the DialogCanvas Line attributes*-*-*-*-*-*-*
//*-*              =======================================

   gROOT->SetSelectedPrimitive(m_MCParticle);
   m_MCParticle->SetLineAttributes();
}


//______________________________________________________________________________
void ATLFParticle::SizeParticles() const
{
   TIter next(m_Particles);
   TPolyLine3D *line;
   while((line=(TPolyLine3D*)next())) {
      line->Sizeof3D();
   }
}


/**************************************************************************
 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
 *                                                                        *
 * Author: The ALICE Off-line Project.                                    *
 * Contributors are mentioned in the code where appropriate.              *
 *                                                                        *
 * Permission to use, copy, modify and distribute this software and its   *
 * documentation strictly for non-commercial purposes is hereby granted   *
 * without fee, provided that the above copyright notice appears in all   *
 * copies and that both the copyright notice and this permission notice   *
 * appear in the supporting documentation. The authors make no claims     *
 * about the suitability of this software for any purpose. It is          *
 * provided "as is" without express or implied warranty.                  *
 **************************************************************************/

/*
$Log: AliDisplay.cxx,v $
Revision 1.7  1999/11/10 07:37:06  fca
Pads do not inherit editability from canvas any more

Revision 1.6  1999/11/09 07:38:52  fca
Changes for compatibility with version 2.23 of ROOT

Revision 1.5  1999/09/29 09:24:29  fca
Introduction of the Copyright and cvs Log

*/


//////////////////////////////////////////////////////////////////////////
//                                                                      //
// AliDisplay                                                           //
//                                                                      //
// Utility class to display ALICE outline, tracks, hits,..              //
//                                                                      //
//////////////////////////////////////////////////////////////////////////

#include <TROOT.h>
#include <TTree.h>
#include <TButton.h>
#include <TCanvas.h>
#include <TView.h>
#include <TText.h>
#include <TPolyMarker3D.h>
#include <TPaveLabel.h>
#include <TPaveText.h>
#include <TList.h>
#include <TDiamond.h>
#include <TNode.h>
#include <TArc.h>
#include <TTUBE.h>
#include <TSlider.h>
#include <TSliderBox.h>
#include <TGaxis.h>
#include <TVirtualX.h>
#include <TMath.h>
#include <X3DBuffer.h>

#include "AliRun.h"
#include "AliDetector.h"
#include "AliDisplay.h"
#include "AliPoints.h"
#include "TParticle.h"

const Float_t ptcutmax  = 2;
const Float_t etacutmax = 1.5;

ClassImp(AliDisplay)


//_____________________________________________________________________________
AliDisplay::AliDisplay()
{
   fCanvas = 0;
}

//_____________________________________________________________________________
AliDisplay::AliDisplay(Int_t size)
{
// Create an event display object.
// A canvas named "edisplay" is created with a vertical size in pixels
//
//    A QUICK Overview of the Event Display functions
//    ===============================================
//
//  The event display can ve invoked by executing the macro "display.C"
// A canvas like in the picture below will appear.
//
//  On the left side of the canvas, the following buttons appear:
//   *Next*       to move to the next event
//   *Previous*   to move to the previous event
//   *Top View*   to display a top view of the current event
//   *Side View*  to display a side view of the current event
//   *Front View* to display a front view of the current event
//   *All Views*  to display front/side/top/30-30 views of the current event
//   *OpenGL*     to use OpenGl to view the current event.
//                Note that OpenGL cannot be used across the network.
//                Before using OpenGL, load the GL libraries
//                by executing the macro GL.C (in $ROOTSYS/macros/GL.C.
//                Once in GL, click the HELP button of the GL canvas.
//   *X3D*        to use X3D to view the current event (Unix only).
//                Once in X3D, type M to see the list of all possible options.
//                for example type J to zoom, K to unzoom
//                use the mouse to rotate.
//   *Pick*       Select this option to be able to point on a track with the
//                mouse. Once on the track, use the right button to select
//                an action. For example, select SetMarkerAttributes to
//                change the marker type/color/size for the track.
//   *Zoom*       Select this option (default) if you want to zoom.
//                To zoom, simply select the selected area with the left button.
//   *UnZoom*     To revert to the previous picture size.
//
//   slider R     On the left side, the vertical slider can be used to
//                set the default picture size.
//   slider pcut  At the top of the canvas, a slider can be used to change
//                the momentum cut (or range) to display tracks.
//   slider eta   On the right side of the canvas, a vertical slider can be used
//                to specify a rapidity range for the tracks.
//
//    When you are in Zoom mode, you can click on the black part of the canvas
//  to select special options with the right mouse button.
//  This will display a pop-up menu with items like:
//     *Disable detector* 
//     *Enable detector*, etc.
//  For example select "Disable detector". You get a dialog box.
//  Diable detector TRD for example.
//
//  When you are in pick mode, you can "Inspect" the object pointed by the mouse.
//  When you are on a track, select the menu item "InspectParticle"
//  to display the current particle attributes.
//
//  You can activate the Root browser by selecting the Inspect menu
//  in the canvas tool bar menu. Then select "Start Browser"
//  This will open a new canvas with the browser. At this point, you may want
//  to display some histograms (from the Trees). Go to the "File" menu
//  of the browser and click on "New canvas".
//  In the browser, click on item "ROOT files" in the left pane.
//  Click on galice.root.
//  Click on TH
//  Click on TPC for example
//  Click on any variable (eg TPC.fX) to histogram the variable.
//
//   If you are lost, you can click on HELP in any Root canvas or browser.
//Begin_Html
/*
<img src="picts/alidisplay.gif">
*/
//End_Html
   
   fPad = 0;
   gAlice->SetDisplay(this);
   
   // Initialize display default parameters
   SetRange();
   SetPTcut();

   // Set front view by default
   fTheta = 0;
   fPhi   = -90;
   fPsi   = 0;
   fDrawAllViews  = kFALSE;
   fDrawHits      = kTRUE;
   fDrawParticles = kTRUE;
   fZoomMode      = 1;
   fZooms         = 0;
   fHitsCuts      = 0;
   
   // Create display canvas
   Int_t ysize = size;
   if (ysize < 100) ysize = 750;
   Int_t xsize = Int_t(size*830./ysize);
   fCanvas = new TCanvas("Canvas", "ALICE Event Display",14,47,xsize,ysize);
   fCanvas->ToggleEventStatus();
   
   // Create main display pad
   fPad = new TPad("viewpad", "Alice display",0.15,0,0.97,0.96);
   fPad->Draw();
   fPad->Modified();
   fPad->SetFillColor(1);
   fPad->SetBorderSize(2);

   // Create user interface control pad
   DisplayButtons();
   fCanvas->cd();

   // Create Range and mode pad
   Float_t dxtr     = 0.15;
   Float_t dytr     = 0.45;
   fTrigPad = new TPad("trigger", "range and mode pad",0,0,dxtr,dytr);
   fTrigPad->SetEditable(kFALSE);
   fTrigPad->Draw();
   fTrigPad->cd();
   fTrigPad->SetFillColor(22);
   fTrigPad->SetBorderSize(2);
   fRangeSlider = new TSlider("range","range",0.7,0.42,0.9,0.98);
   fRangeSlider->SetObject(this);
   char pickmode[] = "gAlice->Display()->SetPickMode()";
   Float_t db = 0.09;
   fPickButton = new TButton("Pick",pickmode,0.05,0.32,0.65,0.32+db);
   fPickButton->SetFillColor(38);
   fPickButton->Draw();
   char zoommode[] = "gAlice->Display()->SetZoomMode()";
   fZoomButton = new TButton("Zoom",zoommode,0.05,0.21,0.65,0.21+db);
   fZoomButton->SetFillColor(38);
   fZoomButton->Draw();
   fArcButton = new TArc(.8,fZoomButton->GetYlowNDC()+0.5*db,0.33*db);
   fArcButton->SetFillColor(kGreen);
   fArcButton->Draw();
   char butUnzoom[] = "gAlice->Display()->UnZoom()";
   TButton *button = new TButton("UnZoom",butUnzoom,0.05,0.05,0.95,0.15);
   button->SetFillColor(38);
   button->Draw();
   AppendPad(); // append display object as last object to force selection

   // Create momentum cut slider pad
   fCanvas->cd();
   fCutPad = new TPad("cutSlider", "pcut slider pad",dxtr,.96,1,1);
   fCutPad->Draw();
   fCutPad->cd();
   fCutPad->SetFillColor(22);
   fCutPad->SetBorderSize(2);
   fCutSlider   = new TSlider("pcut","Momentum cut",0,0,1,1);
   fCutSlider->SetRange(fPTcut/ptcutmax,1);
   fCutSlider->SetObject(this);
   fCutSlider->SetFillColor(45);
   TSliderBox *sbox = (TSliderBox*)fCutSlider->GetListOfPrimitives()->First();
   sbox->SetFillColor(46);
   fCutSlider->cd();
   TGaxis *cutaxis = new TGaxis(0.02,0.8,0.98,0.8,0,ptcutmax,510,"");
   cutaxis->SetLabelSize(0.5);
   cutaxis->SetTitleSize(0.6);
   cutaxis->SetTitleOffset(0.5);
   cutaxis->SetTitle("pcut .  ");
   fCutSlider->GetListOfPrimitives()->AddFirst(cutaxis);

      // Create rapidity cut slider pad
   fCanvas->cd();
   fEtaPad = new TPad("EtaSlider", "Eta slider pad",0.97,0,1,0.96);
   fEtaPad->Draw();
   fEtaPad->cd();
   fEtaPad->SetFillColor(22);
   fEtaPad->SetBorderSize(2);
   fEtaSlider   = new TSlider("etacut","Rapidity cut",0,0,1,1);
   fEtaSlider->SetObject(this);
   fEtaSlider->SetFillColor(45);
   TSliderBox *sbox2 = (TSliderBox*)fEtaSlider->GetListOfPrimitives()->First();
   sbox2->SetFillColor(46);
   fEtaSlider->cd();
   TGaxis *etaaxis = new TGaxis(0.9,0.02,0.9,0.98,-etacutmax,etacutmax,510,"");
   etaaxis->SetLabelSize(0.5);
   etaaxis->SetTitleSize(0.6);
   etaaxis->SetTitleOffset(0.2);
   cutaxis->SetTitle("Etacut .  ");
   fEtaSlider->GetListOfPrimitives()->AddFirst(etaaxis);
   fCanvas->cd();
   

   fCanvas->cd();
   fCanvas->Update();
}


//_____________________________________________________________________________
AliDisplay::~AliDisplay()
{
}

//_____________________________________________________________________________
void AliDisplay::Clear(Option_t *)
{
//    Delete graphics temporary objects
}

//----------------------------------------------------------------------------
void AliDisplay::ShowTrack(Int_t idx) {
   AliDetector *TPC=(AliDetector*)gAlice->GetModule("TPC");
   TObjArray *points=TPC->Points();
   int ntracks=points->GetEntriesFast();
   for (int track=0;track<ntracks;track++) {
      AliPoints *pm = (AliPoints*)points->UncheckedAt(track);
      if (!pm) continue;
      if (idx == pm->GetIndex()) {
         pm->SetMarkerColor(2);
         pm->SetMarkerStyle(22);
         pm->Draw("same");
//       fPad->Update();
//       fPad->Modified();
         TClonesArray *particles=gAlice->Particles();
         TParticle *p = (TParticle*)particles->UncheckedAt(idx);
         printf("\nTrack index %d\n",idx);
         printf("Particle ID %d\n",p->GetPdgCode());
         printf("Parent %d\n",p->GetFirstMother());
         printf("First child %d\n",p->GetFirstDaughter());
         printf("Px,Py,Pz %f %f %f\n",p->Px(),p->Py(),p->Pz());
         return;
      }
   }
}

//----------------------------------------------------------------------------
void AliDisplay::HideTrack(Int_t idx) {
   AliDetector *TPC=(AliDetector*)gAlice->GetModule("TPC");
   TObjArray *points=TPC->Points();
   int ntracks=points->GetEntriesFast();
   for (int track=0;track<ntracks;track++) {
      AliPoints *pm = (AliPoints*)points->UncheckedAt(track);
      if (!pm) continue;
      if (idx == pm->GetIndex()) {
         pm->SetMarkerColor(5);
         pm->SetMarkerStyle(1);
         pm->Draw("same");
//       fPad->Update();
//       fPad->Modified();
         return;
      }
   }
}

//_____________________________________________________________________________
void AliDisplay::DisableDetector(const char *name)
{
//    Disable detector name from graphics views
   
   AliModule *module = (AliModule*)gAlice->Modules()->FindObject(name);
   if (!module) return;
   module->Disable();
   Draw();
}

//_____________________________________________________________________________
void AliDisplay::DisplayButtons()
{
//    Create the user interface buttons

   fButtons = new TPad("buttons", "newpad",0,0.45,0.15,1);
   fButtons->SetEditable(kFALSE);
   fButtons->Draw();
   fButtons->SetFillColor(38);
   fButtons->SetBorderSize(2);
   fButtons->cd();

   Int_t butcolor = 33;
   Float_t dbutton = 0.08;
   Float_t y  = 0.96;
   Float_t dy = 0.014;
   Float_t x0 = 0.05;
   Float_t x1 = 0.95;

   TButton *button;
   char but1[] = "gAlice->Display()->ShowNextEvent(1)";
   button = new TButton("Next",but1,x0,y-dbutton,x1,y);
   button->SetFillColor(38);
   button->Draw();

   y -= dbutton +dy;
   char but2[] = "gAlice->Display()->ShowNextEvent(-1)";
   button = new TButton("Previous",but2,x0,y-dbutton,x1,y);
   button->SetFillColor(38);
   button->Draw();

   y -= dbutton +dy;
   char but3[] = "gAlice->Display()->SetView(90,-90,90)";
   button = new TButton("Top View",but3,x0,y-dbutton,x1,y);
   button->SetFillColor(butcolor);
   button->Draw();

   y -= dbutton +dy;
   char but4[] = "gAlice->Display()->SetView(90,0,-90)";
   button = new TButton("Side View",but4,x0,y-dbutton,x1,y);
   button->SetFillColor(butcolor);
   button->Draw();

   y -= dbutton +dy;
   char but5[] = "gAlice->Display()->SetView(0,-90,0)";
   button = new TButton("Front View",but5,x0,y-dbutton,x1,y);
   button->SetFillColor(butcolor);
   button->Draw();

   y -= dbutton +dy;
   char but6[] = "gAlice->Display()->DrawAllViews()";
   button = new TButton("All Views",but6,x0,y-dbutton,x1,y);
   button->SetFillColor(butcolor);
   button->Draw();

   y -= dbutton +dy;
   char but7[] = "gAlice->Display()->DrawViewGL()";
   button = new TButton("OpenGL",but7,x0,y-dbutton,x1,y);
   button->SetFillColor(38);
   button->Draw();

   y -= dbutton +dy;
   char but8[] = "gAlice->Display()->DrawViewX3D()";
   button = new TButton("X3D",but8,x0,y-dbutton,x1,y);
   button->SetFillColor(38);
   button->Draw();

   // display logo
   TDiamond *diamond = new TDiamond(0.05,0.015,0.95,0.22);
   diamond->SetFillColor(50);
   diamond->SetTextAlign(22);
   diamond->SetTextColor(5);
   diamond->SetTextSize(0.11);
   diamond->Draw();
   diamond->AddText(".. ");
   diamond->AddText("ROOT");
   diamond->AddText("ALICE");
   diamond->AddText("... ");
   diamond->AddText(" ");
}

//______________________________________________________________________________
Int_t AliDisplay::DistancetoPrimitive(Int_t px, Int_t)
{
// Compute distance from point px,py to objects in event

   gPad->SetCursor(kCross);
   
   if (gPad == fTrigPad) return 9999;
   if (gPad == fCutPad)  return 9999;
   if (gPad == fEtaPad)  return 9999;

   const Int_t big = 9999;
   Int_t dist   = big;
   Float_t xmin = gPad->GetX1();
   Float_t xmax = gPad->GetX2();
   Float_t dx   = 0.02*(xmax - xmin);
   Float_t x    = gPad->AbsPixeltoX(px);
   if (x < xmin+dx || x > xmax-dx) return dist;

   if (fZoomMode) return 0;
   else           return 7;
}

//_____________________________________________________________________________
void AliDisplay::Draw(Option_t *)
{
//    Display current event

   if (fDrawAllViews) {
      DrawAllViews();
      return;
   }

   fPad->cd();

   DrawView(fTheta, fPhi, fPsi);

   // Display the event number and title
   fPad->cd();
   DrawTitle();
}

//_____________________________________________________________________________
void AliDisplay::DrawAllViews()
{
//    Draw front,top,side and 30 deg views

   fDrawAllViews = kTRUE;
   fPad->cd();
   fPad->SetFillColor(15);
   fPad->Clear();
   fPad->Divide(2,2);

   // draw 30 deg view
   fPad->cd(1);
   DrawView(30, 30, 0);
   DrawTitle();

   // draw front view
   fPad->cd(2);
   DrawView(0, -90,0);
   DrawTitle("Front");

   // draw top view
   fPad->cd(3);
   DrawView(90, -90, 90);
   DrawTitle("Top");

   // draw side view
   fPad->cd(4);
   DrawView(90, 0, -90);
   DrawTitle("Side");

   fPad->cd(2);
}

//_____________________________________________________________________________
void AliDisplay::DrawHits()
{
//    Draw hits for all ALICE detectors

   Float_t cutmin, cutmax, etamin, etamax, pmom, smin, smax, eta, theta, r;
   Float_t *pxyz;
   Int_t ntracks,track;
   TParticle *particle;
   TObjArray *points;
   AliPoints *pm;
      
   //Get cut slider
   smax   = fCutSlider->GetMaximum();
   smin   = fCutSlider->GetMinimum();
   cutmin = ptcutmax*smin;
   if (smax < 0.98) cutmax = ptcutmax*smax;
   else             cutmax = 100000;
   
   //Get eta slider
   smax   = fEtaSlider->GetMaximum();
   smin   = fEtaSlider->GetMinimum();
   etamin = etacutmax*(2*smin-1);
   etamax = etacutmax*(2*smax-1);
   if (smin < 0.02) etamin = -1000;
   if (smax > 0.98) etamax =  1000;
      
   TIter next(gAlice->Modules());
   AliModule *module;
   fHitsCuts = 0;
   while((module = (AliModule*)next())) {
      if (!module->IsActive()) continue;
      points = module->Points();
      if (!points) continue;
      ntracks = points->GetEntriesFast();
      for (track=0;track<ntracks;track++) {
         pm = (AliPoints*)points->UncheckedAt(track);
         if (!pm) continue;
         particle = pm->GetParticle();
         if (!particle) continue;
         pmom = particle->P();
         if (pmom < cutmin) continue;
         if (pmom > cutmax) continue;
         // as a first approximation, take eta of first point
         pxyz  = pm->GetP();
         r     = TMath::Sqrt(pxyz[0]*pxyz[0] + pxyz[1]*pxyz[1]);
         theta = TMath::ATan2(r,TMath::Abs(pxyz[2]));
         if(theta) eta = -TMath::Log(TMath::Tan(0.5*theta)); else eta = 1e10;
         if (pxyz[2] < 0) eta = -eta;
         if (eta < etamin || eta > etamax) continue;
         pm->Draw();
         fHitsCuts += pm->GetN();
      }
   }
}

//_____________________________________________________________________________
void AliDisplay::DrawTitle(Option_t *option)
{
//    Draw the event title

   Float_t xmin = gPad->GetX1();
   Float_t xmax = gPad->GetX2();
   Float_t ymin = gPad->GetY1();
   Float_t ymax = gPad->GetY2();
   Float_t dx   = xmax-xmin;
   Float_t dy   = ymax-ymin;

   if (strlen(option) == 0) {
      TPaveText *title = new TPaveText(xmin +0.01*dx, ymax-0.09*dy, xmin +0.5*dx, ymax-0.01*dy);
      title->SetBit(kCanDelete);
      title->SetFillColor(42);
      title->Draw();
      char ptitle[100];
      sprintf(ptitle,"Alice event: %d, Run:%d",gAlice->GetHeader()->GetEvent(), gAlice->GetHeader()->GetRun());
      title->AddText(ptitle);
      Int_t nparticles = gAlice->Particles()->GetEntriesFast();
      sprintf(ptitle,"Nparticles = %d  Nhits = %d",nparticles, fHitsCuts);
      title->AddText(ptitle);
   } else {
      TPaveLabel *label = new TPaveLabel(xmin +0.01*dx, ymax-0.07*dy, xmin +0.2*dx, ymax-0.01*dy,option);
      label->SetBit(kCanDelete);
      label->SetFillColor(42);
      label->Draw();
   }
}

//_____________________________________________________________________________
void AliDisplay::DrawView(Float_t theta, Float_t phi, Float_t psi)
{
//    Draw a view of ALICE

   gPad->SetCursor(kWatch);
   gPad->SetFillColor(1);
   gPad->Clear();

   Int_t iret;
   TView *view = new TView(1);
   Float_t range = fRrange*fRangeSlider->GetMaximum();
   view->SetRange(-range,-range,-range,range, range, range);
   fZoomX0[0] = -1;
   fZoomY0[0] = -1;
   fZoomX1[0] =  1;
   fZoomY1[0] =  1;
   fZooms = 0;
   
   // Display Alice Geometry
   gAlice->GetGeometry()->Draw("same");
   
   //Loop on all detectors to add their products to the pad
   DrawHits();

    // add itself to the list (must be last)
   AppendPad();
   
   view->SetView(phi, theta, psi, iret);
}

//_____________________________________________________________________________
void AliDisplay::DrawViewGL()
{
//    Draw current view using OPENGL

   TPad *pad = (TPad*)gPad->GetPadSave();
   pad->cd();
   TView *view = pad->GetView();
   if (!view) return;
   pad->x3d("OPENGL");
}

//_____________________________________________________________________________
void AliDisplay::DrawViewX3D()
{
//    Draw current view using X3D

   TPad *pad = (TPad*)gPad->GetPadSave();
   pad->cd();
   TView *view = pad->GetView();
   if (!view) return;
   pad->x3d();
}

//_____________________________________________________________________________
void AliDisplay::EnableDetector(const char *name)
{
//    Enable detector name in graphics views
   
   AliModule *module = (AliModule*)gAlice->Modules()->FindObject(name);
   if (!module) return;
   module->Enable();
   Draw();
}

//______________________________________________________________________________
void AliDisplay::ExecuteEvent(Int_t event, Int_t px, Int_t py)
{
//  Execute action corresponding to the mouse event

   static Float_t x0, y0, x1, y1;

   static Int_t pxold, pyold;
   static Int_t px0, py0;
   static Int_t linedrawn;
   Float_t temp;

   if (px == 0 && py == 0) { //when called by sliders
      if (event == kButton1Up) {
         Draw();
      }
      return;
   }
   if (!fZoomMode && gPad->GetView()) {
      gPad->GetView()->ExecuteRotateView(event, px, py);
      return;
   }

   // something to zoom ?
//   fPad->SetCursor(kCross);
   gPad->SetCursor(kCross);
   
   switch (event) {

   case kButton1Down:
      gVirtualX->SetLineColor(-1);
      gPad->TAttLine::Modify();  //Change line attributes only if necessary
      x0 = gPad->AbsPixeltoX(px);
      y0 = gPad->AbsPixeltoY(py);
      px0   = px; py0   = py;
      pxold = px; pyold = py;
      linedrawn = 0;
      return;

   case kButton1Motion:
      if (linedrawn) gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow);
      pxold = px;
      pyold = py;
      linedrawn = 1;
      gVirtualX->DrawBox(px0, py0, pxold, pyold, TVirtualX::kHollow);
      return;

   case kButton1Up:
      gPad->GetCanvas()->FeedbackMode(kFALSE);
      if (px == px0) return;
      if (py == py0) return;
      x1 = gPad->AbsPixeltoX(px);
      y1 = gPad->AbsPixeltoY(py);

      if (x1 < x0) {temp = x0; x0 = x1; x1 = temp;}
      if (y1 < y0) {temp = y0; y0 = y1; y1 = temp;}
      gPad->Range(x0,y0,x1,y1);
      if (fZooms < kMAXZOOMS-1) {
         fZooms++;
         fZoomX0[fZooms] = x0;
         fZoomY0[fZooms] = y0;
         fZoomX1[fZooms] = x1;
         fZoomY1[fZooms] = y1;
      }
      gPad->Modified(kTRUE);
      return;
   }

}
 
//___________________________________________
void AliDisplay::LoadPoints()
{
// Read hits info and store x,y,z info in arrays fPoints
// Loop on all detectors
 
   gAlice->ResetPoints();
   TIter next(gAlice->Modules());
   AliModule *module;
   Int_t ntracks = gAlice->GetNtrack();
   for (Int_t track=0; track<ntracks;track++) {
      gAlice->ResetHits();
      gAlice->TreeH()->GetEvent(track);
      while((module = (AliModule*)next())) {
         module->LoadPoints(track);
      }
      next.Reset();
   }
}

//_____________________________________________________________________________
void AliDisplay::Paint(Option_t *)
{
//    Paint miscellaneous items

}

//_____________________________________________________________________________
void AliDisplay::SetPickMode()
{
   fZoomMode = 0;

   fArcButton->SetY1(fPickButton->GetYlowNDC()+0.5*fPickButton->GetHNDC());
   fTrigPad->Modified();
}

//_____________________________________________________________________________
void AliDisplay::SetZoomMode()
{
   fZoomMode = 1;

   fArcButton->SetY1(fZoomButton->GetYlowNDC()+0.5*fZoomButton->GetHNDC());
   fTrigPad->Modified();
}

//_____________________________________________________________________________
void AliDisplay::SetPTcut(Float_t ptcut)
{
   fPTcut = ptcut;

   if (!fPad) return;
   fPad->Clear();
   Draw();
}

//_____________________________________________________________________________
void AliDisplay::SetRange(Float_t rrange, Float_t zrange)
{
// Set view range along R and Z
   fRrange = rrange;
   fZrange = zrange;

   if (!fPad) return;
   fPad->Clear();
   Draw();
}
   
//_____________________________________________________________________________
void AliDisplay::SetView(Float_t theta, Float_t phi, Float_t psi)
{
//  change viewing angles for current event

   fPad->cd();
   fDrawAllViews = kFALSE;
   fPhi   = phi;
   fTheta = theta;
   fPsi   = psi;
   Int_t iret = 0;

   TView *view = gPad->GetView();
   if (view) view->SetView(fPhi, fTheta, fPsi, iret);
   else      Draw();

   gPad->Modified();
}

//_____________________________________________________________________________
void AliDisplay::ShowNextEvent(Int_t delta)
{
//  Display (current event_number+delta)
//    delta =  1  shown next event
//    delta = -1 show previous event

  if (delta) {
     gAlice->Clear();
     Int_t current_event = gAlice->GetHeader()->GetEvent();
     Int_t new_event     = current_event + delta;
     gAlice->GetEvent(new_event);
     if (!gAlice->TreeH()) return; 
   }
  LoadPoints();
  fPad->cd(); 
  Draw();
}

//______________________________________________________________________________
void AliDisplay::UnZoom()
{
   if (fZooms <= 0) return;
   fZooms--;
   TPad *pad = (TPad*)gPad->GetPadSave();
   pad->Range(fZoomX0[fZooms],fZoomY0[fZooms], fZoomX1[fZooms],fZoomY1[fZooms]);
   pad->Modified();
}



This archive was generated by hypermail 2b29 : Tue Jan 02 2001 - 11:50:26 MET