Back Midas Rome Roody Rootana
  Rome Analyzer Framework, Page 4 of 11  Not logged in ELOG logo
ID Date Author Topic Subject
  152   03 Sep 2015 Farrukh AzfarForumARGUS display with canvas and pads ...
Hi Ryu 

thanks ever so much. 

We will modify our code as per your example - is it neccesary to build in development as well or is that only where your example is

-Farrukh

> Dear Farrukh
> 
> What you want to do is probably possible ( I will write a possible method later.).
> However TPad has already several mouse operations (zoom, right-click menu, select active pad and so on); so I am not sure it is the best idea to add own mouse operation (which 
> could override other pre-implemented operations.)
> I will write three solutions below.
> I wrote an example of the first method.
> 
> == Method 1 : Menu ==
> For this solutions, I modified an example in the ROME package.
> The update is done only in the 'develop' branch.
> You can read the example by 'git checkout develop' command after you clone the ROME package.
> The example is in $ROMESYS/examples/argus/menu and the third tab (T3) is one for that.
> In ROME, you can easily add menu items in the menu bar. In the example, menu items to open and save a specific tab are prepared.
> 
> == Method 2 : dedicated buttons ==
> If you prefer buttons instead of menu, you can put dedicated buttons to trigger "OpenPad" function in the example instead of adding menus. The buttons can be implemented 
> either of the following two methods,
>  1) TGTextButton, which can work as the same way as your Save button
>  2) Writing own class derived from TBox or TMarker. A box or maker can be put on each canvas.
> 
> I hope the first method is obvious for you. You can make another button similar to your Save button and call "OpenPad" function.
> 
> The second method is a little more complicated; you make your own class and override "ExecuteEvent" method.
> In the overriding function, you can call any functions when the box or marker is single-clicked, double-clicked, mouse-over and so on.
> A disadvantage is that the box or marker is always visible, and will be drawn in the output PDF files too.
> 
> == Method 3: click on Pad ==
> You can probably do what you write with making own class derived from TPad; then you override "ExecuteEvent" function for calling a function to make a separated canvas and 
> draw a clone of itself.
> You may also need own TCanvas and TRootEmbeddedCanvas for using the customized classes instead of regular TPad and TCanvas.
> 
> If you are satisfied with the first method, please try the example.
> The second method with TGTextButton must not be very difficult.
> 
> If you prefer the second (using TBox or TMarker) and third method, I will investigate if it is actually possible.
> For the two methods, I think you need to write your own classes.
> 
> Best regards,
> 
> Ryu
> 
> > Dear Colleagues,
> > 
> > We are succesfully running a ROME executable both online and offline with an 
> > ARGUS display with a canvas that has multiple pads on it. We have also 
> > implemented a "Save" button which one can click on and save the _entire_ canvas 
> > (containing all the pads) and saves it to pdf.
> > 
> > I was wondering how one would go about making the following modification :
> > 
> > When a user moves a mouse over to a particular pad and clicks on it - then only 
> > the histogram on that pad is displayed on a separate canvas (so the user can 
> > examine it closely) and also save just this one histogram - with a save button 
> > similar to the one we've already written.
> > 
> > many thanks for any insight
> > 
> > Farrukh 
  151   03 Sep 2015 Farrukh AzfarBug ReportSaving canvas as pdf via a button one vs many pads
Dear Colleagues 

we have implemented in one of our tabs a button to call a function which saves a 
canvas to a pdf file with a time date stamp.

1) This works fine when there is only one histogram on the canvas and this code 
is MIDTBCTab.cpp (attached)

2) When the canvas is divided up into a 5x11 pads with 55 histograms and 
we want to save the _whole_ canvas with the whole picture (_not_ any individual 
pads) the code crashes  and no file is generated - the tab code is MIDTRCTab.cpp
and this is also attached 

I am wondering what is going on - is there anything obviously wrong ?

many thanks 

Farrukh
Attachment 1: MIDTBCTab.cpp
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// MIDTBCTab                                                                  //
//                                                                            //
// Begin_Html <!--
/*-->

<!--*/
// --> End_Html
//                                                                            //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

/* Generated header file containing necessary includes                        */
#include "generated/MIDTBCTabGeneratedIncludes.h"

////////////////////////////////////////////////////////////////////////////////
/*  This header was generated by ROMEBuilder. Manual changes above the        *
 * following line will be lost next time ROMEBuilder is executed.             */
/////////////////////////////////////----///////////////////////////////////////

#include "generated/MIDWindow.h"
#include "generated/MIDAnalyzer.h"
#include "tabs/MIDTBCTab.h"
#include "tasks/MIDTFillHistogram.h"
#include "TAxis.h"
#include "TLatex.h"
#include <TGClient.h>
#include <TCanvas.h>

#include <TRandom.h>
#include <TGButton.h>
#include <TGFrame.h>
#include <TRootEmbeddedCanvas.h>
#include <RQ_OBJECT.h>
#include<TString.h>
#include<TDatime.h>
// uncomment if you want to include headers of all folders
//#include "MIDAllFolders.h"


ClassImp(MIDTBCTab)

