TFormula, TF1 and TF2 problems

I don’t know if I miss something or if something should be stated clearly
in docs but with different way to create a TF2 object (the same holds for TFormula
and TF1) I get different responses from Draw method.

[code]
root [0] TF2 fun2
root [1] fun2 = new TF2()
(class TF2
)0x8febe00
root [2] fun2->SetName(“fun2”)
root [3] fun2->SetTitle("([0]*x^2+[1]x)([2]*y^2+[3]*y)")
root [4] fun2->Compile()
(Int_t)0
root [5] fun2->SetRange(5, 1e-3, 350, 10)
root [6] fun2->SetParameters(-3.2653e-4, 1.1428e-1, -4, 40)
root [7] fun2->Eval(175,5)
(const Double_t)9.99901875000000246e+02
root [8] fun2->Draw(“surf”)
TCanvas::MakeDefCanvas: created default TCanvas with name c1
root [9] TF2 *fun1
root [10] fun1 = new TF2(“fun1”,"([0]*x^2+[1]x)([2]*y^2+[3]y)",5,350,1e-3,10)
(class TF2
)0x90d42a0
root [11] fun1->SetRange(5, 1e-3, 350, 10)
root [12] fun1->SetParameters(-3.2653e-4, 1.1428e-1, -4, 40)
root [13] fun1->Eval(175,5)
(const Double_t)9.99901875000000246e+02
root [15] fun1->Draw(“surf”)


the 11th row is only a harmful repetition.
For the function created with def ctor I get an empty pad while for the second 
everything goes smooth. (See Attachment)

Moreover, I do not understand how to use DrawCopy. With the following I
got segmentation violation:

root [16] fun1->SetParameter(0, -1)
root [17] fun1->SetParameter(1, 350)
root [18] fun1->Eval(175,5)
(const Double_t)3.06250000000000000e+06
root [19] TF2 *fun3
root [20] fun3 = dynamic_cast<TF2*>fun1->DrawCopy()
(class TF2*)0x91ecd60
root [21] fun3->Draw("surf")

 *** Break *** segmentation violation
 Generating stack trace...
 0xb753bd4e in <unknown> from /usr/lib/root/libHist.so.4.04
 0xb76b9eff in G__call_cppfunc + 0x2f4 from /usr/lib/root/libCint.so.4.04
 0xb76a8063 in G__interpret_func + 0x807 from /usr/lib/root/libCint.so.4.04
 0xb7686c01 in G__getfunction + 0x16b5 from /usr/lib/root/libCint.so.4.04
 0xb772d1d1 in G__getstructmem + 0x9c6 from /usr/lib/root/libCint.so.4.04
 0xb7723337 in G__getvariable + 0x5cf from /usr/lib/root/libCint.so.4.04
 0xb767c652 in G__getitem + 0x686 from /usr/lib/root/libCint.so.4.04
 0xb767ab9c in G__getexpr + 0x9707 from /usr/lib/root/libCint.so.4.04
 0xb76d3a24 in G__exec_function + 0xd0 from /usr/lib/root/libCint.so.4.04
 0xb76dd261 in G__exec_statement + 0x4005 from /usr/lib/root/libCint.so.4.04
 0xb765fc25 in G__exec_tempfile_core + 0x330 from /usr/lib/root/libCint.so.4.04
 0xb765fe5b in G__exec_tempfile_fp + 0x22 from /usr/lib/root/libCint.so.4.04
 0xb76e623e in G__process_cmd + 0x4cd0 from /usr/lib/root/libCint.so.4.04
 0xb79fb5ed in TCint::ProcessLine(char const*, TInterpreter::EErrorCode*) + 0xaf from /usr/lib/root/libCore.so.4.04
 0xb794be50 in TApplication::ProcessLine(char const*, bool, int*) + 0x698 from /usr/lib/root/libCore.so.4.04
 0xb6db535c in TRint::HandleTermInput() + 0x1f8 from /usr/lib/root/libRint.so.4.04
 0xb6db3f52 in TTermInputHandler::Notify() + 0x24 from /usr/lib/root/libRint.so.4.04
 0xb6db57e2 in TTermInputHandler::ReadNotify() + 0x12 from /usr/lib/root/libRint.so.4.04
 0xb7aa6806 in TUnixSystem::CheckDescriptors() + 0x152 from /usr/lib/root/libCore.so.4.04
 0xb7aa5685 in TUnixSystem::DispatchOneEvent(bool) + 0x195 from /usr/lib/root/libCore.so.4.04
 0xb79b9c0c in TSystem::InnerLoop() + 0x18 from /usr/lib/root/libCore.so.4.04
 0xb79b9bac in TSystem::Run() + 0x7a from /usr/lib/root/libCore.so.4.04
 0xb794c69c in TApplication::Run(bool) + 0x32 from /usr/lib/root/libCore.so.4.04
 0xb6db4d76 in TRint::Run(bool) + 0x3d8 from /usr/lib/root/libRint.so.4.04
 0x08048e23 in main + 0x67 from /usr/bin/root.exe
 0xb6b8bea0 in __libc_start_main + 0xe0 from /lib/tls/libc.so.6
 0x08048d31 in TApplicationImp::ShowMembers(TMemberInspector&, char*) + 0x3d from /usr/bin/root.exe
