Re: [ROOT] Problems when calling TBrowser

From: Rene Brun (Rene.Brun@cern.ch)
Date: Tue Jan 02 2001 - 13:33:19 MET


Hi Christian,

1- Difference in TTree::Print
   ==========================
 The ouput of both calls is correct. In the first example, the data
in your struct fits in the branch buffers in memory. These branch buffers
will be written to the file only when you do T.Write().
In the second example, you have 1 basket (buffer) written to the file.
T.Print() reports the compression factor for this buffer.

2- Why your program crashes ?
   ==========================
 You have a scope problem. In your function readarray, you set the
branch address to a local struct. When you leave the scope of this
function,
this address becomes invalid. The browser reads at this invalid address.
One simple solution is to declare your struct in the global scope as shown
in the modified example below.

Rene Brun

//-----begin macro2.C-------
#include "TMatrix.h"
#include <iostream.h>
#include <math.h>

typedef struct {
   Int_t fNRows;
   Int_t fNCols;
   Int_t fLength;
   Float_t fMeas[10000];
} DATA;

   DATA vData;  //<======declared global

void fillarray(Int_t nrow,Int_t ncol)
{
   TFile f("test.root","recreate");
   TTree T("T","a simple test with an array");
   //DATA vData;   <=== this line has been commented


T.Branch("vDataBranch",&vData.fNRows,"fNRows/I:fNCols:fLength:fMeas[fLength]/F");

   Int_t num = nrow*ncol;
   vData.fNRows = nrow;
   vData.fNCols = ncol;
   vData.fLength = num;
   for (Int_t i=0;i<num;i++) {
      vData.fMeas[i] = i;
   }
   T.Fill();

   T.Print();
   T.Write();
}

void readarray()
{
   Int_t nrow;
   Int_t ncol;
   Float_t vArr[100][100];

   TFile *f = new TFile("test.root");
   TTree *T = (TTree*)f->Get("T");

   //DATA vData;   <=== this line has been commented

   T->SetBranchAddress("vDataBranch",&vData.fNRows);
//   TH1F *hed = new TH1F("hed","ma values",100,-100,100);
//   TH2F *hed2 = new TH2F("hed2","ed values",99,0,99,99,0,99);
   TH2F *hed2 = new TH2F("hed2","ed values",100,0,100,100,0,100);

   Int_t nentries = (Int_t)(T->GetEntries());
   cout << "number of entries: " << nentries << endl;

   T->GetEntry();
   cout << "vData.fNRows: " << vData.fNRows << endl;
   cout << "vData.fNCols: " << vData.fNCols << endl;
   cout << "vData.fLength: " << vData.fLength << endl;
   cout << "vData.fMeas0: " << vData.fMeas[0] << endl;
   cout << "vData.fMeas1: " << vData.fMeas[1] << endl;
   cout << "vData.fMeas2: " << vData.fMeas[2] << endl;

   nrow = vData.fNRows;
   ncol = vData.fNCols;
   for (Int_t i=0;i<nrow;i++) {
      for (Int_t j=0;j<ncol;j++) {
         vArr[i][j] = vData.fMeas[i*ncol + j];
         hed2->SetCellContent(i,j,vArr[i][j]);
//         hed->Fill(vArr[i][j]);
      }
   }
   printf("nrows = %i, ncols = %i \n",nrow,ncol);
//   hed->Draw();
   hed2->Draw("col");
}
//---------end macro2.C---------


On Sun, 31 Dec 2000 cstrato@EUnet.at wrote:

> Dear Rooters
> 
> Maybe I am still not quite understanding the way root works,
> since I do not understand the following problem:
> 
> Although the code (macro2.C) seems to work, opening the Browser
> and double-clicking on a variable always causes root to hang
> so that I have to kill root.
> Note that macro2.C is very similar to macro1.C which does work!
> 
> 1, macro1.C:  The following code, taken from Rene Brun, works:
> (Re: [ROOT] variable length "arrays"
>  Date: Sun, 29 Oct 2000 22:23:11 +0100)
> 
> //-----begin macro1.C-------
> typedef struct{
>   int eventnr;
>   int count;
>   float meas[100];
> } event_struct;
> 
> void fillstruct()
> {
>    TFile f("struct.root","recreate");
>    TTree T("T","test struct");
>    event_struct event;
> 
>    T.Branch("first",&event.eventnr,"eventnr/I:count/I:meas[count]/F");
>    for (Int_t i=0;i<10;i++) {
>       event.eventnr = i;
>       event.count = 100*gRandom->Rndm();
>       for (Int_t j=0;j<event.count;j++) event.meas[j] = i+j;
>       T.Fill();
>    }
>    T.Print();
>    T.Write();
> }
> 
> void readstruct()
> {
>    TFile *f = new TFile("struct.root");
>    TTree *T = (TTree*)f->Get("T");
> 
>    event_struct event;
>    T->SetBranchAddress("first",&event.eventnr);
> 
>    Int_t nentries = (Int_t)(T->GetEntries());
>    cout << "number of entries: " << nentries << endl;
> 
>    for (Int_t i=0;i<nentries;i++) {
>       T->GetEntry(i);
>       cout << "event.eventnr " << event.eventnr << " i= " << i << endl;
>       cout << "event.count " << event.count << " i= " << i << endl;
>       cout << "event.meas " << event.meas[i] << " i= " << i << endl;
>    }
> }
> //------end macro1--------
> 
> This is the output:
> //------begin output------
>   *******************************************
>   *                                         *
>   *        W E L C O M E  to  R O O T       *
>   *                                         *
>   *   Version   3.00/00  19 December 2000   *
>   *                                         *
>   *  You are welcome to visit our Web site  *
>   *          http://root.cern.ch            *
>   *                                         *
>   *******************************************
> 
> CINT/ROOT C/C++ Interpreter version 5.14.65, Dec 6 2000
> Type ? for help. Commands must be C++ statements.
> Enclose multiple statements between { }.
> root [0] .L macro1.C
> root [1] fillstruct()
> ******************************************************************************
> 
> *Tree    :T         : test
> struct                                            *
> *Entries :       10 : Total =               0 bytes  File  Size
> =          0 *
> *        :          : Tree compression factor =
> 1.00                       *
> ******************************************************************************
> 
> *Branch  :first     :
> eventnr/I:count/I:meas[count]/F                        *
> *Entries :       10 : Total  Size=          0 bytes  File Size
> =          0 *
> *Baskets :        0 : Basket Size=      32000 bytes  Compression=
> 1.00     *
> *............................................................................*
> 
> root [2] readstruct()
> number of entries: 10
> event.eventnr 0 i= 0
> event.count 10 i= 0
> event.meas 0 i= 0
> event.eventnr 1 i= 1
> event.count 58 i= 1
> event.meas 2 i= 1
> event.eventnr 2 i= 2
> event.count 31 i= 2
> event.meas 4 i= 2
> event.eventnr 3 i= 3
> event.count 14 i= 3
> event.meas 6 i= 3
> event.eventnr 4 i= 4
> event.count 29 i= 4
> event.meas 8 i= 4
> event.eventnr 5 i= 5
> event.count 4 i= 5
> event.meas 9 i= 5
> event.eventnr 6 i= 6
> event.count 15 i= 6
> event.meas 12 i= 6
> event.eventnr 7 i= 7
> event.count 95 i= 7
> event.meas 14 i= 7
> event.eventnr 8 i= 8
> event.count 47 i= 8
> event.meas 16 i= 8
> event.eventnr 9 i= 9
> event.count 58 i= 9
> event.meas 18 i= 9
> root [3] TBrowser b
> root [4] <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
> //------end output------
> 
> In the Browser I can double-click on the fields of the struct,
> and the Canvas displays the data correctly.
> 
> 2, macro2.C: However, the following code, which is as similar to
> macro1.C as possible, has problems with TBrowser:
> 
> //-----begin macro2.C-------
> #include "TMatrix.h"
> #include <iostream.h>
> #include <math.h>
> 
> typedef struct {
>    Int_t fNRows;
>    Int_t fNCols;
>    Int_t fLength;
>    Float_t fMeas[10000];
> } DATA;
> 
> void fillarray(Int_t nrow,Int_t ncol)
> {
>    TFile f("test.root","recreate");
>    TTree T("T","a simple test with an array");
>    DATA vData;
> 
> 
> T.Branch("vDataBranch",&vData.fNRows,"fNRows/I:fNCols:fLength:fMeas[fLength]/F");
> 
>    Int_t num = nrow*ncol;
>    vData.fNRows = nrow;
>    vData.fNCols = ncol;
>    vData.fLength = num;
>    for (Int_t i=0;i<num;i++) {
>       vData.fMeas[i] = i;
>    }
>    T.Fill();
> 
>    T.Print();
>    T.Write();
> }
> 
> void readarray()
> {
>    Int_t nrow;
>    Int_t ncol;
>    Float_t vArr[100][100];
> 
>    TFile *f = new TFile("test.root");
>    TTree *T = (TTree*)f->Get("T");
> 
>    DATA vData;
>    T->SetBranchAddress("vDataBranch",&vData.fNRows);
> //   TH1F *hed = new TH1F("hed","ma values",100,-100,100);
> //   TH2F *hed2 = new TH2F("hed2","ed values",99,0,99,99,0,99);
>    TH2F *hed2 = new TH2F("hed2","ed values",100,0,100,100,0,100);
> 
>    Int_t nentries = (Int_t)(T->GetEntries());
>    cout << "number of entries: " << nentries << endl;
> 
>    T->GetEntry();
>    cout << "vData.fNRows: " << vData.fNRows << endl;
>    cout << "vData.fNCols: " << vData.fNCols << endl;
>    cout << "vData.fLength: " << vData.fLength << endl;
>    cout << "vData.fMeas0: " << vData.fMeas[0] << endl;
>    cout << "vData.fMeas1: " << vData.fMeas[1] << endl;
>    cout << "vData.fMeas2: " << vData.fMeas[2] << endl;
> 
>    nrow = vData.fNRows;
>    ncol = vData.fNCols;
>    for (Int_t i=0;i<nrow;i++) {
>       for (Int_t j=0;j<ncol;j++) {
>          vArr[i][j] = vData.fMeas[i*ncol + j];
>          hed2->SetCellContent(i,j,vArr[i][j]);
> //         hed->Fill(vArr[i][j]);
>       }
>    }
>    printf("nrows = %i, ncols = %i \n",nrow,ncol);
> //   hed->Draw();
>    hed2->Draw("col");
> }
> //---------end macro2.C---------
> 
> This is the output:
> //------begin output------
> [christian@cookiebook xchip]$ root
>   *******************************************
>   *                                         *
>   *        W E L C O M E  to  R O O T       *
>   *                                         *
>   *   Version   3.00/00  19 December 2000   *
>   *                                         *
>   *  You are welcome to visit our Web site  *
>   *          http://root.cern.ch            *
>   *                                         *
>   *******************************************
> 
> CINT/ROOT C/C++ Interpreter version 5.14.65, Dec 6 2000
> Type ? for help. Commands must be C++ statements.
> Enclose multiple statements between { }.
> root [0] .L macro2.C
> root [1] fillarray(90,90)
> ******************************************************************************
> 
> *Tree    :T         : a simple test with an
> array                            *
> *Entries :        1 : Total =           32491 bytes  File  Size =
> 10303 *
> *        :          : Tree compression factor =
> 3.15                       *
> ******************************************************************************
> 
> *Branch  :vDataBranch :
> fNRows/I:fNCols:fLength:fMeas[fLength]/F             *
> *Entries :        1 : Total  Size=      32491 bytes  File Size  =
> 10303 *
> *Baskets :        1 : Basket Size=      32000 bytes  Compression=
> 3.15     *
> *............................................................................*
> 
> root [2] readarray()
> number of entries: 1
> vData.fNRows: 90
> vData.fNCols: 90
> vData.fLength: 8100
> vData.fMeas0: 0
> vData.fMeas1: 1
> vData.fMeas2: 2
> nrows = 90, ncols = 90
> <TCanvas::MakeDefCanvas>: created default TCanvas with name c1
> root [3] TBrowser b
> //--------end output--------
> 
> Now I have the following questions to the following problems:
> 
> 1, Tree-Print(): Why are the entries so different for macro1.C und
> macro2.C?
> 
> 2, TBrowser: When I double-click on fNRows, a value of 10 is shown,
>    although fNRows = 90!! Why is not the right value displayed?
> 
> 3, TBrowser: When I double-click on fNCols, the Browser hangs
>    and I have to kill root. Moreover I also have to close the
>    terminal-window, since it does no longer work either.
>    What is happening here?
> 
> Overall: What did I wrong in my code??? Why does it seem to work?
> 
> (My system: PowerBook with LinuxPPC, running KDE1.1)
> 
> Any help would be greatly appreciated.
> Thank you very much and Happy New Year
> 
> Christian Stratowa
> Vienna, Austria
> 
> 
> 
> 
> 
> 
> 



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