using namespace std;
//______________________________________________________________________________
void MIDTBCTab::Init()
{
  // Create style for this tab                                                 
  TStyle *orgStyle = gStyle;
  fStyle = new TStyle(*orgStyle); // copy the original style                   
  fStyle->SetOptTitle(1);
  fStyle->SetTitleOffset(0.18, "y");
  fStyle->SetPadGridX(1);
  fStyle->SetPadGridY(1);
  fStyle->SetPadTickX(1);
  fStyle->SetPadTickY(1);
  fStyle->SetFrameBorderSize(0);
  fStyle->SetFrameBorderMode(0);
  fStyle->SetFrameFillStyle(0);
  fStyle->SetTitleSize(0.06, "t");
  fStyle->SetStatH(0.09);
  fStyle->SetStatW(0.09);
  fStyle->cd();
  // Create a vertical frame containing buttons and canvas                     
  fVert = new TGVerticalFrame(this, (UInt_t) (700 * gAnalyzer->GetWindow()->GetWindowScale()), (UInt_t) (700 *gAnalyzer->GetWindow()->GetWindowScale()));

  // Create an embedded canvas and add to the main frame, centered in x and y                                                
  //  TString canvasname = "Sample Canvas";
  
  // set data member 
  fCanvasName =  new TString ("Sample Canvas");
  
  

  fCanvas = new TRootEmbeddedCanvas(fCanvasName->Data(), fVert, (UInt_t) (600 * gAnalyzer->GetWindow()->GetWindowScale()), (UInt_t) (600 * gAnalyzer->GetWindow()->GetWindowScale()));


  fCanvas->GetCanvas()->Divide(1,1);
  TLatex title;
  title.SetTextFont(12);                                                        
  title.SetTextSize(0.03);                                                      
  title.SetNDC(); 


  //Create save button                                                                                                      
  ULong_t green;
  gClient->GetColorByName("Green",green);
  fSaveCanvas = new TGTextButton(fVert, "SaveCanvas");
  fSaveCanvas->ChangeBackground(green);
  fSaveCanvas->Associate(this);
  fVert->AddFrame(fSaveCanvas, new TGLayoutHints(kLHintsCenterX, 5, 5, 3, 4));
                                               
                                                                                                               
                                  
                                                                                                                        /// Create "Update" button                                                    
  ULong_t yellow;
  gClient->GetColorByName("Yellow",yellow);                                            
  fBUpdate = new TGTextButton(fVert, "Update");
  fBUpdate->ChangeBackground(yellow);
  fBUpdate->Associate(this);

  //  fVert->AddFrame(fCanvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 4, 4, 4, 4));
  fVert->AddFrame(fBUpdate, new TGLayoutHints(kLHintsCenterX, 4, 4, 4, 4));
  // AddFrame(fVert, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 4, 4, 4, 4));



  //Create Exit button
  ULong_t red;
  gClient->GetColorByName("Red",red);                                    

  fExit = new TGTextButton(fVert,"&Exit", "gApplication->Terminate(0)");
  fExit->ChangeBackground(red);
  fExit->Associate(this);


  //  fVert->AddFrame(fCanvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 4, 4, 4, 4));
  
fVert->AddFrame(fExit, new TGLayoutHints(kLHintsCenterX, 5, 5, 3, 4));
                                                                                    
   



 fVert->AddFrame(fCanvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 5, 5, 3,  4)); 
 AddFrame(fVert, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 4, 4, 4, 4)); 


  ConnectAll();

  orgStyle->cd();



}

//______________________________________________________________________________
void MIDTBCTab::EndInit()
{
}

//______________________________________________________________________________
void MIDTBCTab::EventHandler()
{
}

//______________________________________________________________________________
void MIDTBCTab::MenuClicked(TGPopupMenu * /* menu */, Long_t /* param */)
{
}

//______________________________________________________________________________
void MIDTBCTab::TabSelected()
{
}

//______________________________________________________________________________
void MIDTBCTab::TabUnSelected()
{
}
  // Save Canvas:
  // you'll need a function of the same signature in your .h -> also make sure that TString is included in your .h
  void MIDTBCTab::SaveCanvas() 
{

 
  TString * fileName = new TString (fCanvasName->Data());

    //replace all spaces in your canvas name 
    fileName->ReplaceAll(" ", "");
    
    //generate data and time stamp -> Recall you'll have to make sure TDatime is included 
    TDatime  dateTime; // time and date remain frozen when this function was called
    TString dateAsString = Form("%d", dateTime.GetDate());
    TString timeAsString = Form("%d", dateTime.GetTime());

    // append time date etc to canvas name

    (*fileName) += ".";
    (*fileName) += dateAsString;
    (*fileName) += ".";
    (*fileName) += timeAsString;
    (*fileName) += ".pdf"; // pdf for now maybe think about png and other options for user later ? 

    // debug
    //    cout << " This is the filename " << fileName->Data() << endl;

    // now print it and hope it works ....
    fCanvas->GetCanvas()->Print(fileName->Data());
    //cout << " Already attempted to print this file  " << fileName->Data() << endl;
}









void MIDTBCTab::Update()
{

  TLatex title;                                                                 
  title.SetTextFont(12);                                                        
  title.SetTextSize(0.03);                                                      
  title.SetNDC(); 

  TStyle *orgStyle = gStyle;
  fStyle->cd();

  TH2 *histo;

  for (Int_t i = 0; i < 1; i++) {
    fCanvas->GetCanvas()->cd(i + 1);
    histo = (TH2D *) gAnalyzer->GetFillHistogramTask()->Geth2_dt_tcpgotheaderAt(i);
    if (!histo) {
      cout << "Histo h2_dt_tcpgotheader not available." << endl;
    } else {

 


      histo->SetMarkerColor(1);
      histo->GetXaxis()->SetRangeUser(-20000,100000);
     
      histo->Draw("COLZ");

                                           
      title.SetTextColor(2);                                                        
                                                                                
                                      
                                                                                
                                                            
                                                                                
      title.SetTextColor(2); 
      title.DrawLatex(0.01,0.32,"tcp header #rightarrow");


      title.SetTextColor(3); 
                           
      title.DrawLatex(0.01,0.4,"tcp data  #rightarrow");                                 

      title.SetTextColor(4); 
      title.DrawLatex(0.01,0.48,"copy to GPU #rightarrow");                         
      title.SetTextColor(5); 
      title.DrawLatex(0.01,0.56,"GPU processing #rightarrow");                      

      title.SetTextColor(6); 
      title.DrawLatex(0.01,0.64,"MFE start #rightarrow");                           
      title.SetTextColor(7); 
      title.DrawLatex(0.01,0.72,"MFE stop #rightarrow");  


    }
  }

  fCanvas->GetCanvas()->cd(0);
  fCanvas->GetCanvas()->Modified();
  fCanvas->GetCanvas()->Update();

  orgStyle->cd();

  return;
}

//______________________________________________________________________________                                              
void MIDTBCTab::ConnectAll()
{
  fBUpdate->Connect("Pressed()", "MIDTBCTab", this, "Update()");
  fExit->Connect("Pressed()", "MIDTBCTab", this, "&Exit()");
  fSaveCanvas->Connect("Pressed()","MIDTBCTab", this, "SaveCanvas()");  
}
//______________________________________________________________________________                                         
void MIDTBCTab::DisconnectAll()
{
  if (fBUpdate) { fBUpdate->Disconnect(this); }
  if (fExit) { fExit->Disconnect(this); }
  if(fSaveCanvas) { fSaveCanvas->Disconnect(this);} 
}

