Uma introdução ao ROOT ● O que é o ROOT, quem o utiliza. ● Funcionalidades disponíveis. ● Modos de utilização. ● OOP em ROOT. ● Alguns exemplos. ● Representação gráfica de vectores. MEFT Física Computacional 30 Outubro 2008 Pedro Martins Introdução ● ● ● O ROOT é uma framework, escrita em C++ por físicos, para físicos. Disponibiliza aos seus utilizadores várias bibliotecas com várias classes: – Simulação e tratamento estatístico de dados, – Representação gráfica dos resultados obtidos, – Accesso a sistemas de armazenamento remotos e a sistemas de processamento paralelo, etc. O que é uma framework? – Uma framework é um conjunto de bibliotecas pré-definidas com o intuito de simplificar a vida aos programadores. – O facto de muita coisa já estar disponível é uma mais-valia. Em contrapartida, a complexidade do sistema aumenta a cada biblioteca que é adicionada. – Para que a framework seja de facto uma ferramenta feita por todos e para todos, há regras de escrita de código que devem ser cumpridas. Quem utiliza o ROOT? – Todo o tipo de físicos (teóricos, experimentalistas), principalmente aqueles que necessitam de fazer um tratamento de dados intensivo. – Economia e risk management: alguns alunos de física introduziram o ROOT em algumas empresas desta área. Funcionalidades ● Histogramas ● Gráficos ● Bibliotecas gerais de matemática, álgebra, geometria ● Vectores físicos ● Input/output local e remoto ● Funcionamento em modo paralelo (cluster) ● Documentação HTML automática ● Interfaces para outras linguagens (Python, Ruby) ● Possibilidade de utilizar bibliotecas criadas por outros grupos (ex: RooFit) Modos de utilização ● ● ● ● O ROOT foi concebido para ser utilizado em C++ mas, ao contrário dos típicos programas que vocês têm utilizado até agora, o código pode ser corrido na íntegra compilado ou interpretado. Um ficheiro de C++, se escrito de acordo com as regras da framework, pode ser compilado dentro do ROOT (uma macro). Se essa macro for uma simples função, ela pode ser chamada após a linha de compilação ter sido executada. No entanto, existe uma funcionalidade no ROOT denominada CINT, que interpreta código C++ linha-a-linha, como se de uma shell se tratasse. – Este tipo de sistema permite testar pequenas porções de código à medida que escrevemos os nossos programas. – A linha de comandos do ROOT tem um sistema de ajuda interactivo, que nos permite aceder aos métodos e membros de cada classe de uma forma expedita. – O CINT continua a ter as suas limitações! Podem surgir situações em que código interpretado não funcione correctamente, enquanto que o mesmo código compilado não apresenta qualquer problema. Como conselho geral de utilização, recomenda-se que a escrita das macros seja feita testando pequenas porções de código no CINT, mas que a versão final seja corrida em modo compilado. Uma boa macro deverá (quase) sempre ser capaz de ser corrida tanto em modo compilado como interpretado. Object-Oriented Programming ● Tudo o que vocês aprenderam sobre C++ é válido para o ROOT. ● A nomenclatura do ROOT é a seguinte: ● ● – As classes começam sempre com um T maiúsculo (TTree, TH1, TVector). – Membros de uma classe começam com um “f” minúsculo e logo de seguida com uma maiúscula (fMass, fMomentum). – Membros constantes começam com um “k” minúsculo. – Métodos começam com maiúscula, a letra inicial de cada palavra é maiúscula (FindParticle,CalculateMass). – variáveis globais começam com um “g” minúsculo. O ficheiro de cabeçalho fundamental a incluir em ROOT é #include <TRoot.h> Uma macro pode conter apenas um conjunto de instruções delimitadas por “{ }” ou elas podem ser incluídas dentro de uma função com o mesmo nome que o ficheiro onde reside a nossa macro. Instalação ● ● ● ● ● Página oficial do ROOT: http://root.cern.ch Existem tipicamente duas versões disponíveis: a versão de desenvolvimento e a versão de produção (mais estável). É recomendável utilizar esta última. Existem versões de ROOT para Linux, Windows e MacOS. Aqui será abordada apenas a instalação em Linux. O ROOT pode ser instalado a partir de binários pré-compilados ou compilando o código-fonte. O código-fonte pode ser descarregado utilizando os programas FTP, CVS ou Subversion. O método mais fácil para quem nunca utilizou CVS ou Subversion é o File Transfer Protocol (FTP). Instalação (2) Retirado das instruções de instalação oficiais do ROOT: 1) Utilizem o cliente “ftp” do vosso sistema operativo pmartins@FC: cd pasta/onde/quero/o/ROOT/instalado pmartins@FC: ftp root.cern.ch User: anonymous Password: [email protected] 2) Entrem na directoria “root” e mudem o tipo de transferência de tipo “text” para “binário”: ftp> cd /root ftp> bin 3) Obtenham a versão do ROOT (aqui a 5.20) desejada ftp> get root-v5-20-00.source.tar.gz ftp> bye 4) Unpack da distribuição: pmartins@FC: gzip -dc root-v5-20-00.source.tar.gz | tar -xf - Instalação (3) – alternativa para o download Se tiverem o cliente de CVS instalado, podem utilizar este método alternativo: 1) Login no servidor: pmartins@FC: cvs -d :pserver:[email protected]:/user/cvs login Password: cvs 2) Download da versão 5.20: pmartins@FC: cvs -d :pserver:[email protected]:/user/cvs export -P -r v5-20-00 root Instalação (4) ● ● Para poder compilar e utilizar o ROOT, é necessário definir algumas variáveis de ambiente. Ficam aqui as instruções para as shells do tipo (T)CSH e BASH: # csh: ● setenv ROOTSYS=.../root # ...=path of root directory ● setenv PATH=$ROOTSYS/bin:$PATH ● setenv LD_LIBRARY_PATH ${ROOTSYS}/lib ● # bash (a minha shell): ● export ROOTSYS=.../root # ...=pasta/onde/quero/o/ROOT ● export PATH=$ROOTSYS/bin:$PATH ● export LD_LIBRARY_PATH=${ROOTSYS}/lib Compilação: pmartins@FC: ./configure --help pmartins@FC: ./configure pmartins@FC: make ou gmake (OPCIONAL): make install Utilização básica ● Para começar o ROOT: – ● Para sair do ROOT: – ● pmartins@FC: root ou root.exe root[1] : .q Introspecção: – Visualizar objectos em memória: ● – Informação sobre uma classe: ● – root[1]: .class TString Reset ao ROOT: ● ● root[1]: .ls gROOT->Reset() Em ROOT, estão imediatamente disponíveis alguns ponteiros globais, como gROOT, gSystem e gStyle que permitem alterar a configurações padrão ou aceder a objectos presentes em memória ou em ficheiros carregados em memória. Utilização de bibliotecas em ROOT ● ● Existem várias bibliotecas dentro do ROOT que necessitam de ser carregadas em memória antes de serem utilizadas. Este processo deverá ser feito tanto em modo compilado como interpretado. – Por vezes, isso pode ser conseguido simplesmente adicionando o header file necessário: #include <TF1.h> – Outra vezes, é necessário fazer o carregamento da biblioteca précompilada: gSystem->Load(“libRooFit.so”); Durante a escrita das macros, é práctica aconselhada compilar o código frequentemente com a opção “+g”, para podermos descobrir em que linhas de código é que o ROOT são necessárias corrigir ou verificar se estamos a utilizar recursos (funções, classes, …) não disponíveis em memória. – .L MinhaMacro.C+g (compila) – MinhaMacro(arg1, arg2) (corre a função definida dentro da macro) – .x MinhaMacro.C (corre a macro sem compilar) Funções básicas ● ● ● ● O ROOT oferece um pacote de operações básicas de matemática TMath, que possui as funções já conhecidas das típicas bibliotecas “math” disponíveis em C e C++. A série de classes, no ROOT, para usar ou definir funções é a TF1, TF2 ou TF3, dependendo do número de dimensão pretendida. Uma função pode ser utilizada como uma variável ou um ponteiro: – TF1 var(“var”,”TMath::Sqrt(x)/TMath:Cos(x)”,0,4); – TF1 *ptr = new TF1(“ptr”,TMath::Sqrt(x)/TMath:Cos(x)”,0,4); Uma função do tipo TF1 também pode ser definida por uma função tradicional de C/ C++. Essa definição pode encontrar-se dentro do ficheiro onde reside o nosso programa ou pode encontrar-se noutro ficheiro que será compilado quando a função se torne necessária. Funções básicas (2) ● Exemplo: Criação de uma função para o cálculo de valores de momento transverso (pT). Esta função é chamada repetidamente durante simulações e pode ser utilizada para ajustar dados experimentais à mesma função. //-------- arg list: temperature, N1, N2, PT0 Double_t GetPt(Double_t *x, Double_t *par){ Double_t mt = TMath::Sqrt(kMassJPsi*kMassJPsi + x[0]*x[0]); Double_t pass1 = mt*TMath::BesselK1(mt/par[0])+ par[2]*TMath::Power((1 + (x[0]/par[3])*(x[0]/par[3])),-6); return x[0]*par[1]*pass1; } Nota: Nesta função, algumas variáveis foram definidas anteriormente (kMassJPsi). A variável “x” é, neste caso, um ponteiro para várias variáveis onde apenas é utilizado o primeiro índice do vector, nesta função específica. Os parâmetros apresentados no comentário encontram-se no vector “par”. TF1 *myf = new TF1("fit",GetPt,0,5,4) Matrizes ● A biblioteca necessária para trabalhar com matrizes e com algumas funcionalidades extra ligadas à álgebra é a libMatrix: – ● Criação de uma matrix simples 3x3: – ● TmatrixD neo(3,3); O elemento (i,j) pode ser acedido como se a variavel “neo” fosse uma matriz bidimensional: – ● gSystem->Load(“libMatrix.so”) Neo[0][1] = 666; Para visualizar a matriz, existe o método Print(). Matrizes (2) ● Cálculo rápido dos valores próprios de uma matriz 2x2: { TMatrixD m(2,2); m[0][0] = 2; m[0][1] = 1; m[1][0] = 1; m[1][1] = 2; m.Print(); TMatrixDEigen eigen(m); TMatrixD diag = eigen.GetEigenValues(); for(int row=0;row<diag.GetNrows();row++) cout << "Eigen value:" << diag[row][row] << endl; } Gráficos ● O ROOT tem várias ferramentas dirigidas à representação gráfica. Na verdade, muita coisa é criada automaticamente, o que torna a tarefa de visualização de um resultado bastante rápida. – ● Este tipo de acção irá criar uma janela nova (uma tela ou canvas) que pode ser manipulado graficamente (usando o rato), ou através da linha de comandos: – ● Todas as funções possuem um método Draw(): ptr->Draw(); Criação manual de um Canvas com as dimensões: TCanvas *a = new TCanvas(“a”, “My canvas”, 400,300); Qualquer objecto que possua propriedades que possam ser representadas graficamente possui um método “Draw()”. Gráficos (2) - escala ● ● ● ● Se quisermos representar os nossos vectores num canvas vazio, temos de respeitar a escala a ser utilizada naquele instante. Ao pedirmos a representação de uma função ou de um histograma, o canvas ajusta-se automaticamente às dimensões do mesmo. Vários objectos podem ser desenhados simultaneamente, utizando a palavra-chave “same” no método Draw(): – func1->Draw(); – func2->Draw(“same”); Obviamente, a escala é definida pelo primeiro objecto a ser desenhado. Gráficos (3) - estilos ● Grande parte dos objectos que podem ser desenhados possuem métodos que permitem alterar o seu aspecto, deixo aqui alguns exemplos: – SetLineColor(kRed); – SetLineWidth(3); – SetLineStyle(kDashed); – SetMarkerColor(kBlue); Representação de vectores graficamente ● #include <TArrow.h> ● TCanvas *c1 = new TCanvas(“c1”,”c1”) ● gPad->Range(0,0,10,10) ● TArrow *arrow = new TArrow(0,0,3,1) ● arrow->SetLineColor(kRed) ● arrow->Draw() Usem e abusem! Alguns conselhos Na página do ROOT encontrarão tutoriais, exemplos, o guia de utilizador e ainda o guia de referências para cada classe no ROOT... mas isto não é tudo. Alguns conselhos (2) ● ● ● No endereço http://root.cern.ch/lxr encontrarão várias caixas de busca, aconselho-vos a escrever o nome de qualquer coisa ligada ao ROOT e clicar em “search”. Este guia de referências cruzadas referencia que ficheiro de cabeçalho é que é necessário utilizar, que exemplos existem disponíveis, entre outras coisas. Existe também um método “.lxr” dentro do ROOT, experimentem. Próxima aula ● Input/Output – como lidar com ficheiros *.root ● TTrees e THistos – como lidar com binned e unbinned data ● Fits – ajustes de funções a dados gerados e a dados reais