Você está na página 1de 30

...

para pessoas que no sabem c++

Alexandre Suaide aula 2

O lego

Organizao das aulas Aula 1 Comandos (realmente) bsicos do ROOT Um pouco de c++ para usurios de ROOT Criando objetos simples (histogramas, grficos, etc) Manuseando grficos e histogramas. A interface grfica Funes e ajustes de grficos Aula 2 Macros Inovando sem perder a classe. Anlise de dados no Pelletron ScanRoot e PelTools Debug, memory leaks e administrando objetos

Macros no ROOT

O que um macro? Conjunto de comandos (como um programa) gravados em um arquivo. Em geral interpretado, mas pode-se compilar Como ler e executar .L carrega um macro na memria .x carrega e executa a funo do macro cujo nome seja o mesmo do macro
O processo de compilao exige que o macro esteja consistente com o c++ standard

Ex: .x teste.C Carrega o macro teste.C e executa a funo teste()

Exemplos simples
Para executar Mtodo 1
root.exe [0] .L hello.C root.exe [1] hello() hello.C void hello() { cout <<"Hello world"<<endl; }

Mtodo 2
root.exe [0] .x hello.C

Passando parmetros Mtodo 1


root.exe [0] .L hist.C root.exe [1] hist(20,3)

Mtodo 2

root.exe [0] .x hist.C(20,3)

hist.C
void hist(float mean, float RMS) { TH1F *h = new TH1F("h","teste",50,mean-4*RMS, mean+4*RMS); for(int i = 0;i<2000;i++) h->Fill(gRandom->Gaus(mean,RMS)); h->Draw(); }

Compilando macros... Tornando a execuo mais rpida Compilar macros torna a execuo 10-1000 vezes mais rpida Para compilar um macro, digite, no prompt do linux
compileMacro macro.C

Esse comando s est disponvel no PelTools O macro compilado gera uma gSystem uma varivel biblioteca de ambiente do ROOT compartilhada (.so) (classe TSystem) Para carregar a biblioteca digite, no ROOT Ex: macro hist.C
root.exe [0] gSystem->Load(macro.so)
compileMacro hist.C root root.exe [0] gSystem->Load(hist.so) root.exe [1] hist(20,3)

Alguns cuidados na hora de compilar macros