Attachment 2: MIDTRCTab.cpp
////////////////////////////////////////////////////////////////////////////////
//                                                                            //
// MIDTRCTab                                                                  //
//                                                                            //
// Begin_Html <!--
/*-->

<!--*/
// --> End_Html
//                                                                            //
//                                                                            //
////////////////////////////////////////////////////////////////////////////////

/* Generated header file containing necessary includes                        */
#include "generated/MIDTRCTabGeneratedIncludes.h"

////////////////////////////////////////////////////////////////////////////////
/*  This header was generated by ROMEBuilder. Manual changes above the        *
 * following line will be lost next time ROMEBuilder is executed.             */
/////////////////////////////////////----///////////////////////////////////////

#include "generated/MIDWindow.h"
#include "generated/MIDAnalyzer.h"
#include "tabs/MIDTRCTab.h"
#include "tasks/MIDTFillHistogramraw.h"


#include "TAxis.h"
#include "TLatex.h"
#include <TGClient.h>
#include <TCanvas.h>

#include <TRandom.h>
#include <TGButton.h>
#include <TGFrame.h>
#include <TRootEmbeddedCanvas.h>
#include <RQ_OBJECT.h>
#include<TString.h>
#include<TDatime.h>

// uncomment if you want to include headers of all folders
#include "MIDAllFolders.h"


ClassImp(MIDTRCTab)
using namespace std;
//______________________________________________________________________________
void MIDTRCTab::Init()
{
  // Create style for this tab                                                                                                                                         
  TStyle *orgStyle = gStyle;
  fStyle = new TStyle(*orgStyle); // copy the original style                                                                                                           
  fStyle->SetOptTitle(1);
  fStyle->SetTitleOffset(0.38, "y");
  fStyle->SetPadGridX(1);
  fStyle->SetPadGridY(1);
  fStyle->SetPadTickX(1);
  fStyle->SetPadTickY(1);
  fStyle->SetFrameBorderSize(0);
  fStyle->SetFrameBorderMode(0);
  fStyle->SetFrameFillStyle(0);
  fStyle->SetTitleSize(0.06, "t");
  fStyle->SetStatH(0.30);
  fStyle->SetStatW(0.30);
  fStyle->cd();
  // Create a vertical frame containing buttons and canvas                                                                                                             
  fVert = new TGVerticalFrame(this, (UInt_t) (700 * gAnalyzer->GetWindow()->GetWindowScale()), (UInt_t) (700 * gAnalyzer->GetWindow()->GetWindowScale()));

  // Create an embedded canvas and add to the main frame, centered in x and y                                            


  // set data member                                                                                
  fCanvasName =  new TString ("Sample Canvas");


                                              
  fCanvas = new TRootEmbeddedCanvas("Sample Canvas", fVert, (UInt_t) (600 * gAnalyzer->GetWindow()->GetWindowScale()), (UInt_t) (600 * gAnalyzer->GetWindow()->GetWindowScale()));
  fCanvas->GetCanvas()->Divide(5, 11);



  // Create "Update" button                                                    
  ULong_t yellow;
  gClient->GetColorByName("Yellow",yellow);                                                     
  fBUpdate = new TGTextButton(fVert, "Update");
  fBUpdate->ChangeBackground(yellow);
  fBUpdate->Associate(this);

  //  fVert->AddFrame(fCanvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 4, 4, 4, 4));
  fVert->AddFrame(fBUpdate, new TGLayoutHints(kLHintsCenterX, 10, 10, 4, 4));
  AddFrame(fVert, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 10, 10, 4, 4));


  //create Exit button
  ULong_t red;
  gClient->GetColorByName("Red",red);
  fExit = new TGTextButton(fVert, "&Exit", "gApplication->Terminate(0)");
  fExit->ChangeBackground(red);
  fExit->Associate(this);
  fVert->AddFrame(fExit, new TGLayoutHints(kLHintsCenterX, 10, 10, 4, 4));


  //create save button                                                                                                   
                                                                                                                         
  ULong_t green;
  gClient->GetColorByName("Green",green);
  fSaveCanvas = new TGTextButton(fVert, "SaveCanvas");
  fSaveCanvas->ChangeBackground(green);
  fSaveCanvas->Associate(this);
  fVert->AddFrame(fSaveCanvas, new TGLayoutHints(kLHintsCenterX, 10, 10, 4, 4));


  fVert->AddFrame(fCanvas, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 4, 4, 4, 4));
  //  AddFrame(fVert, new TGLayoutHints(kLHintsExpandX | kLHintsExpandY, 4, 4, 4, 4));



  ConnectAll();

  orgStyle->cd();

}

//______________________________________________________________________________
void MIDTRCTab::EndInit()
{
}

//______________________________________________________________________________
void MIDTRCTab::EventHandler()
{
}

//______________________________________________________________________________
void MIDTRCTab::MenuClicked(TGPopupMenu * /* menu */, Long_t /* param */)
{
}

//______________________________________________________________________________
void MIDTRCTab::TabSelected()
{
}

//______________________________________________________________________________
void MIDTRCTab::TabUnSelected()
{
}


  // Save Canvas:                                                                                   
  // you'll need a function of the same signature in your .h -> also make sure that TString is included in your .h                                                                                      
  void MIDTRCTab::SaveCanvas()
{

  // if following doesn't work blame Sabato Leo                                                     
  TString * fileName = new TString (fCanvasName->Data());

  //replace all spaces in your canvas name                                                        
  fileName->ReplaceAll(" ", "");

  //generate data and time stamp -> Recall you'll have to make sure TDatime is included           
  TDatime  dateTime; // time and date remain frozen when this function was called                 
  TString dateAsString = Form("%d", dateTime.GetDate());
  TString timeAsString = Form("%d", dateTime.GetTime());

  // append time date etc to canvas name                                                          

  (*fileName) += ".";
  (*fileName) += dateAsString;
  (*fileName) += ".";
  (*fileName) += timeAsString;
  (*fileName) += ".pdf"; // pdf for now maybe think about png and other options for user later ? 

  // debug                                                                                        
  //cout << " This is the filename " << fileName->Data() << endl;

  // now print it and hope it works ....                                                          
  fCanvas->GetCanvas()->Print(fileName->Data());
  //  cout << " Already attempted to print this file  " << fileName->Data() << endl;
  }