Root >

What’s wrong?

Regards, Germano




Hi,

You missed a couple of calls (whose equivalent is done by the constructor):

fun2->SetNpy(100); fun2->SetNpy(100); However, in addition, some of the array holding parameter information can only be initialize in the constructor, so we do NOT recommend that you start with the default constructor to build functions. (The default constructor should currently only be used by the I/O sub-system).

DrawCopy create a temporary function which is deleted as soon as the canvas is cleared. The canvas is cleared whenever you called Draw (for an function or histogram) without the option “SAME”. Hence in your case when you do

root [21] fun3->Draw("surf") It first delete the function, then tries to display it … resulting in a crash!

Instead you may want to use DrawClone which returns a copy which will be deleted only when you ask for it.

Cheers,
Philippe.

[quote=“pcanal”]Hi,

You missed a couple of calls (whose equivalent is done by the constructor):

fun2->SetNpy(100); fun2->SetNpy(100); However, in addition, some of the array holding parameter information can only be initialize in the constructor, so we do NOT recommend that you start with the default constructor to build functions. (The default constructor should currently only be used by the I/O sub-system).
[/quote]
Thanks for your reply Philippe,
this is what I supposed (more or less). Before posting I looked carefully at
the code and I saw how the def ctor was far from “complete” respect to the others.
But maybe the use of def ctor could be clearly discouraged in the codumentation… :wink:
There are no chances at all for the future to have a function making
the correct initializations for a TFormula (or TF1 TF2) created with a
default constructor?

Anyway, stated that it would be better to use other constructors, if I created a
function with a constructor (not the default) and subsequently I decided to change
the formula, something like

fun->SetTitle("...")
fun->Compile()
fun->SetParameters(...)

would do the job or anyway it would be better to use a fresh one?

This is a little bit obscure to me…
I think there are strong reasons for the actual function with the new parameters to be not drawn again so I do not insist on this issue.
Looking at docs I saw that DrawCopy should be used to draw a function
whenever parameters change but nothing in the documentation warns about
what you said; could it be stated clearly in the documentation?

Thanks a lot for your explanations (you are solving the greatest amount of my problems :wink: ), now I know better how to play with
functions and maybe this could be an explanations for a class of mine
that uses TF2 objects as data memebers.

I’ll try also with DrawClone

Regards, Germano

[quote]would do the job or anyway it would be better to use a fresh one? [/quote]It would work only the number of parameter does not change so it is better to use a fresh function object.

[quote]There are no chances at all for the future to have a function making
the correct initializations for a TFormula (or TF1 TF2) created with a
default constructor?[/quote]We’ll see what we can do :slight_smile:

Cheers,
Philippe.

[quote=“pcanal”][quote]There are no chances at all for the future to have a function making
the correct initializations for a TFormula (or TF1 TF2) created with a
default constructor?[/quote]We’ll see what we can do :slight_smile:
[/quote]

No meaning to request features… :blush: but if you’d like… :unamused:

Anyway I think that

newf2->SetBit(kCanDelete);

in DrawCopy method is what causes what you said…

Ok, if docs cannot state this “go to the source” :wink:

Cheers and thanks, Germano