How to save an array of custom objects into a file?

I have an array of custom objects, say myobj[M][N], whose class, myclass, is derivated from TObject in order to write/read into/from a disk file.

class myclass : public TObject {
public:
TH1F a, b;

ClassDef(myclass, 1);
}

But this is how far I go. Can’t find instructions/examples dealing with object arrays… :frowning:

Using a dummy object to “cheat” (is this going to give a file which has only the last dummy?) or there is a formal way dealing with object arrays? Using a tree?

Could someone give me an example or some instructions? Thanks!

See an example below in file objarray.C
To run the example, do:

root > .L objarray.C+ root > objarray()

Rene

[code]#include “TH1.h”
#include “TFile.h”
#include “TRandom.h”

class myclass: public TObject {
protected:
TH1F *fA;
TH1F *fB;

public:
myclass();
virtual ~myclass();
myclass(int n);
void Set(int n);

ClassDef(myclass,1)
};

myclass::myclass() {
fA = 0;
fB = 0;
}

myclass::~myclass() {
delete fA;
delete fB;
}

myclass::myclass(int n) {
Set(n);
}

void myclass::Set(int n) {
fA = new TH1F(“A”,“testa”,100,-3,3);
fB = new TH1F(“B”,“testb”,100,-3,3);
if (n <= 0) n=1000;
fA->FillRandom(“gaus”,n);
fA->FillRandom(“landau”,n);
}

void objarray() {
myclass m(5000);
TFile *f = TFile::Open(“objarray.root”,“recreate”);
TH1::AddDirectory(kFALSE);

//write one object to the file
m.Write(“m”);

//create 2-d array and write each array element to the file
myclass m2[10][5];
for (int i=0;i<10;i++) {
for (int j=0;j<5;j++) {
m2[i][j].Set(10i+100j);
m2[i][j].Write(Form(“m2_%d_%d”,i,j));
}
}

//create a 1-d dynamic array of myclass objects
//write all these objects as one single key to to the file
int nm = 25;
TObjArray *array = new TObjArray(nm);
for (int k=0;k<nm;k++) {
myclass m3 = new myclass(100k);
array->AddAt(m3,k);
}
array->Write(“m3”,TObject::kSingleKey);
f->ls();
delete f;
}

[/code]

Hello Rene,
in your above example:[quote] TObjArray *array = new TObjArray(nm); [/quote]
member array is array of identical objects (myclass *m3), so why not: ?

Why is TObjArray class “better” then TClonesArray (in above example) ?

Thanks, Jan

I was just showing an example using TObjArray. You can use a TClonesArray if you like or a std::vector or std::list.
If you use array->Write a TClonesArray will not show any advantage
compared to a TObjArray. If you use a TTree, TClonesArray will be faster.

Rene

  1. Why do you claim *fA and *fB protected? Random choice or there is a deep reason?

    If protected, we have to rewrite a lot TH1F’s methods in order to use them. Then, TH1 really doesn’t help us that much any more…

  2. Is it going to be the same structure if I want it compilable? I follow the similar structure (I have only 2D array “m2” here) and the program is compiled OK but when I run it, it warns me that “fA” and “fB” are being replaced and there is potential memory leak. Here is the information I got.

“Warning in TH1::Build: Replacing existing histogram: fA (Potential memory leak).”

What key part am I possibly missing? Is it that I should claim *fA and *fB "protected"? I tried, but it has the same warning and I got a core dump eventually, same as with when I claim them public.

thanks for your help!

I forgot to mention that I ran your script in the interactive mode sucessfully.

[quote]1. Why do you claim *fA and *fB protected? Random choice or there is a deep reason?If protected, we have to rewrite a lot TH1F’s methods in order to use them. Then, TH1 really doesn’t help us that much any more…
[/quote]
It is a good practice to declare class members private or protected.
These members should be visible only by the class methods.
I do not understand why you could not use TH1 in this case.

[quote]2. Is it going to be the same structure if I want it compilable? I follow the similar structure (I have only 2D array “m2” here) and the program is compiled OK but when I run it, it warns me that “fA” and “fB” are being replaced and there is potential memory leak. Here is the information I got.

“Warning in TH1::Build: Replacing existing histogram: fA (Potential memory leak).”

What key part am I possibly missing? Is it that I should claim *fA and *fB “protected”? I tried, but it has the same warning and I got a core dump eventually, same as with when I claim them public. [/quote]
The Warning message should not appear if you run my code twice.
Could be that you removed the line TH1::AddDirectory(kFALSE).
Please send the shortest possible running script reproducing your problem.

Rene

Sorry for causing the confusion, I meant if they are protected, then we have to provide our own methods to call TH1’s methods since we don’t have direct access to fA and fB in this example.

It’s just that I was worried the warning message was caused by claiming them public.

Problem solved after this option. Thanks!