void MIDTRCTab::Update()
{
  TStyle *orgStyle = gStyle;
  fStyle->cd();

  TH1 *histo;

  for (Int_t i = 0; i < 55; i++) { //loop over all 55 pads
    fCanvas->GetCanvas()->cd(i + 1);
    histo = (TH1F *) gAnalyzer->GetFillHistogramrawTask()->Geth1_wfAt(i);
    if (!histo) {
      cout << "Histo ADC not available." << endl;
    } else {
      histo->Draw();
    }
  }

  fCanvas->GetCanvas()->cd(0);
  fCanvas->GetCanvas()->Modified();
  fCanvas->GetCanvas()->Update();

  orgStyle->cd();

  return;




}
//_____________________________________________________________________________\
_                                                                               
void MIDTRCTab::ConnectAll()
{
  fBUpdate->Connect("Pressed()", "MIDTRCTab", this, "Update()");
  fExit->Connect("Pressed()", "MIDTRCTab", this, "&Exit()");
  fSaveCanvas->Connect("Pressed()","MIDTRCTab", this, "SaveCanvas()");

}

//_____________________________________________________________________________\
_                                                                               
void MIDTRCTab::DisconnectAll()
{
  if (fBUpdate) { fBUpdate->Disconnect(this); }
  if (fExit) { fExit->Disconnect(this); }
  if(fSaveCanvas) { fSaveCanvas->Disconnect(this);}

}
  150   03 Sep 2015 Farrukh AzfarForumARGUS display with canvas and pads ...
Hi Ryu

thanks very much - I will certainly look at this example. In the meantime we are having some issues with out save buttons - I will post a thread separately
-Farrukh

> Dear Farrukh
> 
> What you want to do is probably possible ( I will write a possible method later.).
> However TPad has already several mouse operations (zoom, right-click menu, select active pad and so on); so I am not sure it is the best idea to add own mouse operation (which 
> could override other pre-implemented operations.)
> I will write three solutions below.
> I wrote an example of the first method.
> 
> == Method 1 : Menu ==
> For this solutions, I modified an example in the ROME package.
> The update is done only in the 'develop' branch.
> You can read the example by 'git checkout develop' command after you clone the ROME package.
> The example is in $ROMESYS/examples/argus/menu and the third tab (T3) is one for that.
> In ROME, you can easily add menu items in the menu bar. In the example, menu items to open and save a specific tab are prepared.
> 
> == Method 2 : dedicated buttons ==
> If you prefer buttons instead of menu, you can put dedicated buttons to trigger "OpenPad" function in the example instead of adding menus. The buttons can be implemented 
> either of the following two methods,
>  1) TButton, which can work as the same way as your Save button
>  2) Writing own class derived from TBox or TMarker. A box or maker can be put on each canvas.
> 
> I hope the first method is obvious for you. You can make another button similar to your Save button and call "OpenPad" function.
> 
> The second method is a little more complicated; you make your own class and override "ExecuteEvent" method.
> In the overriding function, you can call any functions when the box or marker is single-clicked, double-clicked, mouse-over and so on.
> A disadvantage is that the box or marker is always visible, and will be drawn in the output PDF files too.
> 
> == Method 3: click on Pad ==
> You can probably do what you write with making own class derived from TPad; then you override "ExecuteEvent" function for calling a function to make a separated canvas and 
> draw a clone of itself.
> You may also need own TCanvas and TRootEmbeddedCanvas for using the customized classes instead of regular TPad and TCanvas.
> 
> If you are satisfied with the first method, please try the example.
> The second method with TButton must not be very difficult.
> 
> If you prefer the second (using TBox or TMarker) and third method, I will investigate if it is actually possible.
> For the two methods, I think you need to write your own classes.
> 
> Best regards,
> 
> Ryu
> 
> > Dear Colleagues,
> > 
> > We are succesfully running a ROME executable both online and offline with an 
> > ARGUS display with a canvas that has multiple pads on it. We have also 
> > implemented a "Save" button which one can click on and save the _entire_ canvas 
> > (containing all the pads) and saves it to pdf.
> > 
> > I was wondering how one would go about making the following modification :
> > 
> > When a user moves a mouse over to a particular pad and clicks on it - then only 
> > the histogram on that pad is displayed on a separate canvas (so the user can 
> > examine it closely) and also save just this one histogram - with a save button 
> > similar to the one we've already written.
> > 
> > many thanks for any insight
> > 
> > Farrukh 
  149   03 Sep 2015 Ryu SawadaForumARGUS display with canvas and pads ...
Dear Farrukh

What you want to do is probably possible ( I will write a possible method later.).
However TPad has already several mouse operations (zoom, right-click menu, select active pad and so on); so I am not sure it is the best idea to add own mouse operation (which 
could override other pre-implemented operations.)
I will write three solutions below.
I wrote an example of the first method.

== Method 1 : Menu ==
For this solutions, I modified an example in the ROME package.
The update is done only in the 'develop' branch.
You can read the example by 'git checkout develop' command after you clone the ROME package.
The example is in $ROMESYS/examples/argus/menu and the third tab (T3) is one for that.
In ROME, you can easily add menu items in the menu bar. In the example, menu items to open and save a specific tab are prepared.

== Method 2 : dedicated buttons ==
If you prefer buttons instead of menu, you can put dedicated buttons to trigger "OpenPad" function in the example instead of adding menus. The buttons can be implemented 
either of the following two methods,
 1) TGTextButton, which can work as the same way as your Save button
 2) Writing own class derived from TBox or TMarker. A box or maker can be put on each canvas.

I hope the first method is obvious for you. You can make another button similar to your Save button and call "OpenPad" function.

The second method is a little more complicated; you make your own class and override "ExecuteEvent" method.
In the overriding function, you can call any functions when the box or marker is single-clicked, double-clicked, mouse-over and so on.
A disadvantage is that the box or marker is always visible, and will be drawn in the output PDF files too.

