national taiwan university computational methods in
TRANSCRIPT
COMPUTATIONAL METHODS INEXPERIMENTAL PARTICLE PHYSICS
Kai-Feng ChenNational Taiwan University
Lecture 03: Basic Visualization with ROOT2016
1
ROOT: AN INTRODUCTIONAn analysis framework for large scale data handling, mostly used by high-energy physics, astrophysics, nuclear physics, including both experiments & theory.It's also an open source project.Started in 1995, with 8 full time developers at CERN, plus Fermilab, Agilent Tech, Japan, MIT (one each).Large number of part-time developers: Users participate its development.Available (incl. source) under GNU/LGPL.
3
ROOT: AN INTRODUCTION (CONT.)
The ROOT can deal with:An efficient(?) data storage, access and query system up to PetaBytes level.Advanced statistical analysis tools and algorithms (multi dimensional histogramming, fitting, minimization and cluster finding, etc.)Scientific visualization: 2D and 3D graphics, convert the output to Images (jpeg/png/gif), Postscript, PDF, LateXGeometrical modeller (to show some 3D detector view)PROOF parallel query engine (MPI...)
4
A LITTLE HANDS-ON SHOWI'm going to show you a very easy/little thing that can do with the ROOT framework:
6
{ TH1F *h1 = new TH1F("h1","A Random Histogram",100,0.,1.); TF1 *f1 = new TF1("f1","[0]+[1]*x+[2]*gaus(2)"); f1->SetParameters(2.,-1.0,2.5,0.5,0.05); h1->FillRandom("f1",2000); h1->Fit("f1"); }
example_01.cc
A direct run of this piece of code will generate this plot (with a fit) already:
MATHEMATICS UTILITIESMost of the computing tasks we have covered in this lecture can be actually made with few root commands.e.g. plotting the Legendre polynomials:
12
{ gSystem->Load("libMathMore"); TF1* l1 = new TF1("l1", "ROOT::Math::legendre(1,x)", -1., 1.); TF1* l2 = new TF1("l2", "ROOT::Math::legendre(2,x)", -1., 1.); TF1* l3 = new TF1("l3", "ROOT::Math::legendre(3,x)", -1., 1.); l1->Draw(); l2->Draw("same"); l3->Draw("same"); }
example_02.cc
1− 0.8− 0.6− 0.4− 0.2− 0 0.2 0.4 0.6 0.8 11−
0.5−
0
0.5
1
ROOT::Math::legendre(1,x)
Pn(x) =1
2nn!
d
n
dx
n[(x2 � 1)n]
no needs of implementation by yourself.
MULTIVARIATE ANALYSIS SUPPORT
The question: how could we distinguish cats from dogs with a computer program?
13
MULTIVARIATE ANALYSIS SUPPORT
The question: how could we distinguish cats from dogs?Cats are generally smaller then dogs, so we could measure their sizes.Cats are generally lighter then dogs, so we could also measure their weights.They have different “barking” sound – so we could analysis their voice.They have different favorite food – so we could feed them with fish and bone and see if they take them.Cats can safely fall down from a high place, so we could perform a (cruelly) free-falling test. maybe more ...
14
MULTIVARIATE ANALYSIS SUPPORT
15
size? weight? food favor?
free-falling test?
ROOT includes a tool TMVA to do multivariate analysis. It supports Neural Network, Likelihood methods, Boost
decision trees, etc.
MULTI CPU/CLUSTER SUPPORT
Q: I just spent a big memory buying a multi-core cpu, could I use it in my work?A: Yes, there is some parallel working supports in RROOF.
16
MORE FEATURES TO BE DISCOVERED...
There are more features to be discovered from the web:http://root.cern.chWe are going to show you how to use this tool to carry out your own work during in following lecture time.
18
BEGINNING OF EVERYTHING:GET A WORKING COPY SOMEWHERE
As you connect to the ROOT webpage, you can already find a big icon showing at the left:
19
JUST GO AHEAD!
I recommend to use the final version of ROOT 5 for now. There is still some minor
compatibility issue with ROOT 6.
BEGINNING OF EVERYTHING:GET A WORKING COPY SOMEWHERE
For Linux//Mac OSX: Just download the right precompiled binary corresponding to your gcc version.For the people who is not using scientific linux/CentOS/Fedora/Ubuntu, there may be some missing libraries, but in principle they can be solved easily.For Windows, you will need to download the corresponding binaries depending on your Visual Studio.
20
STARTUP FOR LINUX/MAC OS WITH BINARY
Download and unpack the tar ball, for example:
For linux, you may get the binary tar ball corresponding to your system. But if your system is not listed, you can try to use the binary from a similar system (note the glibc and gcc version). You may miss some libraries or version mismatch. The solution will be either make a soft link under your system directory, or build your own binary from the source (will be introduced in the later slides).
21
> cd /some/where > curl -O https://root.cern.ch/download/root_v6.06.08.macosx64-10.10-clang70.tar.gz > tar xfvz root_v5.34.32.macosx64-10.10-clang61.tar.gz > ls root/ LICENSE bin emacs geom lib test README cmake etc icons macros tutorials aclocal config fonts include man
INSTALLING FROM SOURCEAlternatively: you may want to compile your own ROOT if your system is not listed in the binary list. Just follow the instruction below:https://root.cern.ch/building-root
Note the prerequisites are very important:https://root.cern.ch/build-prerequisites
22
sudo yum install git make gcc-c++ gcc binutils \libX11-devel libXpm-devel libXft-devel libXext-devel
sudo yum install gcc-gfortran openssl-devel pcre-devel \mesa-libGL-devel mesa-libGLU-devel glew-devel ftgl-devel mysql-devel \fftw-devel cfitsio-devel graphviz-devel \avahi-compat-libdns_sd-devel libldap-dev python-devel \libxml2-devel gsl-static
sudo apt-get install git dpkg-dev make g++ gcc \binutils libx11-dev libxpm-dev libxft-dev libxext-dev
sudo apt-get install gfortran libssl-dev libpcre3-dev \xlibmesa-glu-dev libglew1.5-dev libftgl-dev \libmysqlclient-dev libfftw3-dev cfitsio-dev \graphviz-dev libavahi-compat-libdnssd-dev \libldap2-dev python-dev libxml2-dev libkrb5-dev \libgsl0-dev libqt4-dev
BUILD PREREQUISITES
23
You need these packages in a Fedora system
You need these packages in a Ubuntu system
Make����������� ������������������ sure����������� ������������������ all����������� ������������������ of����������� ������������������ the����������� ������������������ required����������� ������������������ libraries����������� ������������������ are����������� ������������������ installed!
Get the source tar ball from the root web:
Just follow the commands below:
It will take a while, please wait (or you can use make -j N) if you have a N-core CPU. If no error messages shown at the end of “make”, you are ready to use it!
INSTALLING FROM SOURCE
24
> cd /some/where > curl -O https://root.cern.ch/download/root_v6.06.08.source.tar.gz > tar xfvz root_v6.06.08.source.tar.gz > cd root/ > ./configure --all (enable any supported libraries, eg. roofit, etc.) > make (and just wait...)
ROOT STARTUPIn order to use the ROOT under the terminal, we have to setup the environment:
Alternatively you can setup the environment (for tcsh) as following:
For bash, you have to replace the “setenv” with “export”, and plus a “=” right after the variable name:
25
> setenv ROOTSYS /some/where/root > setenv PATH "${ROOTSYS}/bin:$PATH" > setenv LD_LIBRARY_PATH "${ROOTSYS}/lib"
> export ROOTSYS=/some/where/root > export PATH="${ROOTSYS}/bin:$PATH" > export LD_LIBRARY_PATH="${ROOTSYS}/lib"
> source /some/where/root/bin/thisroot.csh (for tcsh) or > source /some/where/root/bin/thisroot.sh (for bash)
THEN... JUST LAUNCH IT!
26
> root ------------------------------------------------------------------------- | Welcome to ROOT 6.06/08 http://root.cern.ch | | (c) 1995-2016, The ROOT Team | | Built for macosx64 | | From heads/v6-06-00-patches@v6-06-06-30-g3bae07b, Sep 01 2016, 14:28:05 | | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q' | -------------------------------------------------------------------------
root [0]
If����������� ������������������ you����������� ������������������ have����������� ������������������ got����������� ������������������ it����������� ������������������ setup����������� ������������������ correctly!
ASSESSMENT
Time to get your ROOT working!For experts, please help someone who cannot get his/her system work.Remarks for Windows: it is very difficult to have ROOT fully functioning in general. Linux or Mac OSX are strongly recommended. ROOT with gcc on Windows is not well supported (Visual C++ is better).
27
ROOT AS A POCKET CALCULATOR
You may just use the ROOT prompt as a calculator:
28
root [0] exp(10) (std::enable_if<true, double>::type) 22026.5 root [1] sqrt(28) (std::enable_if<true, double>::type) 5.29150 root [2] double x = 0.54; root [3] x (double) 0.540000 root [4] x+x*x+x*x*x (double) 0.989064 root [5] printf("%f\n",sin(x)); 0.514136 root [6] for(int i=0;i<5;i++) cout << i << endl; 0 1 2 3 4 root [7] _
SIMPLE BUT IMPORTANT OPERATIONS
The most important command: how to quit root:
A command list – help page
Go back to csh/sh temporary
Execute a shell command
Reset ROOT
29
root [0] .q
root [0] .help
root [0] .!csh
root [0] .! <command>
root [0] gROOT->Reset();
ROOT PROMPTProbably you already noticed that, the root prompt is actually based on C/C++, except those special commands starting with a “.”.This interactive prompt is called CLING (a C++ interpreter in fact), in principle all your codes can be written in C/C++ and execute them directly. Remark: ROOT version 5 and before is using a CINT interpreter, this is one of the reason why ROOT 5 and 6 are so different.
Basically there are some variations (python, ruby, etc) for those who does not like to use C/C++ as a script language. Why not GUI interface? There are some fine GUI for tuning your figures, fits, others, but it is still recommended to go the work in scripts/codes. A line from ROOT developers: ROOT is not an office suite, but a programming framework!
30
RUNNING UNDER CINTA minimum example with a function (hello, world?):
Let's run it with “.x”:
This is equivalent to load it (“.L”) and run it:
31
void example_03(double x) { printf("x*x = %g\n",x*x); }
NOTE: the entry point is not main() but example_03()
root [0] .x example_03.cc(2.5) x*x = 6.25
root [0] .L example_03.cc root [1] example_03(2.5) x*x = 6.25
example_03.cc
#include <TRandom3.h>
#define M_SIZE 500 void do_some_calc() { double A[M_SIZE][M_SIZE],B[M_SIZE][M_SIZE],C[M_SIZE][M_SIZE];
TRandom3 rnd; for(int i=0;i<M_SIZE;i++) for(int j=0;j<M_SIZE;j++) { A[i][j] = rand(); B[i][j] = rnd.Uniform(); } for(int i=0;i<M_SIZE;i++) for(int j=0;j<M_SIZE;j++) { C[i][j] = 0.; for(int k=0;k<M_SIZE;k++) C[i][j] += A[k][j]*B[i][k]; } } void example_04() { for(int i=0;i<10;i++) do_some_calc(); }
RUNNING UNDER CINTA little bit heavier example:
32
example_04.cc
RUNNING UNDER CINTDirect execute, well, it runs, but it may take a few seconds?
For a boost in speed, it's recommended to compile it first, and then execute it:
If your code has been compiled already, it just runs immediately!
33
root [0] .x example_04.cc (0:05.11)
root [0] .x example_04.cc+ (0:02.15) Info in <TMacOSXSystem::ACLiC>: creating shared library /Users/kfjack/Workspace/course/hep_computing/slides/2016/lecture-03/./example_04_cc.so
root [0] .x example_04.cc+ (0:00.28)
This running mode is not called CLING/CINT anymore, but named as ACLiC (Automatic Compiler of Libraries for CLING/CINT)
CINT VERSUS ACLIC
General guide lines:If your code needs lots of for/while loops, just compile it.If you just want to write a lazy script, keep it as CLING. CLING already does a good job for most of plotting/graphics works.Restriction of ACLiC: need to include full headers.
34
CLING/CINT ACLIC
Interpreter (Pre-)compiledSlower Faster
Run with partial code Coding with full headers, C/C++ rulesNo grammar checks A full check before execute
Easy object allocation, freelyA full tight code
(prepare for segment violation!)
SOME TECHNICAL ASPECTS…In fact, if you run exactly the same code, but with ROOT version 5 and above, you’ll find the speed decreases dramatically:
After ROOT 6 the interpreter CINT has been replaced by Cling. Cling is an interactive C++ interpreter, built on the top of LLVM and Clang libraries. Its advantages over the standard interpreters are that it has command line prompt and uses just-in-time (JIT) compiler for compilation. In general, Cling has the backward capability with CINT. Cling runs faster but also require more memory.
35
root [0] .x example_04.cc (ROOT 5 – >10 mins)
root [0] .x example_04.cc (ROOT 6 – 0:05.11)
ASSESSMENT
Now it’s the time to install or prepare a working ROOT environment!Try the examples given in the previous slides, running under CLING/CINT and/or ACLiC modes, and see if you can get them work?
36
SOME BASIC HISTOGRAM OPERATIONS
Create an empty histogram:
Make a clone:
List the objects we just created:
37
root [0] TH1F* h1 = new TH1F("h1","a histogram",100,-5.,5.);
Object name (in your code)
Object name (in ROOT record) Histogram title
# of bins min & max
root [1] TH1F* h2 = (TH1F*)h1->Clone("h2");
root [2] .ls OBJ: TH1F h1 a histogram : 0 at: 0x7fe60c3e98a0 OBJ: TH1F h2 a histogram : 0 at: 0x7fe60c445730
SOME BASIC HISTOGRAM OPERATIONS
Let's fill them with random numbers:
Plot them:
38
root [6] h2->Draw(); root [7] h1->Draw(); root [8] h1->GetYaxis()->SetRangeUser(0.,150.); root [9] h1->Draw()
root [3] TRandom3 rnd(1234); root [4] for(int i=0;i<10000;i++) h1->Fill(rnd.Uniform(-5.,5.)); root [5] for(int i=0;i<10000;i++) h2->Fill(rnd.Gaus(0.,1.));
Initial a generator with seed = 1234(Algorithm: Mersenne Twister)
Loop & fill for 10,000 times Uniform generator (min,max) & Gaussian generator (mean,width)
SOME BASIC HISTOGRAM OPERATIONS
Direct operations: (+/−/×/÷)
Normalize it:
Draw the error bar
39
root [10] TH1F* h3 = (TH1F*)h1->Clone("h3"); root [11] h3->Add(h2); root [12] TH1F* h4 = (TH1F*)h1->Clone("h4"); root [13] h4->Add(h2,-1.); root [14] TH1F* h5 = (TH1F*)h1->Clone("h5"); root [15] h5->Multiply(h1); root [16] TH1F* h6 = (TH1F*)h1->Clone("h6"); root [17] h6->Divide(h1);
root [18] h1->SetNormFactor();
root [19] h2->Draw("e");
SOME BASIC HISTOGRAM OPERATIONS
Obtain/set the mean value/error of a specific bin:
Reset (clean up) the histogram:
Get total entries:
40
root [20] h1->GetBinContent(5) (Double_t)94.0000 root [21] h1->GetBinError(5) (Double_t)9.69536 root [22] h1->SetBinContent(5,128.0) root [23] h1->SetBinError(5,0.05) root [24] h1->GetBinContent(5) (Double_t)128.000
root [25] h1->Reset()
root [26] h2->GetEntries()
SOME BASIC HISTOGRAM OPERATIONS
A quick fit (we will come back to the fitting in one of the later lectures)
41
root [26] h2->Fit("gaus"); FCN=76.7734 FROM MIGRAD STATUS=CONVERGED 59 CALLS 60 TOTAL EDM=1.60726e-09 STRATEGY= 1 ERROR MATRIX ACCURATE EXT PARAMETER STEP FIRST NO. NAME VALUE ERROR SIZE DERIVATIVE 1 Constant 3.98520e+02 4.87828e+00 1.72269e-02 1.26437e-05 2 Mean 1.09934e-02 1.00185e-02 4.31207e-05 -1.81996e-03 3 Sigma 9.93964e-01 7.01172e-03 8.26736e-06 2.29756e-02 (class TFitResultPtr)140246138123936 root [27]
A simple fit with Gaussian distribution:
� / 1p2⇡�
exp
� (x� µ)
2
2�
2
�
SOME DRAWING OPTIONSSet line width:
Set line color:
Set line style:
Set filling color:
42
root [20] h3->SetLineWidth(3); root [21] h3->Draw();
root [23] h3->SetLineStyle(7);
root [24] h3->SetFillColor(50);
root [22] h3->SetLineColor(1);
2D HISTOGRAMSWorking with 2D histograms is also very straightforward:
Let's fill it with some random numbers:
Just plot it:
43
TH2F* h2d = new TH2F("h2d","a 2d histogram",20,-5.,5.,20,-5.,5.);
# of bins (x) min & max (x)
# of bins (y) min & max (y)
for(int i=0;i<10000;i++) h2d->Fill(rnd.Gaus(0,1),rnd.Gaus(0,1));
h2d->Draw();
MORE DRAWING OPTIONS
44
h2d->Draw("box"); h2d->Draw("lego"); h2d->Draw("lego2");
h2d->Draw("cont"); h2d->Draw("surf"); h2d->Draw("surf4");
FUNCTIONSWhat should we do if we just want to plot a function, e.g.:
Just plot it:
Get the function value at x=0.5
45
TF1* f1 = new TF1("f1","x+x^2+x^3+x^4+sin(5*pi*x)+exp(x)",0.,1.);
function object name free function form min & max
f(x) = x+ x
2+ x
3+ x
4+ sin(5⇡x) + exp(x)
f1->Draw()
f1->Eval(0.5)
FUNCTIONS (CONT.)Then we could also practice those “hands-on shows” at the beginning of this lecture:
Derivative x = 0.5:
Integration in an interval, e.g. [0,1]:
Generate a random number according to this function:
46
root [30] f1->Derivative(0.5) (Double_t) 4.89871
root [31] f1->Integral(0.,1.) (Double_t) 3.12894
root [32] f1->GetRandom() (Double_t) 0.999880
FILL RANDOM HISTOGRAMWe could fill a histogram with the random numbers generated according to such a specific function:
Create a 1D histogram and fill:
This is the same as
If you draw it:
47
root [33] TH1F* h1 = new TH1F("h1","a histogram",100,0.,1.); root [34] for(int i=0;i<10000;i++) h1->Fill(f1->GetRandom());
root [35] h1->FillRandom("f1",10000);
2D FUNCTIONSThe 2D function is not really different from the 1D functions: (as we already see the example earlier in fact)
48
root [36] TF2* f2 = new TF2("f2","sin(x)*sin(y)",0,10,0,10); root [37] f2->SetFillColor(50); root [38] f2->Draw("lego1"); root [39] f2->Draw("surf4");
GRAPHICAL OBJECTSSome simple graphical objects which might be useful:
Line:
Arrow:
Box (rectangle):
Ellipse (or Pie):
Text or equation:
49
root [40] TLine *l1 = new TLine(0.1.,0.1,0.9,0.3); root [41] l1->Draw();
root [42] TArrow *a1 = new TArrow(0.9,0.1,0.1,0.3,0.05,"|>"); root [43] a1->Draw();
root [44] TBox *b1 = new TBox(0.4,0.7,0.9,0.4); root [45] b1->Draw();
root [46] TEllipse *e1 = new TEllipse(0.3,0.7,0.2,0.2,30.,330.); root [47] e1->Draw();
root [48] TLatex *t1 = new TLatex(0.6,0.8,"#sqrt{x^{2}+y^{2}}"); root [49] t1->Draw();
{ TCanvas *c1 = new TCanvas("c1","c1",500,500); TLine *l1 = new TLine(0.1,0.1,0.9,0.3); l1->SetLineWidth(2); l1->Draw(); TArrow *a1 = new TArrow(0.9,0.1,0.1,0.3,0.05,"|>"); a1->SetLineWidth(2); a1->SetLineStyle(2); a1->Draw(); TBox *b1 = new TBox(0.4,0.7,0.9,0.4); b1->SetFillColor(kYellow); b1->Draw(); TEllipse *e1 = new TEllipse(0.3,0.7,0.2,0.2,30.,330.); e1->SetLineWidth(3); e1->SetFillColor(kGreen); e1->Draw(); TLatex *t1 = new TLatex(0.6,0.8,"#int #frac{#sqrt{x^{2}+y^{2}}}{2#pi} dxdy"); t1->SetTextColor(kBlue); t1->Draw(); }
GRAPHICAL OBJECTSAs a quick demonstration:
50
example_05.cc dxdy
π22+y2x ∫
LET'S PUT THEM ALL TOGETHER!
Step1: Generate some data and save them into a text file (yes, and this step can be replaced by any other program as your data source!).Step 2: Read those data back, and draw it.
51
void example_06() { TRandom3 rnd; FILE *fpout = fopen("whatever_data.txt","w"); for(int i=0;i<1000;i++) fprintf(fpout,"%f\n",rnd.Gaus()); fclose(fpout);
0.998933 -0.434764 0.781796 -0.030053 0.824264 -0.056717 -0.900876 -0.074704 0.007912 -0.410763 1.391194 -0.985066 ......Output store in
the “whatever_data.txt”
example_06.cc
LET'S PUT THEM ALL TOGETHER!
52
TH1F *h1 = new TH1F("h1","whatever data",100,-5.,5.); FILE *fpin = fopen("whatever_data.txt","r"); float val; while(1) { int r = fscanf(fpin,"%f",&val); if (r!=1) break; h1->Fill(val); } fclose(fpin); h1->SetFillColor(50); h1->Draw(); }
1) Prepare an empty histogram2) Open the file, read the data back3) fill the histogram and draw it!
example_05.cc (cont.)
ALL TOGETHER (II)
53
void example_06a() { TRandom3 rnd; FILE *fpout = fopen("whatever_data_2.txt","w"); for(int i=0;i<100;i++) fprintf(fpout,"%f %f\n",(float)i*0.1*(1.+rnd.Gaus()),(float)i*0.1); fclose(fpout); TH1F *h1 = new TH1F("h1","whatever data",100,0.,100.); FILE *fpin = fopen("whatever_data_2.txt","r"); float val,err; for(int i=0;i<100;i++) { int r = fscanf(fpin,"%f %f",&val,&err); if (r!=2) break; h1->SetBinContent(i+1,val); h1->SetBinError(i+1,err); } fclose(fpin);
example_06a.cc
ALL TOGETHER (II)
54
h1->SetMarkerStyle(21); h1->Draw(); TLine *l1 = new TLine(0.,0.,100.,10.); l1->SetLineColor(50); l1->SetLineWidth(2); l1->Draw(); }
example_05a.cc (cont.)
dot����������� ������������������ +����������� ������������������ error����������� ������������������ bar����������� ������������������ +����������� ������������������ reference����������� ������������������ line����������� ������������������ all����������� ������������������ together!
FOR YOU TO EXPLOREJust check out the “test” and “tutorials” directories under your root installation. There are many fancy examples you may want to try it out by yourself.
55
You can even find a Tetris game..
ASSESSMENT
Read some of the data which is really related to your own work, and produce some nice figures with ROOT.Practice:
Draw some specific function and generate the corresponding distributions with random numbers. Try out different drawing options.
56
HOMEWORK #1As an example function drawing: a heart for Valentine's day?
57
{ TCanvas *c1 = new TCanvas("c1","c1",600,600); TF2 *func = new TF2("func","(x^2+y^2-1)^3-x^2*y^3<0.",-2.,2.,-2.,2.); func->SetNpx(500); func->SetNpy(500); func->Draw("col"); }
Now����������� ������������������ you����������� ������������������ can����������� ������������������ write����������� ������������������ a����������� ������������������ card����������� ������������������ for����������� ������������������ Valentine’s����������� ������������������ day����������� ������������������ with����������� ������������������ ROOT?
HOMEWORK #1Using the above example code to draw this for the Spring Festival?
58
x
4 + y
4 +100
x
4 + (2y � 2)4 + (2y � 1)2+
100
x
4 + (2y + 2)4 + (2y + 1)2
� 1
(y + 3)4 + (x/15)4� 1
(y + 4)4 + (x/15)4
� 1
(y + 5)4 + (x/15)4� 1
4(x+ y + 4)4 + [(x� y + 1)/5]4
�⇢
100
[(x� 4)2 + (y + 5)2 � 13]2 + [(x� 19)2 + (y + 12)2 � 400]2
�16
< 25
http://pansci.asia/archives/75693Original source from:
The����������� ������������������ “spring”����������� ������������������ equation:
HOMEWORK #1 CHALLENGE
If you can draw this extra spring festival scroll(?), as hinted by the same author of the previous equation, you will get some extra credit for your homework.
59
CLOSING REMARKHopefully you will not get this as a reply to your card after the Valentine's day…
60
{ TCanvas *c1 = new TCanvas("c1","c1",600,600); TF2 *func = new TF2(“func","17*(x^2+y^2)-16*y*abs(x)+150./abs(5*x+sin(5*y))<200", -5.,5.,-5.,5.); func->SetNpx(500); func->SetNpy(500); func->Draw("col"); }