Re: [ROOT] TClonesArrays and TObjStrings...

From: Rene Brun (Rene.Brun@cern.ch)
Date: Tue Jul 04 2000 - 17:19:18 MEST


Hi David,
Sorry for this late reply.

When you use myObject->Write() , the class of myObject must have a Streamer
function implemented. see http://root.cern.ch/root/HowtoWrite.html

I have modified your code to be runnable through the script compiler .
To use it, simply do in a Root interactive session:

.L testlist.C++
write()
read()

Rene Brun


#include "TClonesArray.h"
#include "TFile.h"
#include "TObjString.h"
#include "iostream.h"
      
class TESTLIST : public TObject {

public:
  TESTLIST() { fdata = new TClonesArray("TObjString",10); fndata = 0; };
  ~TESTLIST() { fdata->Delete(); };
  void Add(TString l) { new ((*fdata)[fndata++]) TObjString(l); };
  TObjString* At(Int_t i) { return (TObjString*)fdata->At(i); };
  Int_t ndata() { return fndata; };

private:
  TClonesArray *fdata;
  Int_t fndata;
public:

  ClassDef(TESTLIST,1)
};

  ClassImp(TESTLIST)
     
void write() {

  TESTLIST t;
  TObjString line("test line");
  t.Add("test one");
  t.Add("test two");
  t.Add("test three");
  cout << line.String() << endl;
  cout << "Ndata = " << t.ndata() << endl;
  for (Int_t i=0; i<t.ndata(); i++) cout << t.At(i)->String() << endl;

  TFile *f = new TFile("test.root","RECREATE");
  f->cd();
  t.Write("mylist",TObject::kOverwrite);
  line.Write("myline",TObject::kOverwrite);
  f->Close();
  delete f;
}

void read() {

  TFile *f = new TFile("test.root","READ");
  TObjString *l = (TObjString*)f->Get("myline");
  cout << l->String() << endl;
  TESTLIST *t = (TESTLIST*)f->Get("mylist");
  cout << "Ndata = " << t->ndata() << endl;
  for (Int_t i=0; i<t->ndata(); i++) cout << t->At(i)->String() << endl;

}

David Bailey (Antares Post Graduate) wrote:
> 
> Hi rooters,
> 
>   I would like to be able to store a TClonesArray of TStrings ( wrapped in
> TObjStrings ). Say I have a class which has a TClonesArray as a private
> member. I then add TObjStrings to this array during the lifetime of the
> object before writing it to a file. The code below is a simplified example
> which runs in ROOT/CINT. I do the following:
> 
> root [0]> .L testfile.C
> root [1]> main()
> test line
> Ndata = 3
> test one
> test two
> test three
> (Int_t)0
> root [2] read()
> test line
> Ndata = 0
> 
> So, the array is built correctly but the data in the array isn't stored in
> the file... I'm probably missing something obvious about the ROOT I/O
> system. Suggestions? I'm using ROOT 2.25/00 under RH6.1 built from the CVS
> source using the linuxegcs option.
> 
> ---
> 
> class TESTLIST : public TObject {
> 
> public:
>   TESTLIST() { fdata = new TClonesArray("TObjString",10); fndata = 0; };
>   ~TESTLIST() { fdata->Delete(); };
>   void Add(TString l) { new ((*fdata)[fndata++]) TObjString(l); };
>   TObjString* At(Int_t i) { return (TObjString*)fdata->At(i); };
>   Int_t ndata() { return fndata; };
> 
> private:
>   TClonesArray *fdata;
>   Int_t fndata;
> 
> };
> 
> Int_t main() {
> 
>   TESTLIST t;
>   TObjString line("test line");
>   t.Add("test one");
>   t.Add("test two");
>   t.Add("test three");
>   cout << line->String() << endl;
>   cout << "Ndata = " << t.ndata() << endl;
>   for (Int_t i=0; i<t.ndata(); i++) cout << t.At(i).String() << endl;
> 
>   TFile *f = new TFile("test.root","RECREATE");
>   f->cd();
>   t.Write("mylist",TObject::kOverwrite);
>   line.Write("myline",TObject::kOverwrite);
>   f->Close();
>   delete f;
> 
>   return 0;
> 
> }
> 
> void read() {
> 
>   TFile *f = new TFile("test.root","READ");
>   TObjString *l = (TObjString*)f->Get("myline");
>   cout << l->String() << endl;
>   TESTLIST *t = (TESTLIST*)f->Get("mylist");
>   cout << "Ndata = " << t->ndata() << endl;
>   for (Int_t i=0; i<t.ndata(); i++) cout << t.At(i).String() << endl;
> 
> }



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