== Method 3: click on Pad ==
You can probably do what you write with making own class derived from TPad; then you override "ExecuteEvent" function for calling a function to make a separated canvas and 
draw a clone of itself.
You may also need own TCanvas and TRootEmbeddedCanvas for using the customized classes instead of regular TPad and TCanvas.

If you are satisfied with the first method, please try the example.
The second method with TGTextButton must not be very difficult.

If you prefer the second (using TBox or TMarker) and third method, I will investigate if it is actually possible.
For the two methods, I think you need to write your own classes.

Best regards,

Ryu

> Dear Colleagues,
> 
> We are succesfully running a ROME executable both online and offline with an 
> ARGUS display with a canvas that has multiple pads on it. We have also 
> implemented a "Save" button which one can click on and save the _entire_ canvas 
> (containing all the pads) and saves it to pdf.
> 
> I was wondering how one would go about making the following modification :
> 
> When a user moves a mouse over to a particular pad and clicks on it - then only 
> the histogram on that pad is displayed on a separate canvas (so the user can 
> examine it closely) and also save just this one histogram - with a save button 
> similar to the one we've already written.
> 
> many thanks for any insight
> 
> Farrukh 
  148   02 Sep 2015 Farrukh AzfarForumARGUS display with canvas and pads ...
Dear Colleagues,

We are succesfully running a ROME executable both online and offline with an 
ARGUS display with a canvas that has multiple pads on it. We have also 
implemented a "Save" button which one can click on and save the _entire_ canvas 
(containing all the pads) and saves it to pdf.

I was wondering how one would go about making the following modification :

When a user moves a mouse over to a particular pad and clicks on it - then only 
the histogram on that pad is displayed on a separate canvas (so the user can 
examine it closely) and also save just this one histogram - with a save button 
similar to the one we've already written.

many thanks for any insight

Farrukh 
  147   15 Jun 2015 Ryu SawadaBug ReportProblems with programming tabs when using TGraph
Dear Farrukh

If you attach your code related to the problem, I can investigate the problem.

Best regards,

Ryu


Farrukh Azfar wrote:
Hi Ryu,

thanks for your reply. yes I am(was) using it.


Ryu Sawada wrote:
Dear Farrukh

I presume you implemented your tab which draws the graph.
Which option do you use for Draw function of the graph ?
I am afraid you might forget to add 'A' in the option.
For example, you need to use 'A' like,
  graph->Draw("APL");

Best regards,

Ryu

> Dear Colleagues,
>
> I have been using the ROME framework and have succesfully implemented a program
> to run on MIDAS input and plot histograms.
>
> Not satisfied with the default settings of the Canvas, pads and text sizes etc I
> consulted Ryu who kindly showed me how to implement the event and init and update
> methods in the Tabs to bring the display closer to what I needed.
>
> This has worked fine with histograms. However not with TGraphs:
>
> I noticed that if I implemented the plotting of the TGraphs in the tab class then
> after setting points in the TGraph in the Fill tasks the Tab classes plot was
> empty -> is there something peculiar about TGraph ? Any tips would be great !
>
> many thanks
> Farrukh Azfar
  146   15 Jun 2015 Ryu SawadaInfoROME examples : histoGUI
Dear Farrukh

ProcessEvents is nothing to do with ROME.
It is a ROOT function to process events called by timer, click, sockets etc.
"event" is not MIDAS event, but for example, an event where someone clicked a button.
For example, if you click an "update" button, ROOT needs to call a function connected to the button; ProcessEvents does the job.
So if you want to use the GUI during the sleep of a task, you need to call ProcessEvents sometimes.

https://root.cern.ch/root/html604/TSystem.html#TSystem:ProcessEvents

You need not to overwrite ProcessEvents.

Best regards,

Ryu


Farrukh Azfar wrote:
Dear Ryu,

many thanks for your reply that's very useful.

For my knowledge and for the sake of understanding the basics.

1) Its the line : gSystem->ProcessEvents(); that calls all the event methods in the Fill classes and the Tabs classes yes ?

2) This way I am controlling the filling of the tabs at an interval regulated by "sleep" then what has happened to the program itself calling ProcessEvents ? Have I overriden that call by calling ProcessEvents or will it continue to be called - perhaps I just set the <UpdateFrequency> 0</UpdateFrequency> to disable the programs own calling and only use mine ?

I hope I've been clear. Thanks very much for your continued help.

-Farrukh




Ryu Sawada wrote:
Dear Farrukh

If you want to control the frequency of update of all tabs, maybe, you could use the same method (namely using 'none' DAQ') for calling event methods of tasks and tabs also for non-event based
application.
You may add a task in which you only call 'sleep' function for controlling the frequency.
For allowing you to use GUI buttons also during the sleep, you need to call the sleep function like following.
ProcessEvents function allows you to use GUI parts also during the sleep.
   Int_t sec = GetSP()->GetSleepTime();

   if (sec > 0) {
      struct timespec req, rem;
      req.tv_sec = 0;
      req.tv_nsec = 100000000; // sleep time in loop

      struct timeval endTime, currentTime;
      gettimeofday(&currentTime, 0);
      endTime.tv_sec = currentTime.tv_sec + sec;
      endTime.tv_usec = currentTime.tv_usec;

      int ret;

      while(1) {
         memset(&rem, 0, sizeof(rem));
         ret = nanosleep(&req, &rem);

         gettimeofday(&currentTime, 0);
         if (currentTime.tv_sec > endTime.tv_sec ||
             (currentTime.tv_sec == endTime.tv_sec && currentTime.tv_usec > endTime.tv_usec)) {
            break;
         }

         gSystem->ProcessEvents();
      }
   }

gettimeofday is defined in sys/time.h header file in UNIX-like OS.
gSystem is in TSystem.h

For controlling the frequency, in this example, I added a new steering parameter for the task, which is defined like,
     <Task>
  ... other definition of tasks ...
        <SteeringParameters>
          <SteeringParameterField>
            <SPFieldName>SleepTime</SPFieldName>
            <SPFieldType>Int_t</SPFieldType>
            <SPFieldInitialization>10</SPFieldInitialization>
            <SPFieldComment>Sleep time in sec</SPFieldComment>
          </SteeringParameterField>
        </SteeringParameters>
     </Task>

Best regards,

Ryu

> Dear Farrukh
>
> The 'histoGUI' example was prepared as an example for displaying histograms.
> And the data are generated randomly in FillHisto task instead of reading from an input file.
> So the example is using 'none' DAQ as written in romeConfig.xml in the example; the DAQ class is
> implemented in include/ROMENoDAQSystem.h, and it actually does nothing.
>
> With 'none' DAQ, the program simply call Event method continuously without any control of the frequency.
>
> When you run the example, the frequency is not so fast because the CPU is used for updating the display.
> If you change <UpdateFrequency>, for example, to 10000, you will find the frequency of events through
> the task is increased because you update the display with a less frequency (thus lower CPU power is
> needed).
>
> If you are going to use ROME for non-event based application, there are two ways to call some functions
> defined in tabs.
> 1) With GUI parts, like buttons, menus, sliders and so on
> 2) With calling a function periodically.
>
> 1) is suitable if you want to actively control the GUI; a user needs to, for example, click a button for
> operate the tab.
>
> 2) is suitable if you want to update the display without any operations.
> You can see examples/argus/timer/ and examples/argus/thread as examples.
>
> Best regards,
>
> Ryu
>
> > Dear Colleagues,
> >
> > I have succesfully written a ROME application for monitoring MIDAS events and
> > understand that the appearance of a new MIDAS event record triggers the calling
> > of the event method in the Fill Histogram task.
> >
> > My two questions are however about the example in $ROMESYS/example/histoGUI -
> >
> > 1) In this example there is no MIDAS event nor event record - what then is
> > triggering the calling of the event method
> >
> > 2) Is it possible to regulate the frequency that the event method is called in
> > this example ?
> >
> > best wishes
> > Farrukh Azfar
  Draft   13 Jun 2015 Farrukh AzfarBug ReportProblems with programming tabs when using TGraph
