Use of TRefArray

Hi Rooters,

I have problems using TRefArray. I don’t see the effect of using them …
May be the way to solve my problem is different than using TRefArray ?
So I have one class which threats waveforms, and on class which threats the charges. Note that for each charge “event” we have ~1000 waveform “events”. I would need to be able to make cuts on charge when plotting waveform, and vice versa.
See the code below :

[code]#include
#include
#include <assert.h>
#include
#include <TFile.h>
#include <TTree.h>
#include “sys/stat.h”
#include
#include “TClonesArray.h”
#include “TObjArray.h”
#include “TRefArray.h”

class Wave : public TObject {
public:
Double_t time;
Double_t amp;
ClassDef(Wave,1);
};

class Cha : public TObject {
public:
Double_t Charge;
Double_t Triggertime;
Int_t Ntrig;
TRefArray fWaves;
TRefArray &GetWaves() {return fWaves; }

ClassDef(Cha,1);

};

class Channel : public TNamed {
public:
Channel(const char *name = “not set”) : TNamed(name,“title”),fWaves(“Wave”),fChas(“Cha”) {}

TClonesArray fWaves;
TClonesArray fChas;

Wave *AddWave() {
    return new (fWaves[fWaves.GetEntries()]) Wave;
}
Cha *AddCha() {
    return new (fChas[fChas.GetEntries()]) Cha;
}

void Clear(const char *opt = "") {
    fWaves.Clear(opt);
    fChas.Clear(opt);
}
ClassDef(Channel,1);

};
void gettime(time_t file_creation_time,int &year, int &month, int &day, int &hour, int &minute, int &second);

void ChargeTree(char dirname[100]=".",char fileName[100]=“pmtsignal”,
char outdirname[100]=".",char rfname[100]=“ou1”,
Int_t N_Files_Start=0,Int_t N_Files=2)
{

TFile *f = new TFile(Form("%s/%s.root",outdirname,rfname),"RECREATE");    
TTree *tree = new TTree("T","staff data from ascii file");

TObjArray Channels;
for(Int_t d = 0; d < 4 /* number of Channels */; ++d ) {
Channel *chan = new Channel(TString::Format(“chan_%d”,d));
Channels.Add(chan);
}
tree->Branch(&Channels);

for(int i=0;i<4;i++) Trig[i]  =0;

for(Int_t ifile=N_Files_Start;ifile<N_Files;ifile++){// Loop on files
    Int_t ichan = 0;
    TIter next( &Channels );
    Channel *chan=0;

    while( (chan = (Channel*)next() ) ) { // Loop on Channels 
        chan->Clear();
        triggertime    = 0;
        time_ref       = 0;
        sprintf(filepath,"%s/C%d%s%5.5d.txt",dirname,ichan+1,fileName,ifile);

//--------- time -----------------------------
stat(filepath, &sts);
time_t file_time= sts.st_mtime;
gettime(file_time,year, month, day, hour, minute, second);

ifstream file_in(filepath);

            for(Int_t trig_id=0;trig_id<segments;trig_id++)
            {
                Charge[ichan]=0;
                triggertime = (hour*60+minute)*60. + TrigTime[trig_id];
                Trig[ichan]++;
                Cha *cha = chan->AddCha();

                for(Int_t wave_id=0;wave_id<Segsize;wave_id++)
                {
                    
                    Wave *wave = chan->AddWave();
                    file_in.getline(buf,5000);
                    

                    pt = strtok (buf," ");
                    wave->time      = atof (pt);
                    pt = strtok(NULL,"");
                    wave->amp       = atof (pt);

                    
                    Charge[ichan] += atof (pt);
                    //    cha->fWaves.Add(wave);
                }
                cha->Ntrig          = Trig[ichan];
                cha->Triggertime    = triggertime;
                cha->Charge         = Charge[ichan];
                
            }
        }
        else{
            cout<<" Error opening file : "<<filepath<<endl;
        }            
        file_in.close();       //close file
        ichan++;
    }
    tree->Fill();
}

tree->Write();
tree->Print();
f->Close();

}

void gettime(time_t file_creation_time,int &year, int &month, int &day, int &hour, int &minute, int &second)
{
struct tm *date;
date = localtime(&file_creation_time);

year = date->tm_year - 100;
month = date->tm_mon+1;
day = date->tm_mday;

hour = date->tm_hour;
minute = date->tm_min;
second = date->tm_sec;
}
[/code]
Thanks for your help !

Cheers

[quote]May be the way to solve my problem is different than using TRefArray ? [/quote]Another alternative is to store in the Charge object a collection of indices (the index of the wave in the Channel’s TClonesArray).

[quote]I have problems using TRefArray. I don’t see the effect of using them … [/quote]By default, when dereferencing the content of the TRefArray you must load explicitly the branch containing the referenced object. If you want to automate this you need to call tree->BranchRef(); at the time you are creating the TTree for writing.

Cheers,
Philippe.

Unfortunately, tree->BranchRef() does not solve the problem :frowning:
I.E. we might need waveforms when the integral (charge) is > or < than a value or the other way around (get the charge when the waveform amplitude is > or < than a value or other more fancy condition on the waveform).

Don’t see how can I implement this … :frowning:

Cheers

Hi,

I am still quite confused and what you tried and how it fails …

[quote]It there a possibility to implement a method to automate the waveform integral ? like Charge(time=time0 to time=time1) ? [/quote]Yes, you can implement a method in your class Channel that loops over the content of its arrays.

[quote]… store in the Charge object a collection of indices … Don’t see how can I implement this … [/quote] What I mean is strictly replacing the TRefArray in the class ‘Cha’ with a TArrayI (or a vector of int) and the TArrayI would contain the index of the Wave object in the TClonesArray.

[quote]I have problems using TRefArray. I don’t see the effect of using them …[/quote]One more part of my confusion, you do declare a TRefArray but you never fill it or use it … so I am no idea what effect you expect :slight_smile:.

[quote]I need of course to be able to make cuts between different level … [/quote]In which context do you need to make those cuts (I.e. C++ code, TSelector code, TTree::Draw)? Can you be specific of how you are trying to use those cuts?

Cheers,
Philippe.