O processo de compilao utiliza um compilador padro c++ Cuidado com a sintaxe. Em geral, o ROOT muito tolerante com a sintaxe em c++. Macros interpretados rodam sem problemas mas na hora de compilar a estria outra O compilador no sabe sobre as definies do ROOT Deve-se incluir explicitamente as definies de classes do ROOT (#include) O macro hist.C ficaria assim:
#include TRandom.h #include TH1.h void hist(float mean, float RMS) { TH1F *h = new TH1F("h","teste",50,mean-4*RMS, mean+4*RMS); for(int i = 0;i<2000;i++) h->Fill(gRandom->Gaus(mean,RMS)); h->Draw(); }

Criando sem perder a classe O ROOT oferece a possibilidade de criar as suas prprias classes Utilize o mesmo padro de programao em c++ Porm o ROOT oferece algumas vantagens Integrao completa com o framework do ROOT

Para usar essas benfeitorias deve-se seguir algumas regras

Criao de dicionrios para utilizar o prompt de comando, incluindo a tecla TAB para completar comandos Gerenciamento de IO. Pode-se gravar objetos de classes criadas pelo usurio em arquivos root Atualizao de verses. O ROOT gerencia automaticamente a evoluo das classes que so criadas.

(necessrias somente se voc quiser integrao total com o ROOT)

Regras para criao de classes

Classes devem ser derivadas do TObject ou TNamed (ou de outras classes derivadas delas) Isso inclui automaticamente mtodos de IO, como Write(), Get(), etc... Utilizar os macros ClassDef e ClassImp na definio da classe Esses macros so essenciais na gerao do dicionrio e tambm no gerenciamento de verses
O dicionrio faz com que possa-se utilizar o prompt de comandos para manusear objetos definidos a partir de novas classes O gerenciamento de verses faz com que possa-se ler objetos de arquivos root criados a partir de definies antigas de novas classes. Ex: cria-se uma classe para cuidar de um telescpio E-DE. Faz-se algumas anlises e grava-se alguns objetos em um arquivo. Aps um tempo, muda-se a estrutura dessa classe para torn-la melhor. O gerenciamento de verses faz com que consiga-se ler os objetos definidos com a verso antiga da classe.

Exemplo
TTeste.h
#include "TObject.h" class TTeste: public TObject { public: TTeste(); TTeste.cxx virtual ~TTeste(); ClassDef(TTeste,1) }; #include "TTeste.h" #include <iostream> using namespace std;

ClassImp(TTeste)

Verso da classe

TTeste::TTeste() { cout <<"Esse o construtor"<<endl; } TTeste::~TTeste() { cout <<"Esse o destrutor"<<endl; }

Compilando classes Classes podem ser lidas do mesmo jeito que macros, porm compilar muito mais eficiente Compilar classes no ROOT algo que exige uns 3-4 comandos no prompt do Linux Compilar os arquivos propriamente ditos Gerar o dicionrio com o comando rootcint Linkar o dicionrio compilado com os outros arquivos compilados e gerar uma biblioteca compartilhada (.so) Assim, para facilitar a vida, existe o comando compile (somente no PelTools) Macro que compila todos os .cxx em um diretrio, gera os dicionrios, compila tudo e cria um arquivo .so

Algumas regras para o comando compile Todos os arquivos devem estar em um nico diretrio Os headers devem ter extenso .h e os cdigos, .cxx Cada classe deve ser definida em um arquivo .h cujo nome deve ser o mesmo da classe (facilita gerao do dicionrio) Ex: a classe TTeste deve ser definida no arquivo TTeste.h Uso: cd para o diretrio onde esto as classes Digite compile [nome do arquivo .so]

ScanRoot e PelTools ScanRoot Verso modificada do ROOT que inclui bibliotecas e mtodos para anlise dos dados tomados no Pelletron
Agrupa as funes do SCAN + DAMM Abre e l arquivo de dados brutos (.FIL) Preenche histogramas a partir dos dados, etc

PelTools Classe definida com algumas funes bsicas para anlise de dados no Pelletron, como traar bananas, projees, ajustes de picos etc. Setup Inclua no seu arquivo de login
source /mnt/software/setup

Idia por trs do ScanRoot

Os dados so adquiridos no Pelletron e gravados em um formato especial (.FIL) Bastante compacto Informao de cada evento separadamente Os dados devem ser processados para gerar os histogramas ou qualquer outra figura Aqui entra o ScanRoot
ScanRoot em 4 etapas Abrir um arquivo de dados (.FIL) Abrir uma biblioteca com as funes que processaro os eventos Processar os eventos Gravar os resultados

ScanRoot

Iniciando o programa. Digite:


scanroot

******************************************* ** ** ** S c a n R o o t v 2.0 ** ** ** ** (c) 2003-2004 A. A. P. Suaide ** ** ** *******************************************

Running ScanRoot. type scanroot -help for options

Para um help, digite:


scanroot -h

type menu() to open the ScanRoot Menu ScanRoot [0]>

******************************************* ** ** ** S c a n R o o t v 2.0 ** ** ** ** (c) 2003-2004 A. A. P. Suaide ** ** ** ******************************************* usage: spmroot [-h|help] [-d|debug] [-t|tools] [file1] [file2] ... -h or -help displays this message -d or -debug turns on debug mode and display event by event information -n or -nogui does not open the ScanRoot Menu file1, file2,... open root files and display the browser

A interface grfica
Como processar um arquivo .FIL Clique em Open .FIL e selecione o arquivo Clique em Load Histograms e selecione a biblioteca com as definies dos histogramas Clique em GO Clique em Save Histograms para salvar os histogramas gerados Para abrir a janela de anlise, clique em PelTools Menu

Alm da interface grfica, h comandos para o prompt


Comandos bsicos hac(filename)
Abre o .FIL Carrega arquivo de definio de histogramas

openInput(filename)

openOutput(filename,outNumber)
loadL2(filename)

Abre um novo arquivo FIL para gravao Carrega definio de trigger de software

saveHist(filename) go(N)

Grava arquivo de histogramas


Processa N eventos (N=0 processa o arquivo inteiro) Abre a janela de PelTools

tools()

help()

Analisando dados

Usando o prompt de comando (RootCint) Alta flexibilidade


Interpretador c++/ROOT

Usando o PelTools Pequena interface grfica que auxilia, dentre outras coisas
Criao de bananas (TCutG) Projeo de histogramas Ajustes de picos, etc Ajuste bastante rudimentar (precisa desenvolvimento)

Como fazer histogramas


Pequena rotina em c++ Todo o poder do c++ e do ROOT disponveis No precisa compilar O ScanRoot compila sozinho Mesmo programa pode ser usado para aquisio de dados (SPMRoot) Header Incluir bibliotecas bsicas Definir variveis globais 4 funes (2 obrigatrias) bookHistograms() fillHistograms() init() finish()

Mantendo a memria em ordem

Objetos criados no heap (comando new) s so deletados quando explicitamente requisitados Isso gera um problema de gerenciamento de memria Considere o seguinte exemplo
void hist() { TH1F *h = new TH1F("h","teste",50,0,10); } root.exe [0] for(int i=0;i<10;i++) hist(); Vrios objetos so criados com o mesmo nome, alm disso, os ponteiros so perdidos. Perdeu-se o acesso quele objeto mas a memria continua alocada

MEMORY LEAK

Algumas ferramentas no auxlio de gerenciamento


O ROOT possui alguma classes para ajudar no gerenciamento do sistema como um todo TROOT

TSystem

Ponto de entrada do ROOT. Permite acesso a cada objeto criado dentro do ROOT, alm de outras informaes do sistema (varivel global gROOT) Define a interface bsica com o sistema operacional (varivel global gSystem)

TMemStat

TBenchmark

Auxilia na monitorao do uso de memria


Auxilia na medida de tempo (total e CPU) de processamento de um certo processo

Procurando objetos na memria (gROOT)


O ROOT mantm uma lista de objetos criados na memria. Essa lista indexada pelo nome do objeto. TROOT::FindObject(char* name);

Retorna o ponteiro para o objeto cujo nome name Resolve somente casos onde o endereo (ponteiro) do objeto foi perdido. Objetos criados com o mesmo nome so perdidos, a menos que se tome o cuidado de guardar os ponteiros dos mesmos root.exe [0] TH1F *h = gROOT->FindObject(h);

TROOT::ls();

Lista o contedo da memria do ROOT


root.exe [0] gROOT->ls();
TROOT* OBJ: TH1F Rint h The ROOT of EVERYTHING teste : 0 at: 0x8d4ca20

TMemStat

TMemStat fornece informao sobre o uso de memria no ROOT TMemStat::PrintMem();


Fornece a quantidade de memria sendo usada e quanto essa memria cresceu/diminuiu desde a ltima solicitao
root.exe [60] TMemStat m root.exe [61] m.PrintMem("") TMemStat:: total = 41.175781 heap = 15.332096 ( +0.102976) root.exe [62] for (int i=0;i<10000;i++) hist() Warning in <TH1::Build>: Replacing existing histogram: h (Potential memory leak). Warning in <TH1::Build>: Replacing existing histogram: h (Potential memory leak). ... Warning in <TH1::Build>: Replacing existing histogram: h (Potential memory leak). root.exe [64] m.PrintMem("") TMemStat:: total = 51.562500 heap = 26.420584 (+10.080040)

Essa mensagem aparece porque tenta-se criar vrios objetos com o mesmo

TBenchmark

TBenchmark um relgio para medir o desempenho de execuo do cdigo Vrios mtodos


Start() Inicia relgio Stop() Para relgio GetRealTime() Fornece tempo real de execuo GetCpuTime() Fornece tempo de cpu

root.exe [67] TBenchmark b root.exe [68] b.Start(""); for(int i=0;i<1000;i++) hist(); b.Stop(""); Warning in <TH1::Build>: Replacing existing histogram: h (Potential memory leak). ... Warning in <TH1::Build>: Replacing existing histogram: h (Potential memory leak). root.exe [69] b.GetRealTime("") (Float_t)1.09000003337860107e+00 root.exe [70] b.GetCpuTime("") (Float_t)4.69999998807907104e-01

Como resolver o nosso problema de memory leak

Duas situaes diferentes Eu s quero 1 histograma por vez na memria

Eu realmente necessito de vrios histogramas na memria

Tenho que destruir o velho antes de criar o novo Nesse caso, costuma-se dizer que o objeto pertence funo pois a funo decide se o objeto continua vivendo ou no

Ou eu ponho nomes diferentes para cada histograma... ...ou eu mantenho os ponteiros de cada histograma construdo com o mesmo nome Nesse caso, costuma-se dizer que o objeto no pertence funo pois ela no controla a vida do mesmo

Caso 1: Eu s quero 1 histograma por vez Usar o ROOT para verificar se o objeto j existe na memria e delet-lo, caso necessrio
void hist() { TH1F *h = gROOT->FindObject("h"); if (h) delete h; h = new TH1F("h","teste",50,0,10); } root.exe [1] TMemStat m; root.exe [2] m.PrintMem("") TMemStat:: total = 35.445312 heap = 10.857408 (+10.857408) root.exe [3] for(int i =0;i<10000;i++) hist() root.exe [4] m.PrintMem("") TMemStat:: total = 35.445312 heap = 10.857464 ( +0.000056)

Esse procedimento lento pois, a cada chamada da funo, a mesma precisa procurar pelo objeto. Porm, seguro.

No foi alocada memria adicional

Caso 2: o usurio controla o nmero de histogramas

Vamos fazer direito Cada objeto possui um nome distinto A funo retorna um ponteiro do objeto criado
TH1F* hist(int index) { TString nome = "hist"; nome+=index; // cria um histograma cujo nome histxxxx TH1F *h = new TH1F(nome,nome,50,0,10); return h; // retorna o ponteiro do objeto recem criado } root.exe [1] TH1F *hist[10000] root.exe [2] TMemStat m; root.exe [3] m.PrintMem("") TMemStat:: total = 35.144531 heap = 10.863632 (+10.863632) root.exe [4] for(int i =0;i<10000;i++) hist[i] = hist(i) root.exe [5] m.PrintMem("") TMemStat:: total = 46.007812 heap = 22.093968 (+11.230336)

Houve aumento da memria utilizada... ...mas o usurio tem controle sobre ela

root.exe [6] for(int i =0;i<10000;i++) delete hist[i] root.exe [7] m.PrintMem("") TMemStat:: total = 46.007812 heap = 10.920744 (-11.173224)

Quando gerenciamento de memria importante

Do ponto de vista do programador Sempre Do ponto de vista do cientista Quando no fazer gerenciamento causar problema
Na prtica, deve-se tomar cuidado com a memria. Quando um trabalho for feito de tal forma que cria-se algumas centenas ou milhares de objetos, dependendo do tamanho de cada um, pode-se, facilmente, alocar praticamente toda a memria disponvel, o que pode acarretar no trmino do programa por falta de memria ou na completa degradao da performance devido ao fato do computador comear a fazer swap em disco. Programinhas onde somente so criados alguns objetos, apesar de no ser elegante, pode-se viver com um pequeno vazamento de memria.

Como conseguir mais informao

Site do ROOT http://root.cern.ch Documentao 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

... Para finalizar