Hi Ryu,

thanks for your reply. yes I am(was) using it.


Ryu Sawada wrote:
Dear Farrukh

I presume you implemented your tab which draws the graph.
Which option do you use for Draw function of the graph ?
I am afraid you might forget to add 'A' in the option.
For example, you need to use 'A' like,
  graph->Draw("APL");

Best regards,

Ryu

> Dear Colleagues,
>
> I have been using the ROME framework and have succesfully implemented a program
> to run on MIDAS input and plot histograms.
>
> Not satisfied with the default settings of the Canvas, pads and text sizes etc I
> consulted Ryu who kindly showed me how to implement the event and init and update
> methods in the Tabs to bring the display closer to what I needed.
>
> This has worked fine with histograms. However not with TGraphs:
>
> I noticed that if I implemented the plotting of the TGraphs in the tab class then
> after setting points in the TGraph in the Fill tasks the Tab classes plot was
> empty -> is there something peculiar about TGraph ? Any tips would be great !
>
> many thanks
> Farrukh Azfar
  144   13 Jun 2015 Farrukh AzfarInfoROME examples : histoGUI
Dear Ryu,

many thanks for your reply that's very useful.

For my knowledge and for the sake of understanding the basics.

1) Its the line : gSystem->ProcessEvents(); that calls all the event methods in the Fill classes and the Tabs classes yes ?

2) This way I am controlling the filling of the tabs at an interval regulated by "sleep" then what has happened to the program itself calling ProcessEvents ? Have I overriden that call by calling ProcessEvents or will it continue to be called - perhaps I just set the <UpdateFrequency> 0</UpdateFrequency> to disable the programs own calling and only use mine ?

I hope I've been clear. Thanks very much for your continued help.

-Farrukh




Ryu Sawada wrote:
Dear Farrukh

If you want to control the frequency of update of all tabs, maybe, you could use the same method (namely using 'none' DAQ') for calling event methods of tasks and tabs also for non-event based
application.
You may add a task in which you only call 'sleep' function for controlling the frequency.
For allowing you to use GUI buttons also during the sleep, you need to call the sleep function like following.
ProcessEvents function allows you to use GUI parts also during the sleep.
   Int_t sec = GetSP()->GetSleepTime();

   if (sec > 0) {
      struct timespec req, rem;
      req.tv_sec = 0;
      req.tv_nsec = 100000000; // sleep time in loop

      struct timeval endTime, currentTime;
      gettimeofday(&currentTime, 0);
      endTime.tv_sec = currentTime.tv_sec + sec;
      endTime.tv_usec = currentTime.tv_usec;

      int ret;

      while(1) {
         memset(&rem, 0, sizeof(rem));
         ret = nanosleep(&req, &rem);

         gettimeofday(&currentTime, 0);
         if (currentTime.tv_sec > endTime.tv_sec ||
             (currentTime.tv_sec == endTime.tv_sec && currentTime.tv_usec > endTime.tv_usec)) {
            break;
         }

         gSystem->ProcessEvents();
      }
   }

gettimeofday is defined in sys/time.h header file in UNIX-like OS.
gSystem is in TSystem.h

For controlling the frequency, in this example, I added a new steering parameter for the task, which is defined like,
     <Task>
  ... other definition of tasks ...
        <SteeringParameters>
          <SteeringParameterField>
            <SPFieldName>SleepTime</SPFieldName>
            <SPFieldType>Int_t</SPFieldType>
            <SPFieldInitialization>10</SPFieldInitialization>
            <SPFieldComment>Sleep time in sec</SPFieldComment>
          </SteeringParameterField>
        </SteeringParameters>
     </Task>

Best regards,

Ryu

> Dear Farrukh
>
> The 'histoGUI' example was prepared as an example for displaying histograms.
> And the data are generated randomly in FillHisto task instead of reading from an input file.
> So the example is using 'none' DAQ as written in romeConfig.xml in the example; the DAQ class is
> implemented in include/ROMENoDAQSystem.h, and it actually does nothing.
>
> With 'none' DAQ, the program simply call Event method continuously without any control of the frequency.
>
> When you run the example, the frequency is not so fast because the CPU is used for updating the display.
> If you change <UpdateFrequency>, for example, to 10000, you will find the frequency of events through
> the task is increased because you update the display with a less frequency (thus lower CPU power is
> needed).
>
> If you are going to use ROME for non-event based application, there are two ways to call some functions
> defined in tabs.
> 1) With GUI parts, like buttons, menus, sliders and so on
> 2) With calling a function periodically.
>
> 1) is suitable if you want to actively control the GUI; a user needs to, for example, click a button for
> operate the tab.
>
> 2) is suitable if you want to update the display without any operations.
> You can see examples/argus/timer/ and examples/argus/thread as examples.
>
> Best regards,
>
> Ryu
>
> > Dear Colleagues,
> >
> > I have succesfully written a ROME application for monitoring MIDAS events and
> > understand that the appearance of a new MIDAS event record triggers the calling
> > of the event method in the Fill Histogram task.
> >
> > My two questions are however about the example in $ROMESYS/example/histoGUI -
> >
> > 1) In this example there is no MIDAS event nor event record - what then is
> > triggering the calling of the event method
> >
> > 2) Is it possible to regulate the frequency that the event method is called in
> > this example ?
> >
> > best wishes
> > Farrukh Azfar
  143   11 Jun 2015 Ryu SawadaInfoROME examples : histoGUI
