Double_t in a TList

Hi,

I whish to know if it was possible to add many variables declared as Double_t in a TList ?

c:\Documents and Settings\alice\Mes documents\Visual Studio Projects\BenchTest\BenchTest\Channel.cpp(286) : error C2440: ‘cast de type’ : impossible de convertir de ‘TObject *’ en 'double’
Aucun contexte dans lequel cette conversion est possible

Thanks

Only objects derived from TObject can be added to a TList.
To add an array of Double_t use a TVectorD object.

Rene

Thanks Rene,

I had never used the “TVectorD”, another aspect which I discover. and a powerfull solution !!!

Best Regards

Hi there,

TVectorD (TVectorT in the reference guide) is limited to 5 elements.
I’m trying to find a way to work with a linked list of doubles in CINT.
I’ve come up with this

TList *mylist = new TList() ; for (Int_t i=0 ; i<10 ; i++) { mylist->Add(new TParameter<double>(TString::Format("x%02d",i),i*1.)) ; } for (Int_t i=0 ; i<mylist->Capacity() ; i++) { printf("\n%f",((TParameter<double>*)(mylist->At(i)))->GetVal()) ; }There should be an easier way though.

TIA,
Z

TVectorD can contain as many elements as you wish.
When the vector has 5 or less elements, they are kept internally
on the stack , otherwise on the heap. But that should be of
no concern to the user.

Eddy

Thanks for the correction.
So here comes my stupid question: How do you fill a TVectorD?
I didn’t manage to find any Add()-like method (like in TList or any linked list class).
Thanks,
Z

TVectorD is part of the linear algebra classes and not a container,
so no Add() functions or iterators.
Filling is described in

root.cern.ch/root/HowtoCreateMatrix.html

So this is not a linked list.
Then my question still lies.
Is there any easier way than that proposed above to implement a linked list of doubles working in CINT?
Thanks,
Z

Hi,

Simply use:root [0] #include <list> root [1] list<double> list; root [2] list.push_back(1.0);Cheers,
Philippe.

Thanks Philippe.
So there must have been some (nice) improvements in CINT.
I’m pretty sure the following macro did not work in the past:

vector<Double_t> *mylist = new vector<Double_t> ; mylist->push_back(1.); mylist->push_back(3.); for (Int_t i=0 ; i<mylist->size() ; i++) { printf ("\n%f",mylist->at(i)) ; }It does now. So much the better! :slight_smile:

On the contrary, the result is more mitigated with TObjects: :cry:

Double_t x[3] = {1.,2.,3.} ; Double_t y[3] = {1.,2.,3.} ; vector<TGraph*> *mylist = new vector<TGraph*> ; mylist->push_back(new TGraph (3,x,y)); mylist->push_back(new TGraph (3,x,y)); printf ("\n%f\n",mylist->at(1)->GetX()[2]) ; /// DOES work in CINT for (Int_t i=0 ; i<mylist->size() ; i++) { printf ("\n%f",mylist->at(i)->GetX()[0]) ; } /// DOES NOT work in CINT (works fine with ACLIC)This could be overcome using TList at the expense of very irritating necessary “cast wrapping”:

Double_t x[3] = {1.,2.,3.} ; Double_t y[3] = {1.,2.,3.} ; TList *mylist = new TList() ; mylist->Add(new TGraph (3,x,y)); mylist->Add(new TGraph (3,x,y)); printf ("\n%f\n",((TGraph*)(mylist->At(1)))->GetX()[2]) ; for (Int_t i=0 ; i<mylist->GetSize() ; i++) { printf ("\n%f",((TGraph*)(mylist->At(i)))->GetX()[2]) ; }Unless anyone has a nice hint to share… [-o<

TIA,
Z

Hi,

To properly use an STL container you need (in most case) to generate a dictionary for int. For list the dictionary is provided with the ROOT build (and its loading is triggered by the #include). For the STL instances we do not provide a dictionary for (for example vector<TGraph*>) you need to generate it your self with is as simple as writing this small file:// loader.C #include <vector> #include "TGraph.h" #ifdef __MAKECINT__ #pragma link C++ class vector<TGraph*>+; #endifand load it into your via ACLiC:root [] .L loader.C+

Cheers,
Philippe.

:smiley:
Thank you so much Philippe.
Z

Hi Philippe,
Is there any way to cope with such templates:

[code]#include <TROOT.h>
#include <TClass.h>
#include <TH1.h>
#include <TH2.h>

#ifdef MAKECINT
// #pragma link C++ ?
#endif

template
void MRF_binarizeHisto ( ATH* histo )
{
TString type = TString(histo->Class()->GetName()) ;
if ( ! (type.Contains(“TH1”) || type.Contains(“TH2”) ) ) { fprintf (stderr,"\n\n!!!ERROR in <MRF_binarizeHisto>: bad type!!!\n\n") ; getchar() ; exit(1) ; }
if ( type.Contains(“TH1”) ) { for (Int_t ibin=1 ; ibin<=histo->GetNbinsX(); ibin++) { if ( TMath::Abs(histo->GetBinContent(ibin)) > 0 ) { histo->SetBinContent(ibin,1) ; } } }
else if ( type.Contains(“TH2”) ) { for (Int_t col=1; col<=histo->GetNbinsX(); col++) { for (Int_t row=1; row<=histo->GetNbinsY(); row++) { if ( TMath::Abs(histo->GetBinContent(col,row)) > 0 ) { histo->SetBinContent(col,row,1) ; } } } }
return ;
}[/code]I’ve tried several #pragma statements in vain.
Cheers,
Z

Hi,

As you have it (and thanks to the class hierarchy of the ROOT histograms) you functions does not need to be templated at all! You can simply use:

template void MRF_binarizeHisto ( ATH* histo );
#ifdef MAKECINT
// Both those syntax should work.
#pragma link C++ function MRF_binarizeHisto(TH1F*);
#pragma link C++ function MRF_binarizeHisto;
#endif[/code]

Cheers,
Philippe.

Thanks Philippe.

[quote]Your function does not need to be templated at all![/quote]True only if histo->Class()->GetName() is replaced byhisto->GetClassName()That’s a pity I’d missed that point so far!

[quote]// Both those syntax should work.[/quote]I’d tried the second one actually.
None of them works unfortunatelly :frowning:

histo->ClassName() NOT histo->GetClassName()I’m sorry :blush:

Actually you meant:TString type( histo->IsA()->GetName() );and you can even do if ( ! histo->InheritsFrom( TH1::Class() ) ) { fprintf (stderr,"\n\n!!!ERROR in <MRF_binarizeHisto>: bad type!!!\n\n") ; getchar() ; exit(1) ; } if ( histo->InheritsFrom( TH2::Class() ) ) { // 2D histogram stuff } else { // 1D histogram stuff }

Cheers,
Philippe.

Thx Philippe.
Any clue for the #pragma thing?

Hi,

With#ifdef __MAKECINT__ #pragma link C++ function _MRF_binarizeHisto_(TH1*); #endif

I get the correct dictionary:

root [0] .L tt.C+ Info in <TUnixSystem::ACLiC>: creating shared library /private/var/tmp/./tt_C.so root [1] .function > res01 root [2] .! grep MRF res01 tt_C.so -1:-1 0 public: void _MRF_binarizeHisto_(TH1* histo);

Cheers,
Philippe.

Thanks Philippe.
Indeed you get the correct dictionary if the prototype of the function is declared before the #pragma block.
Attached’s a complete working example using the template way (mrf_template.C) and the “plain/smart” way (mrf.C). Just type .x ztest.cpp[+]As the function call in ztest.cpp has to be the same in both cases* (namely MRF_binarizeHisto()), there’s no point in implementing the template case indeed.
Cheers,
Z

  • Using MRF_binarizeHisto() does not work in CINT (which is normal considering the pragma statement used)
  • MRF_binarizeHisto() (without any <>) does not make ACLIC whinge
    ztest.cpp (656 Bytes)
    mrf_template.C (864 Bytes)
    mrf.C (686 Bytes)