Hi all,
We like to transfer a TCanvas from shared memory TMapFile into
a server and then via TSocket to the client. This works well for
objects like TH1 and TList and some other.
It works for TCanvas by using some ROOT macros, but we have problems
with the compiled version (KAI C++ 3.3E compiler). I have the impression
that the TCanvas is not completly extracted out of the shared memory.
I'm not absolutetly sure about initialization of root in compiled version,
but more about it later.
I provide the code of the macros and the compiled verions.
here are the code of the macros which are working fine:
*****************************
1.) Producer of shared memory
#ifndef __CINT__
#include <iostream.h>
#include "TROOT.h"
#include "TH1.h"
#include "TH2.h"
#include "TRandom.h"
#include "TMapFile.h"
#include "TSystem.h"
#include "TDirectory.h"
int main ()
{
TROOT producer("producer","Simple histogram producer to shared memory
");
#endif
#ifdef __CINT__
{
gROOT->Reset();
#endif
//Now create the memory map file
//TMapFile *mfile;
// mfile = TMapFile::Create("hsimple.map","RECREATE", 50000,
// "Demo memory mapped file with histograms");
// Create 1d and 2d histograms. These objects will
// be automatically added to the current directory, i.e. mfile.
TCanvas *c1;
TPad *pad1, *pad2, *pad3;
c1 = new TCanvas("c1","Shared Memory Consumer
Example",200,10,700,780);
pad1 = new TPad("pad1","This is pad1",0.02,0.52,0.98,0.98,21);
pad2 = new TPad("pad2","This is pad2",0.02,0.02,0.48,0.48,21);
pad3 = new TPad("pad3","This is pad3",0.52,0.02,0.98,0.48,21);
pad1->Draw();
pad2->Draw();
pad3->Draw();
TH1F *histo1;
TH1F *histo2;
TH2F *histo3;
pad1->cd();
histo1 = new TH1F("histo1","Muon Energy",50,0,30);
histo1->SetXTitle("muon energy");
histo1->SetYTitle("event count");
histo1->SetFillColor(48);
histo1->Draw();
pad2->cd();
histo2 = new TH1F("histo2","Muon Pt",50,0,30);
histo2->SetXTitle("muon pt");
histo2->SetYTitle("event count");
histo2->SetFillColor(48);
histo2->Draw();
pad3->cd();
histo3 = new TH2F("histo3","Muon py vs px",50,0,30,50,0,30);
histo3->SetXTitle("muon px");
histo3->SetYTitle("muon py");
histo3->Draw();
Float_t muon_Energy,muon_Pt,muon_Px,muon_Py;
for (Int_t i = 0; i < 2500; i++) {
//get random number for muon px and py:
gRandom->Rannor(muon_Px,muon_Py);
muon_Px = muon_Px + 10.;
muon_Py = muon_Py + 10.;
muon_Pt = sqrt(muon_Px*muon_Px+muon_Py*muon_Py);
muon_Energy = sqrt(0.105*0.105+muon_Pt*muon_Pt);
histo1->Fill(muon_Energy,1.0);
histo2->Fill(muon_Pt,1.0);
histo3->Fill(muon_Px,muon_Py,1.0);
}
c1->Draw();
//Now create the memory map file
TMapFile *mfile;
mfile = TMapFile::Create("hsimple.map","RECREATE", 50000,
"Demo memory mapped file with histograms");
mfile->Add(c1);
mfile->Update();
mfile->Print();
mfile->ls();
}
******************
2.) reding from shared memory and sending client over TSocket
{
// Open the memory mapped file "hsimple.map" in "READ" (default) mode.
mfile = TMapFile::Create("hsimple.map");
// Print status of mapped file and list its contents
mfile->Print();
mfile->ls();
//gROOT->cd();
TSocket *sock = new TSocket("localhost", 9090);
TMessage mess(kMESS_OBJECT);
TCanvas *c = (TCanvas *) mfile->Get("c1");
c->ls();
c->Draw();
mess.Reset();
printf("hallo1");
mess.WriteObject(c); // write object in message buffer
printf("hallo2");
sock->Send(mess);
}
***************
3.) receiving and displaying in a client macro is no issue.
************************
********here are the codes for the compiled versions
producer is more or less the same:
problems start in the reading of the TCanvas from shared memory, we are
able to
read it ls() and Print() the TMapFile and ls() the TCanvas or
(c1->ListOfPrimitives)->ls() but we are not able to Draw() or Print() the
TCanvas.
code:
#include "TROOT.h"
#include "TApplication.h"
#include "TCanvas.h"
#include "TLine.h"
#include "TPaveLabel.h"
#include <iostream.h>
#include "TH1.h"
#include "TH2.h"
#include "TRandom.h"
#include "TMapFile.h"
#include "TSystem.h"
#include "TDirectory.h"
#include "TPad.h"
#include "TSocket.h"
#include "TMessage.h"
#include "TPad.h"
extern void InitGui();
VoidFuncPtr_t initfuncs[] = { InitGui, 0 };
TROOT root("hello","Hello World", initfuncs);
int main(int argc, char **argv)
{
TApplication theApp("App", &argc, argv);
TMapFile *mfile;
mfile = TMapFile::Create("hsimple.map");
mfile->Print();
mfile->ls();
// gROOT->cd();
TSocket *sock = new TSocket("localhost", 9090);
TMessage mess(kMESS_OBJECT);
TCanvas *c = (TCanvas *) mfile->Get("c1");
printf("hallo1 \n");
c->ls();
printf("hallo1 \n");
(c->GetListOfPrimitives())->ls();
printf("hallo2 \n");
// it works up to here
c->Print();
printf("hallo3 \n");
c->Draw();
mess.Reset();
printf("hallo4 \n");
mess.WriteObject(c); // write object in message buffer
printf("hallo5 \n");
sock->Send(mess);
// Here we don't return from the eventloop. "Exit ROOT" will quit the
app.
theApp.Run();
return 0;
}
By defining another Canvas and drawing it before taking the
Canvas from shared memeory, the situation changes, Print(0 is now possible
and
Draw() too (not really only the canvas without histogramms is displayed)
I think the problem is based in some members of TCanvas which are pointers
and I think are pointing to a certain window scope.
Is there a method to transfer grafic objects via the shared memory
without having to bother about these things or will it be implemented?
Any help will be appreciated.
cheers
Frank
************* (-; ****LIVE LONG AND PROSPER**** ;-) ****************
Frank Hartmann
Institut fuer Experimentelle Kernphysik
*Universitaet Karlsruhe | Forschungszentrum Karlsruhe/Bau 401
Engesserstr. 7 | Hermann-von-Helmholtz-Platz
76128 Karlsruhe | 76344 Eggenstein-Leopoldshafen
Phone: +49-721-608-3418 | Phone: +49-7247-82-4803
Fax: +49-721-607-262 | Fax: +49-7247-82-3414
Email: hartmann@fnal.gov | WWW: http://iekp-kcdf3.fzk.de
------------------------------
Fermilab MS 318
P.O.Box 500 Phone ++1 630 840 8240
Batavia 60510,Il Fax: ++1 630 840 2968
This archive was generated by hypermail 2b29 : Tue Jan 04 2000 - 00:43:42 MET