... para pessoas que não sabem c++ Alexandre Suaide aula 1 O que é o ROOT? • O ROOT é tudo que você precisa ... – Conjunto de bibliotecas para análise de dados e desenvolvimento de aplicativos • Histogramas, gráficos, análise em geral, simulação, IO, desenvolvimento de aplicativos, etc – Poderoso interpretador c++ (Cint) • Você pode rodar um programa em c++ linha por linha no prompt de comando – Interface gráfica poderosa (mas não é o Origin) • ... mas ao mesmo tempo não é muita coisa. – O usuário tem que saber programar um pouco... Organização das aulas • Aula 1 – Comandos (realmente) básicos do ROOT – Um pouco de c++ para usuários de ROOT – Criando objetos simples (histogramas, gráficos, etc) – Manuseando gráficos e histogramas. • A interface gráfica – Funções e ajustes de gráficos • Aula 2 – Análise de dados no Pelletron • ScanRoot e PelTools – Macros – Inovando sem perder a classe. – Debug, memory leaks e administrando objetos Comandos básicos • Como iniciar o programa – Digite root • Como sair do ROOT – Digite .q Note que esse tipo de texto será utilizado sempre que for algum • Estranho, mas como o ROOT é um comando interpretador c++, os para ser comandos internos do mesmo têm que ser diferenciados. digitado no computador Assim, todos os comandos do ROOT começam com “.”. Os comandos mais importantes, alem do .q são – .L para carregar um macro na memória – .x para carregar e executar um macro – .h para um help A interface do ROOT • Use a tecla TAB para obter ajuda root [0] b = new TB <TAB> root [1] b = new TBrow<TAB> root [2] b = new TBrowser(<TAB> • Útil para descobrir a lista de métodos • Descobrir também lista de parâmetros O ROOT é realmente um interpretador c++ • Exemplo de algo bem básico ... root [0] float a root [1] float b root [2] cout << a + b = 30 root [3] for(int i = 0 i = 1 i = 2 = 10; = 20; “a + b = “ << a + b << endl; i = 0; i<3; i++) cout << “i = “ << i <<endl; • Tipos de variáveis – C++ • double, float, long int, int, short int, char, etc. – No ROOT • Double_t, Float_t, Long_t, Int_t, Short_t, Char_t, etc. – A diferença vem do fato que as variáveis em c++ dependem da plataforma (em termos de tamanho) • Ex: int (i386 = 4 bytes, Solaris = 8 bytes) – ... Enquanto os tipos definidos no ROOT têm tamanho fixo, independente de plataforma Um pouco de c++ só para não ficar totalmente perdido • Comentários – /* comentário de bloco */ – // comentário de linha • IO básico: – cout/cin • Loops cout << “Ola. 1 + 1 = “ << 1 + 1 << endl; int idade; cout <<“Quantos anos voce tem? “<<endl; cin >> idade; – for ( parâmetros do loop ) { comandos } for(int i=0;i<10;i++) cout << i << endl; – do { alguma coisa } while ( condição ); – while ( condição ) { alguma coisa } • Condições – if ( condição ) { alguma coisa } else { outra coisa } if (i==0) cout << “É zero “<<endl; else cout <<“Não é zero “<<endl; – == (igual), != (diferente), || (or), && (and), ! (not) Um pouco mais de c++ • Classe – É a descrição de algum conceito abstrato – Classes possuem membros • Membros podem ser variáveis ou funções. • Os membros podem ser públicos, privados ou protegidos. O usuário tem acesso somente aos membros públicos – Classes podem derivar de outras classes. • Objeto – É a “coisa” real criada na memória do computador que tem uma estrutura definida pela classe • Ponteiro – Contém o endereço de um objeto na memória • É uma espécie de atalho para uma certa região de memória do computador Classes possuem interface • Como o usuário só tem acesso aos membros públicos, não importa como as coisas são feitas internamente. – A interface é muito importante e define o nível de facilidade com o qual o usuário interage com o objeto Criando (... e destruindo) objetos... • Criando objetos no stack Parâmetros para criação do objeto void exemplo_obj_1() { TH1F h("hist","histograma",100,0,10); h.SetLineColor(1); Construtor do h.Draw(); objeto } – O objeto h deixa de existir quando a função termina • Criando objetos no heap (new e delete) void exemplo_obj_2() { TH1F* h = new TH1F("hist","histograma",100,0,10); h->SetLineColor(1); h->Draw(); } – Objetos no heap são acessados com ponteiros – O objeto h só deixa de existir com o delete h; Construindo objetos... Múltiplos construtores (polimorfia) As funções de uma classe que possuem o mesmo nome da classe são os construtores. A função ~NOME é o destrutor class TH1F : public TH1, public TArrayF { public: TH1F() TH1F(const char* name, const char* title, Int_t nbinsx, Axis_t xlow, Axis_t xup); TH1F(const char* name, const char* title, Int_t nbinsx, const Float_t* xbins); TH1F(const char* name, const char* title, Int_t nbinsx, const Double_t* xbins); TH1F(const TVectorF& v); TH1F(const TH1F& h1f); virtual ~TH1F(); virtual void AddBinContent(Int_t bin); virtual void AddBinContent(Int_t bin, Stat_t w); ... Alguns padrões no código do ROOT facilita a aprendizagem Classes Começam com T TBrowser, TH1F Tipos Terminam com _t Int_t Membros de classes Começam com f fSize Funções membros Começam com maiúsculo Get(), SetSize() Constantes Começam com k kRed Variáveis estáticas Começam com g gROOT, gSystem Membros estáticos Começam com fg fgTokenClient Trabalhando com o ROOT • Gráficos e histogramas – O ROOT possui uma quantidade enorme de classes para tratar objetos gráficos – Histogramas • TH1 – Histogramas de 1 dimensão – TH1I, TH1S, TH1F, TH1D, ... (estabelece a precisão do eixo) • TH2 – Histogramas de 2 dimensões • TH3 – Histogramas de 3 dimensões – Gráficos • TGraph – Gráficos de X e Y simples • TGraphErrors – Gráficos com barras de erro Histogramas de 1 dimensão (TH1) • Criando um Histograma de 1 dimensão – TH1F *h = new TH1F(“nome”,”título”, Nbins, Xmin, Xmax); – TH1F h (“nome”,”título”, Nbins, Xmin, Xmax); void exemplo_TH1() { TRandom *r = new TRandom(); TH1F *h1 = new TH1F("histograma","Exemplo histograma",50,0,10); for(int i = 0;i<2000;i++) { float x = r->Gaus(5,1); h1->Fill(x); } h1->Draw(); } Para rodar esse exemplo, assim como os Seguintes, salve-o em um arquivo, por Exemplo, teste.C e digite, no prompt do ROOT root [0] .L teste.C root [1] exemplo_TH1(); Histogramas de 2 dimensões (TH2) • Muito similar ao TH1 – TH2F *h = new TH2F(“nome”,”título”, NbinsX, Xmin, Xmax, NBinsY, Ymin, Ymax); – TH2F h (“nome”,”título”, NbinsX, Xmin, Xmax, NbinsY, Ymin,Ymax); void exemplo_TH2() { TRandom *r = new TRandom(); TH2F *h2 = new TH2F("h","Exemplo Th2",50,0,10,50,0,5); for(int i = 0;i<2000;i++) { float x = r->Gaus(5,1); float y = r->Gaus(3,0.5); h2->Fill(x,y); } h2->Draw(); } Gráficos X-Y • Criar gráficos a partir de uma tabela é como tirar doce da mão de criança... • TGraph e TGraphError – ... = new TGraph(N,x,y); – ... = new TGraphErrors(N,x,y,ex,ey); • Onde – N = número de pontos – x, y são ponteiros (float) para os vetores com os dados – ex, ey são ponteiros (float) para os vetores com os erros Um exemplinho void exemplo_TGraph() { float x[] = {1,2,3,4,5,6}; float y[] = {0.1,0.3,0.5,0.7,0.9,1.1}; float ex[] = {0.1,0.1,0.1,0.1,0.1,0.1}; float ey[] = {0.02,0.03,0.02,0.04,0.03,0.05}; TGraphErrors *g = new TGraphErrors(6,x,y,ex,ey); g->SetMarkerStyle(20); // para circulo g->Draw("AP"); // A desenha os eixos, P desenha pontos } Personalizando histogramas e gráficos • As propriedades dos objetos podem ser alteradas através dos métodos implementados na definição das classes – Pode-se fazer: h1->SetFillColor(2); // muda a cor de preenchimento h1->SetLineWidth(1.3); // muda espessura da linha h1->GetXaxis()->SetTitle(“legenda X”); // muda legenda do eixo X ... • Além disso, o ROOT possui uma interface gráfica bastante amigável – Botão da esquerda • Arrasta objetos de um lugar para outro – Botão do meio • Muda a janela gráfica onde os gráficos serão desenhados – Botão da direita • Acessa menus e propriedades dos objetos onde o mouse está localizado. Acessando propriedades dos objetos clicando com o botão direito do mouse Mudando propriedades dos gráficos/histogramas Fazendo ajustes simples Ok, fiz meus gráficos, histogramas, etc... Como que eu os gravo em um arquivo? • O ROOT possui uma classe para IO. – TFile • TFile *f = new TFile(“NOME”,”opções”); • Um exemplo... Gravando histogramas void exemplo_TFile_write() { TRandom *r = new TRandom(); TH1F *h1 = new TH1F("hist1","Exemplo TH1",50,0,10); TH2F *h2 = new TH2F("hist2","Exemplo TH2",50,0,10,50,0,5); for(int i = 0;i<2000;i++) { h1->Fill(r->Gaus(5,1)); h2->Fill(r->Gaus(5,1), r->Gaus(3,0.5)); } TFile *f = new TFile("teste.root","NEW"); h1->Write(); h2->Write(); f->Close(); IMPORTANTE!! delete f; ! } Abrindo e lendo objetos de um arquivo • Usando o prompt root [0] TFile *f=new TFile("teste.root"); root [1] TH1F *h1=f->Get("hist1"); root [2] h1->Draw(); • Usando a interface gráfica (browser) new TBrowser(); Esse comando cria um objeto do tipo TBrowser. • Arquivos abertos aparecem na pasta ROOT Files Trabalhando melhor com janelas gráficas (TCanvas) • Como criar uma janela gráfica vazia root [0] TCanvas *c = new TCanvas(“nome”,”Titulo”,400,300); Um exemplo. Mostrando histogramas de várias formas void exemplo_TCanvas() { TFile *f = new TFile("teste.root"); TH2F *h1 = f->Get("hist1"); TH2F *h2 = f->Get("hist2"); TCanvas *c = new TCanvas(); c->Divide(2,2); c->cd(1); h2->Draw(); c->cd(2); h2->Draw("colz"); c->cd(3); h1->Draw(); c->cd(4); gPad->SetFillColor(11); gPad->SetLogy(); h1->Draw(); } gPad é um ponteiro interno do ROOT que sempre aponta para o objeto TPad atual. Fazendo ajustes mais complexos – Criando funções • A interface gráfica do ROOT permite ajustes simples (Gaussiana, polinômios, etc). • O ROOT possui classes para definir funções. – TF1, TF2 e TF3 • Uso – TF1 *f = new TF1(“nome”,”formula”,min,max); • A fórmula deve ser escrita usando a sintaxe padrão de c++. – Parâmetros variáveis devem vir entre brackets • [0], [1], etc – As variáveis são x, y e z • Alguns métodos interessantes – SetParameter(), GetParameter(), GetParError(), GetChisquare(), Eval(), etc. Um exemplo simples void exemplo_Func() { TF1 *f1 = new TF1("func","[0]*exp(-x/[1])*sin([2]*x)",0,6.28); f1->SetParameter(0,1); f1->SetParameter(1,3); f1->SetParameter(2,6); f1->Draw(); } Ajustando um histograma void exemplo_Fit() { TFile *f = new TFile("teste.root"); TH2F *h1 = f->Get("hist1"); TF1 *f1 = new TF1("func","[0]*exp(-0.5*pow((x-[1])/[2],2))"); for(int i=0;i<3;i++) f1->SetParameter(i,1); h1->Fit(f1,"Q"); h1->SetFillColor(23); for(int i=0;i<3;i++) { cout <<"Parametro "<<i <<" = "<<f1->GetParameter(i) <<" +- "<<f1->GetParError(i)<<endl; } cout <<"Chi2 = "<<f1->GetChisquare() <<" NDF = "<<f1->GetNDF()<<endl; } root [0] .L exemplo.C root [1] exemplo_Fit() Parametro 0 = 159.659 +- 4.41171 Parametro 1 = 5.00271 +- 0.0223727 Parametro 2 = 0.987987 +- 0.0160371 Chi2 = 24.7388 NDF = 30 Na próxima aula ... • Análise de dados no Pelletron – scanroot e PelTools • Vamos explorar o ROOT um pouco mais a fundo – Macros – Definindo novas classes – Compilando para tornar a execução mais rápida – Como corrigir problemas (debug) Como conseguir mais informação • Site do ROOT – http://root.cern.ch • Documentação das classes – http://root.cern.ch/root/Reference.html • Alguns documentos interessantes (root, c++) – Incluindo essas aulas – http://dfn.if.usp.br/~suaide/pelletron/links.htm • Download ROOT (+scanroot e PelTools) – http://dfn.if.usp.br/~suaide/pelletron/download.htm