Dear Farrukh

If you want to control the frequency of update of all tabs, maybe, you could use the same method (namely using 'none' DAQ') for calling event methods of tasks and tabs also for non-event based
application.
You may add a task in which you only call 'sleep' function for controlling the frequency.
For allowing you to use GUI buttons also during the sleep, you need to call the sleep function like following.
ProcessEvents function allows you to use GUI parts also during the sleep.
   Int_t sec = GetSP()->GetSleepTime();

   if (sec > 0) {
      struct timespec req, rem;
      req.tv_sec = 0;
      req.tv_nsec = 100000000; // sleep time in loop

      struct timeval endTime, currentTime;
      gettimeofday(&currentTime, 0);
      endTime.tv_sec = currentTime.tv_sec + sec;
      endTime.tv_usec = currentTime.tv_usec;

      int ret;

      while(1) {
         memset(&rem, 0, sizeof(rem));
         ret = nanosleep(&req, &rem);

         gettimeofday(&currentTime, 0);
         if (currentTime.tv_sec > endTime.tv_sec ||
             (currentTime.tv_sec == endTime.tv_sec && currentTime.tv_usec > endTime.tv_usec)) {
            break;
         }

         gSystem->ProcessEvents();
      }
   }

gettimeofday is defined in sys/time.h header file in UNIX-like OS.
gSystem is in TSystem.h

For controlling the frequency, in this example, I added a new steering parameter for the task, which is defined like,
     <Task>
  ... other definition of tasks ...
        <SteeringParameters>
          <SteeringParameterField>
            <SPFieldName>SleepTime</SPFieldName>
            <SPFieldType>Int_t</SPFieldType>
            <SPFieldInitialization>10</SPFieldInitialization>
            <SPFieldComment>Sleep time in sec</SPFieldComment>
          </SteeringParameterField>
        </SteeringParameters>
     </Task>

Best regards,

Ryu

> Dear Farrukh
>
> The 'histoGUI' example was prepared as an example for displaying histograms.
> And the data are generated randomly in FillHisto task instead of reading from an input file.
> So the example is using 'none' DAQ as written in romeConfig.xml in the example; the DAQ class is
> implemented in include/ROMENoDAQSystem.h, and it actually does nothing.
>
> With 'none' DAQ, the program simply call Event method continuously without any control of the frequency.
>
> When you run the example, the frequency is not so fast because the CPU is used for updating the display.
> If you change <UpdateFrequency>, for example, to 10000, you will find the frequency of events through
> the task is increased because you update the display with a less frequency (thus lower CPU power is
> needed).
>
> If you are going to use ROME for non-event based application, there are two ways to call some functions
> defined in tabs.
> 1) With GUI parts, like buttons, menus, sliders and so on
> 2) With calling a function periodically.
>
> 1) is suitable if you want to actively control the GUI; a user needs to, for example, click a button for
> operate the tab.
>
> 2) is suitable if you want to update the display without any operations.
> You can see examples/argus/timer/ and examples/argus/thread as examples.
>
> Best regards,
>
> Ryu
>
> > Dear Colleagues,
> >
> > I have succesfully written a ROME application for monitoring MIDAS events and
> > understand that the appearance of a new MIDAS event record triggers the calling
> > of the event method in the Fill Histogram task.
> >
> > My two questions are however about the example in $ROMESYS/example/histoGUI -
> >
> > 1) In this example there is no MIDAS event nor event record - what then is
> > triggering the calling of the event method
> >
> > 2) Is it possible to regulate the frequency that the event method is called in
> > this example ?
> >
> > best wishes
> > Farrukh Azfar
  142   11 Jun 2015 Konstantin OlchanskiInfoROME examples : histoGUI
> I have succesfully written a ROME application ...

For the record, at TRIUMF we have moved away from ROME towards the ROOTANA ROOT-based analyzer 
package which has some simple C++ classes for reading midas raw data, some simple classes and examples for 
working with midas data in ROOT, and some fairly advanced graphical example applications.

https://bitbucket.org/tmidas/rootana

K.O.
  141   11 Jun 2015 Ryu SawadaBug ReportProblems with programming tabs when using TGraph
Dear Farrukh

I presume you implemented your tab which draws the graph.
Which option do you use for Draw function of the graph ?
I am afraid you might forget to add 'A' in the option.
For example, you need to use 'A' like,
  graph->Draw("APL");

Best regards,

Ryu

> Dear Colleagues,
>
> I have been using the ROME framework and have succesfully implemented a program
> to run on MIDAS input and plot histograms.
>
> Not satisfied with the default settings of the Canvas, pads and text sizes etc I
> consulted Ryu who kindly showed me how to implement the event and init and update
> methods in the Tabs to bring the display closer to what I needed.
>
> This has worked fine with histograms. However not with TGraphs:
>
> I noticed that if I implemented the plotting of the TGraphs in the tab class then
> after setting points in the TGraph in the Fill tasks the Tab classes plot was
> empty -> is there something peculiar about TGraph ? Any tips would be great !
>
> many thanks
> Farrukh Azfar
  140   11 Jun 2015 Ryu SawadaInfoROME examples : histoGUI
Dear Farrukh

The 'histoGUI' example was prepared as an example for displaying histograms.
And the data are generated randomly in FillHisto task instead of reading from an input file.
So the example is using 'none' DAQ as written in romeConfig.xml in the example; the DAQ class is 
implemented in include/ROMENoDAQSystem.h, and it actually does nothing.

