Alexandre Suaide aula 2 Resumo da semana anterior • Root é uma coleção de classes para análise de dados com um interpretador c++ • C++ – Pequena introdução dos conceitos mais básicos – Comandos mais comuns – Classes e objetos • ROOT – Como criar e preencher histogramas – Gráficos e funções Entendendo como as coisas funcionam • Para conhecer as classes do ROOT e as suas funcionalidades, é necessário pensar em uma estrutura de árvore – Uma classe pode ser derivada de muitas outras – Uma funcionalidade específica pode estar escondida em uma outra classe • Manual de classes do ROOT – http://root.cern.ch/root/ Categories.html Obtendo informação • O ROOT possui centenas de classes diferentes – Clique na classe que mais satisfaz as suas necessidades Obtendo informação Nome da classe Árvore de derivação: todos os métodos públicos dessas classes são acessíveis por um objeto TH2F. Ex: SetLineColor() muda a cor da linha no histograma e é um método da classe TAttLine Construtores Os objetos podem ser criados de várias formas Métodos públicos Se o que você procura não está aqui, tente procurar em uma das classes mães Obtendo informação Nome da função documentação: todos os métodos públicos das classes do ROOT possuem documentação detalhada, descrevendo os parâmetros e, em muitos casos, com exemplos e figuras ilustrativas Todas as funções possuem links Se você tem dúvida pode seguir os links e obter mais informação Nesse ponto, acabou a novidade • Toda a teoria de como usar o ROOT se resume a – Saber programar em c++ – Conhecer as classes do ROOT • O mais importante para isso é estar sintonizado e familiarizado com os tutoriais e documentação no site do ROOT – Isso não quer dizer que não tem mais nada a aprender... • O c++ e ROOT são bastante ricos e em alguns casos as soluções não são tão obvias • O – – – aprendizado se faz na prática... Entrada de dados em um gráfico Manipulando gráficos e histogramas de 1 e 2 dimensões ScanRoot Problema: como criar um gráfico a partir de dados em um arquivo de texto? Exemplo: criando um gráfico com barras de incerteza O arquivo dados.dat contém 3 colunas, x, y, ey. No prompt do ROOT, digite Root [1]: TGraphErrors *g = new TGraphErrors(“dados.dat”,"%lg %lg %lg"); Root [2]: g->Draw(“AP”); Simple, isnt´t it? Como trabalhar diretamente com os atributos de um gráfico? TCanvas *c1 = new TCanvas(“canvas”,”janela de grafico”,600,600); c1->SetLogy(); TGraphErrors *g = new TGraphErrors(“teste.dat”,"%lg %lg %lg"); g->Draw(“AP”); Letras gregas e outros caracteres especiais g->SetTitle(“Electrons from heavy quarks decay”); de LaTEX podem ser obtidos com a mesma g->SetMarkerStyle(20); g->SetMarkerColor(2); sintaxe do LaTEX, substituindo \ por # g->SetLineColor(2); TAxis* Y = g->GetYaxis(); Y->SetTitle(“1/(2#pi p_{T}) d^{2}N/dp_{T}d#eta”); Y->SetTitleSize(0.03); Y->SetLabelSize(0.03); Y->SetTitleOffset(1.4); TAxis* X = g->GetXaxis(); X->SetTitle(“p_{T} (GeV/c)”); X->SetTitleSize(0.03); X->SetLabelSize(0.03); Fazendo ajustes de funções • • Vamos utilizar o nosso bom e velho gráfico do slide anterior Método mais simples de ajuste: utilizar TF1 TF1 *f = new TF1(“f”,”[0]*pow(1+x/[1],-[2])”,0,15); f->SetParameter(0,1); f->SetParameter(1,1.5); B f->SetParameter(2,9); g->Fit(f); pow( A, B) A Adicionando legenda aos gráficos • Utilize a classe TLegend – TLegend *l = new TLegend(xmin,ymin,xmax,ymax); • Os valores são fração do tamanho da janela gráfica e não coordenadas reais nos graficos – l->AddEntry(objeto,”label”,”modo de exibição”); • Modos de exibição – l = linha – p = ponto – f = cor de preenchimento • Exemplo TLegend *l = new TLegend(0.67,0.75,0.87,0.87); l->AddEntry(g,”dados”,”p”); l->AddEntry(f,”ajuste”,”l”); l->Draw(); Outro exemplo de fit (com histogramas) • Vamos criar um histograma fajuto TF1 *f = new TF1(“f”,”[0]*exp([1]*x)+gaus(2)+gaus(5)”,0,10); f->SetParameter(0,40); f->SetParameter(1,-0.3); f->SetParameter(2,20); f->SetParameter(3,4.3); f->SetParameter(4,0.2); f->SetParameter(5,56); Funções pré-definidas. f->SetParameter(6,8); O Root possui algumas funções pré-definidas, f->SetParameter(7,0.2); tais como: TH1F* h = new TH1F(“hist”,”teste”,100,0,10); gaus – Gaussiana for(int i=0; i<8000; i++) h->Fill(f->GetRandom()); polN – polinômio de grau N (N = 0...9) h->Draw(); landau – distribuição de Landau expo – exp([0]+[1]*x) Outro exemplo de fit (com histogramas) [0]*exp([1]*x)+gaus(2)+gaus(5) • Vamos ajustar o histograma h->Fit(f); • Como extrair informações da função ajustada que não seja pela tela? Outro exemplo de fit (com histogramas) [0]*exp([1]*x)+gaus(2)+gaus(5) • Qual o Х2red do ajuste? f->GetChisquare()/f->GetNDF(); 1.36299 • Qual o número de contagens no primeiro pico? TF1 *peak = new TF1(“peak”,”gaus(0)”,0,10); peak->SetParameters(f->GetParameters()+2); peak->Draw(“same”); peak->Integral(0,10); 53.5103 peak->Integral(0,10)/h->GetBinWidth(23); Essa é uma operação com ponteiros. Se você checar a documentação do ROOT verá que o 535.103 • método GetParameters() retorna um Double_t* que E no segundo? indica a posição na memória onde os parâmetros estão peak->SetParameters(f->GetParameters()+5); guardados. O +2 indica o deslocamento dentro dessa peak->Integral(0,10)/h->GetBinWidth(23); memória Integral, por definição, 1349.11 inclui o tamanho do Caso operações com ponteiros incomodem, pode-se fazer canal. Caso o canal não na força bruta: tenha tamanho == 1, deve-se ter cuidados peak->SetParameter(0,f->GetParameter(2)); extras peak->SetParameter(1,f->GetParameter(3)); peak->SetParameter(2,f->GetParameter(4)); Histogramas de duas dimensões TGraph* dedx = new TGraph("dedx.dat","%lg %lg"); dedx->Draw("AL"); Tcanvas* c1 = new TCanvas(); f->Draw(); // essa é a mesma função usada anteriormente TRandom *r = new TRandom(); TH2F* h2 = new TH2F("h2", "#DeltaE_{gas} x E_{total} para ^{7}Li", 100,0,10,100,0,2); for(int i=0;i<8000;i++) { float e = f->GetRandom(); float de = r->Gaus(dedx->Eval(e),0.1); h2->Fill(e,de); } Tcanvas* c2 = new TCanvas(); gStyle->SetPalette(1,0); h2->Draw("colz"); O ROOT possui objetos pré-definidos para auxiliar a configuração geral do ambiente. Dentre eles estão: gStyle (TStyle) → configurações padrões de estilos gráficos gROOT (TROOT) → controle geral do ROOT gSystem (TSystem) → interface com sistema operacional gPad (TPad) → sempre aponta para o pad que esta acionado Fazendo projeções de um histograma • • Projetar o histograma no eixo-y (similar para o eixo-x) – ProjectionY(“nome”,bin1,bin2,”opções”); – Note que os parâmetros são os números dos bins e não os valores no eixo Exemplo TAxis* X = h2->GetXaxis(); int bin1=X->FindBin(7.5); Int bin2=X->FindBin(9) TH1D* projTotal = h2->ProjectionY(“total”); TH1D* projBins = h2->ProjectionY(“bins”,bin1,bin2); projTotal->Draw(); projBins->Draw(“same”); Gravando objetos em arquivos .root • Ok, criei meus gráficos, histogramas, funções ou qualquer outro objeto do ROOT. Como eu posso armazená-los? • O Root possui um sistema de arquivos complexos, onde TODOS os seus objetos podem ser salvos em um arquivo com estrutura de diretórios. • TFile – Classe do ROOT para abrir, ler, gravar e manipular arquivos .root TFile: Gravando objetos em um arquivo • Uso – TFile f(“nome_do_arquivo”,”opções”); – TFile* f = new TFile(“nome_do_arquivo”,”opções”); • Opções – NEW ou CREATE – Abre o arquivo para escrita. Se o arquivo já existir, nada acontece – RECREATE – Abre a arquivo para escrita. Se o arquivo já existir, escreve por cima. – READ (ou sem opção) – Abre o arquivo para leitura. • Gravando e lendo objetos – Para gravar, use a função Write() dos objetos a serem gravados – Para ler, use a função Get(“nome”) do objeto TFile Gravando objetos no arquivo (Write) • Criamos vários objetos em vários exemplos. Como podemos gravá-los em um arquivo? TFile file("teste.root","RECREATE"); file.cd(); // muda o diretorio padrão para o arquivo criado g->Write(); dedx->Write(); f->Write(); h->Write(); h2->Write(); projTotal->Write(); projBins->Write(); file.ls(); // lista o conteudo do arquivo file.Close(); // fecha o arquivo Lendo objetos do arquivo (Get) • • Como eu recupero o histograma “h2” do arquivo? – O importante são os nomes dos objetos, que se obtém a partir do método ls() da classe TFile. TFile file("teste.root"); // abrir para leitura file.cd(); TH2F* myhist = (TH2F*)file.Get(“h2”); myhist->Draw(“colz”); Importante!!! – Não feche o arquivo enquanto estiver trabalhando com o histograma, pois o mesmo será removido da memória ROOT e a interface gráfica • O uso do ROOT em linha de comando é bastante útil – Permite automatizar as tarefas – Possibilidades praticamente ilimitadas – Análises complexas • Porém, muitos atributos podem ser alterados graficamente – Torna a manipulação mais fácil e intuitiva no mundo “for windows” atual • O ROOT possui uma interface gráfica com recursos complexos (e em expansão). TBrowser Interface gráfica para navegar os arquivos e objetos na memória do computador new TBrowser(); TCanvas Janela gráfica para uso geral (use botão da direita para menus) new TCanvas(); TCanvas (editor e toolbar) Próxima semana • Os conceitos básicos para uma análise de dados no nosso ambiente foram exploradas com o ROOT. – É possível ir adiante? • É claro, as possibilidades são muita grandes • Semana que vem – ScanRoot • Adaptando o ROOT às necessidades das análises no Pelletron • Como usar e tirar proveito do ROOT nesse ambiente • Lendo arquivos .FIL, .spk e trabalhando como os nossos dados – Bananas, projeções, contas com parâmetros, etc. Extras... Para quem estiver interessado • Entrada e saída de dados em um arquivo texto • Na primeira aula nós vimos como entrar e sair dados do teclado e monitor – cout << “Ola, quantos anos voce tem? “; – cin >> idade; • O c++ permite a mesma estrutura para entrada e saída de dados de um arquivo através das classes – ifstream • Para entrada de dados – ofstream • Para saída de dados Entrada de dados a partir de um arquivo ASCII • Vamos utilizar o mesmo arquivo do começo dessa apresentação – dados.dat – três colunas de dados float x[100],y[100],e[100]; // vetores para armazenar os dados ifstream entrada(“dados.dat”); // cria o objeto entrada para ler os dados int n = 0; // numero de linhas lidas while(!entrada.eof()) // a função eof() indica se chegou no fim do arquivo { entrada >> x[n] >> y[n] >> e[n]; // mesma sintaxe do cin n++ } entrada.close(); // fecha o arquivo Saída de dados para um arquivo ASCII • Vamos escrever os dados lidos na transparência anterior para um arquivo novosDados.dat – três colunas de dados x, y, e // of vetores de dados (x,y,e) bem como o numero de dados (n) // supõe-se já definidos na transparência anterior ofstream saida(“novosDados.dat”); // cria o objeto saída para os dados for(int i=0; i<n; i++) // loop sobre todos os dados { saida <<x[i]<<“ “<<y[i]<<“ “<<e[i]<<endl; // mesma sintaxe do cout } saida.close(); // fecha o arquivo