With 'none' DAQ, the program simply call Event method continuously without any control of the frequency.

When you run the example, the frequency is not so fast because the CPU is used for updating the display.
If you change <UpdateFrequency>, for example, to 10000, you will find the frequency of events through 
the task is increased because you update the display with a less frequency (thus lower CPU power is 
needed).

If you are going to use ROME for non-event based application, there are two ways to call some functions 
defined in tabs.
1) With GUI parts, like buttons, menus, sliders and so on
2) With calling a function periodically.

1) is suitable if you want to actively control the GUI; a user needs to, for example, click a button for 
operate the tab.

2) is suitable if you want to update the display without any operations.
You can see examples/argus/timer/ and examples/argus/thread as examples.

Best regards,

Ryu

> Dear Colleagues,
> 
> I have succesfully written a ROME application for monitoring MIDAS events and 
> understand that the appearance of a new MIDAS event record triggers the calling 
> of the event method in the Fill Histogram task.
> 
> My two questions are however about the example in $ROMESYS/example/histoGUI - 
> 
> 1) In this example there is no MIDAS event nor event record - what then is 
> triggering the calling of the event method 
> 
> 2) Is it possible to regulate the frequency that the event method is called in 
> this example ?
> 
> best wishes
> Farrukh Azfar
  139   09 Jun 2015 Farrukh AzfarBug ReportProblems with programming tabs when using TGraph
Dear Colleagues,
 
I have been using the ROME framework and have succesfully implemented a program 
to run on MIDAS input and plot histograms.

Not satisfied with the default settings of the Canvas, pads and text sizes etc I 
consulted Ryu who kindly showed me how to implement the event and init and update 
methods in the Tabs to bring the display closer to what I needed.

This has worked fine with histograms. However not with TGraphs:

I noticed that if I implemented the plotting of the TGraphs in the tab class then 
after setting points in the TGraph in the Fill tasks the Tab classes plot was 
empty -> is there something peculiar about TGraph ? Any tips would be great !

many thanks
Farrukh Azfar
  138   09 Jun 2015 Farrukh AzfarInfoROME examples : histoGUI
Dear Colleagues,

I have succesfully written a ROME application for monitoring MIDAS events and 
understand that the appearance of a new MIDAS event record triggers the calling 
of the event method in the Fill Histogram task.

My two questions are however about the example in $ROMESYS/example/histoGUI - 

1) In this example there is no MIDAS event nor event record - what then is 
triggering the calling of the event method 

2) Is it possible to regulate the frequency that the event method is called in 
this example ?

best wishes
Farrukh Azfar
  137   09 Jun 2008 Stefan RittForumRome License
> I was wondering what type of license, if any, applies to the Rome distribution.
> Midas is using GPL and Root is using LGPL.

Midas uses GPL because when I started that project, the LGPL was not yet in
existence. If anybody want Midas under the LGPL, I could consider switching that.
ROME is under the LGPL.
  136   06 Jun 2008 Todd BredewegForumRome License
I was wondering what type of license, if any, applies to the Rome distribution.
Midas is using GPL and Root is using LGPL.
  135   18 Apr 2007 Ryu SawadaInfoI/O system change
I changed default type of dictionaries. By this change we use new I/O system introduced at ROOT version 3.

A newly generated program can not read old files created by old programs by default. Error messages like following will be shown.
Error in <TBuffer::CheckByteCount>: object of class PMTData read too few bytes: 21 instead of 169

There is one flag to avoid this problem. When <DictionaryType> in <Experiment> is 0, romebuilder will
generate a program with old dictionary type.
<Experiment>
   <ExperimentName>MEG Analysis and monitor.</ExperimentName>
   <ExperimentShortCut>MEG</ExperimentShortCut>
   <ProgramName>Analyzer</ProgramName>
   <ProgramDefinitionVersion>3</ProgramDefinitionVersion>
   <FrameworkDescription>MEGAnalyzer is an analysis framework for MEG. It works as monitor as well.</FrameworkDescription>
   <DictionaryType>0</DictionaryType>   <!-- Add this line -->
</Experiment>

During development stage of version 2.9, we will check if there are problems in the new I/O system.
If we don't find any problems, The new I/O system will be the default of ROME version 2.9.
Even if we change the default, users can continue using the old I/O by using the flag.
  134   28 Feb 2007 Ryu SawadaForumDuplicate header file
> > > > I just started using Rome v2.7 and Root v5.14.00. I have run into a rather
> > > > interesting issue trying to compile my analyzer. I tracked the problem to the
> > > > fact that both Root and Rome are loading their own version of a header file
> > > > called TArrayL64.h.
> > 
> > I have just run into the TArrayL64.h problem myself. I recommend that we resolve
> > the clashing header files. We could ask Rene Brun to rename his file or we could
> > rename the clashing file in Rome.
> > 
> > K.O.
> 
> As Matthias mensioned, this problem is solved in SVN version of ROME.
> I propose to release ROME version 2.8, which will not have this problem.
> 
> If there are users who want to continue to use 2.7, we could also release patch release of 2.7. (2.7.1), in which only compatibility problems 
> are fixed.

I prepared a new release 2.8. It can be downloaded from http://midas.psi.ch/rome/download.html

The new release works with also ROOT 5.14 or 5.15.

At this release, style of configuration file was changed. Please see following message for details. 
https://ladd00.triumf.ca/elog/Rome/129
  133   28 Feb 2007 Ryu SawadaForumDuplicate header file
> > > I just started using Rome v2.7 and Root v5.14.00. I have run into a rather
> > > interesting issue trying to compile my analyzer. I tracked the problem to the
> > > fact that both Root and Rome are loading their own version of a header file
> > > called TArrayL64.h.
> 
> I have just run into the TArrayL64.h problem myself. I recommend that we resolve
> the clashing header files. We could ask Rene Brun to rename his file or we could
> rename the clashing file in Rome.
> 
> K.O.

As Matthias mensioned, this problem is solved in SVN version of ROME.
I propose to release ROME version 2.8, which will not have this problem.

If there are users who want to continue to use 2.7, we could also release patch release of 2.7. (2.7.1), in which only compatibility problems 
are fixed.

Ryu
ELOG V3.1.4-2e1708b5