Title: ... para pessoas que n
1... para pessoas que não sabem c
2O lego
3Organizaçã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
- Macros
- Inovando sem perder a classe.
- Análise de dados no Pelletron
- ScanRoot e PelTools
- Debug, memory leaks e administrando objetos
4Macros no ROOT
- O que é um macro?
- Conjunto de comandos (como um programa) gravados
em um arquivo. - Em geral é interpretado, mas pode-se compilar
- O processo de compilação exige que o macro esteja
consistente com o c standard - Como ler e executar
- .L carrega um macro na memória
- .x carrega e executa a função do macro cujo
nome seja o mesmo do macro - Ex .x teste.C
- Carrega o macro teste.C e executa a função teste()
5Exemplos simples
hello.C
- Para executar
- Método 1
- Método 2
void hello() cout ltlt"Hello world"ltltendl
root.exe 0 .L hello.C root.exe 1 hello()
root.exe 0 .x hello.C
- Passando parâmetros
- Método 1
- Método 2
root.exe 0 .L hist.C root.exe 1 hist(20,3)
root.exe 0 .x hist.C(20,3)
hist.C
void hist(float mean, float RMS) TH1F h
new TH1F("h","teste",50,mean-4RMS, mean4RMS)
for(int i 0ilt2000i) h-gtFill(gRandom-gtGaus(m
ean,RMS)) h-gtDraw()
6Compilando macros... Tornando a execução mais
rápida
- Compilar macros torna a execução 10-1000 vezes
mais rápida - Para compilar um macro, digite, no prompt do
linux
compileMacro macro.C
- Esse comando só está disponível no PelTools
- O macro compilado gera uma biblioteca
compartilhada (.so) - Para carregar a biblioteca digite, no ROOT
gSystem é uma variável de ambiente do ROOT
(classe TSystem)
root.exe 0 gSystem-gtLoad(macro.so)
compileMacro hist.C root root.exe 0
gSystem-gtLoad(hist.so) root.exe 1 hist(20,3)
7Alguns cuidados na hora de compilar macros
- O processo de compilação utiliza um compilador
padrão 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 estória é outra - O compilador não sabe sobre as definições do ROOT
- Deve-se incluir explicitamente as definições 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-4RMS, mean4RMS)
for(int i 0ilt2000i) h-gtFill(gRandom-gtGaus(me
an,RMS)) h-gtDraw()
8Criando sem perder a classe
- O ROOT oferece a possibilidade de criar as suas
próprias classes - Utilize o mesmo padrão de programação em c
- Porém o ROOT oferece algumas vantagens
- Integração completa com o framework do ROOT
- Criação de dicionários para utilizar o prompt de
comando, incluindo a tecla TAB para completar
comandos - Gerenciamento de IO.
- Pode-se gravar objetos de classes criadas pelo
usuário em arquivos root - Atualização de versões.
- O ROOT gerencia automaticamente a evolução das
classes que são criadas. - Para usar essas benfeitorias deve-se seguir
algumas regras
9Regras para criação de classes(necessárias
somente se você quiser integração total com o
ROOT)
- Classes devem ser derivadas do TObject ou TNamed
(ou de outras classes derivadas delas) - Isso inclui automaticamente métodos de IO, como
Write(), Get(), etc... - Utilizar os macros ClassDef e ClassImp na
definição da classe - Esses macros são essenciais na geração do
dicionário e também no gerenciamento de versões - O dicionário faz com que possa-se utilizar o
prompt de comandos para manusear objetos
definidos a partir de novas classes - O gerenciamento de versões faz com que possa-se
ler objetos de arquivos root criados a partir de
definições antigas de novas classes. - Ex cria-se uma classe para cuidar de um
telescópio E-DE. Faz-se algumas análises e
grava-se alguns objetos em um arquivo. Após um
tempo, muda-se a estrutura dessa classe para
torná-la melhor. O gerenciamento de versões faz
com que consiga-se ler os objetos definidos com a
versão antiga da classe.
10Exemplo
TTeste.h
include "TObject.h" class TTeste public
TObject public TTeste()
virtual TTeste() ClassDef(TTeste,1)
TTeste.cxx
include "TTeste.h" include ltiostreamgt using
namespace std ClassImp(TTeste) TTesteTTeste()
cout ltlt"Esse é o construtor"ltltendl TTeste
TTeste() cout ltlt"Esse é o
destrutor"ltltendl
Versão da classe
11Compilando classes
- Classes podem ser lidas do mesmo jeito que
macros, porém 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 dicionário com o comando rootcint
- Linkar o dicionário 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 diretório,
gera os dicionários, compila tudo e cria um
arquivo .so
12Algumas regras para o comando compile
- Todos os arquivos devem estar em um único
diretório - Os headers devem ter extensão .h e os códigos,
.cxx - Cada classe deve ser definida em um arquivo .h
cujo nome deve ser o mesmo da classe (facilita
geração do dicionário) - Ex a classe TTeste deve ser definida no arquivo
TTeste.h - Uso
- cd para o diretório onde estão as classes
- Digite compile nome do arquivo .so
13ScanRoot e PelTools
- ScanRoot
- Versão modificada do ROOT que inclui bibliotecas
e métodos para análise dos dados tomados no
Pelletron - Agrupa as funções do SCAN DAMM
- Abre e lê arquivo de dados brutos (.FIL)
- Preenche histogramas a partir dos dados, etc
- PelTools
- Classe definida com algumas funções básicas para
análise de dados no Pelletron, como traçar
bananas, projeções, ajustes de picos etc. - Setup
- Inclua no seu arquivo de login
- source /mnt/software/setup
14Idéia por trás do ScanRoot
- Os dados são adquiridos no Pelletron e gravados
em um formato especial (.FIL) - Bastante compacto
- Informação 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 funções que
processarão os eventos - Processar os eventos
- Gravar os resultados
15ScanRoot
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 type menu() to open
the ScanRoot Menu ScanRoot 0gt
- Iniciando o programa.
- Digite
- Para um help, digite
scanroot
scanroot -h
S c a n R o o t v 2.0
(c)
2003-2004 A. A. P. Suaide
usage spmroot -hhelp
-ddebug -ttools 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
16A interface gráfica
- Como processar um arquivo .FIL
- Clique em Open .FIL e selecione o arquivo
- Clique em Load Histograms e selecione a
biblioteca com as definições dos histogramas - Clique em GO
- Clique em Save Histograms para salvar os
histogramas gerados - Para abrir a janela de análise, clique em
PelTools Menu
17Além da interface gráfica, há comandos para o
prompt
- Comandos básicos
- hac(filename)
- Carrega arquivo de definição de histogramas
- openInput(filename)
- Abre o .FIL
- openOutput(filename,outNumber)
- Abre um novo arquivo FIL para gravação
- loadL2(filename)
- Carrega definição de trigger de software
- saveHist(filename)
- Grava arquivo de histogramas
- go(N)
- Processa N eventos (N0 processa o arquivo
inteiro) - tools()
- Abre a janela de PelTools
- help()
18Analisando dados
- Usando o prompt de comando (RootCint)
- Alta flexibilidade
- Interpretador c/ROOT
- Usando o PelTools
- Pequena interface gráfica que auxilia, dentre
outras coisas - Criação de bananas (TCutG)
- Projeção de histogramas
- Ajustes de picos, etc
- Ajuste bastante rudimentar (precisa
desenvolvimento)
19Como fazer histogramas
- Pequena rotina em c
- Todo o poder do c e do ROOT disponíveis
- Não precisa compilar
- O ScanRoot compila sozinho
- Mesmo programa pode ser usado para aquisição de
dados (SPMRoot) - Header
- Incluir bibliotecas básicas
- Definir variáveis globais
- 4 funções (2 obrigatórias)
- bookHistograms()
- fillHistograms()
- init()
- finish()
20Mantendo a memória em ordem
- Objetos criados no heap (comando new) só são
deletados quando explicitamente requisitados - Isso gera um problema de gerenciamento de memória
- Considere o seguinte exemplo
void hist() TH1F h new TH1F("h","teste",50,
0,10) root.exe 0 for(int i0ilt10i)
hist()
Vários objetos são criados com o mesmo nome, além
disso, os ponteiros são perdidos. Perdeu-se o
acesso àquele objeto mas a memória continua
alocada
MEMORY LEAK
21Algumas ferramentas no auxílio de gerenciamento
- O ROOT possui alguma classes para ajudar no
gerenciamento do sistema como um todo - TROOT
- Ponto de entrada do ROOT. Permite acesso a cada
objeto criado dentro do ROOT, além de outras
informações do sistema (variável global gROOT) - TSystem
- Define a interface básica com o sistema
operacional (variável global gSystem) - TMemStat
- Auxilia na monitoração do uso de memória
- TBenchmark
- Auxilia na medida de tempo (total e CPU) de
processamento de um certo processo
22Procurando objetos na memória (gROOT)
- O ROOT mantém uma lista de objetos criados na
memória. Essa lista é indexada pelo nome do
objeto. - TROOTFindObject(char name)
- Retorna o ponteiro para o objeto cujo nome é
name - Resolve somente casos onde o endereço (ponteiro)
do objeto foi perdido. Objetos criados com o
mesmo nome são perdidos, a menos que se tome o
cuidado de guardar os ponteiros dos mesmos
root.exe 0 TH1F h gROOT-gtFindObject(h)
- TROOTls()
- Lista o conteúdo da memória do ROOT
root.exe 0 gROOT-gtls() TROOT Rint
The ROOT of EVERYTHING OBJ TH1F h
teste 0 at 0x8d4ca20
23TMemStat
- TMemStat fornece informação sobre o uso de
memória no ROOT - TMemStatPrintMem()
- Fornece a quantidade de memória sendo usada e
quanto essa memória cresceu/diminuiu desde a
última solicitação
root.exe 60 TMemStat m root.exe 61
m.PrintMem("") TMemStat total
41.175781 heap 15.332096 ( 0.102976) root.exe
62 for (int i0ilt10000i) hist() Warning in
ltTH1Buildgt Replacing existing histogram h
(Potential memory leak). Warning in ltTH1Buildgt
Replacing existing histogram h (Potential memory
leak). ... Warning in ltTH1Buildgt 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
vários objetos com o mesmo nome.
24TBenchmark
- TBenchmark é um relógio para medir o desempenho
de execução do código - Vários métodos
- Start() Inicia relógio
- Stop() Para relógio
- GetRealTime() Fornece tempo real de execução
- GetCpuTime() Fornece tempo de cpu
root.exe 67 TBenchmark b root.exe 68
b.Start("") for(int i0ilt1000i) hist()
b.Stop("") Warning in ltTH1Buildgt Replacing
existing histogram h (Potential memory
leak). ... Warning in ltTH1Buildgt Replacing
existing histogram h (Potential memory
leak). root.exe 69 b.GetRealTime("") (Float_t)1.
09000003337860107e00 root.exe 70
b.GetCpuTime("") (Float_t)4.69999998807907104e-01
25Como resolver o nosso problema de memory leak
- Duas situações diferentes
- Eu só quero 1 histograma por vez na memória
- Tenho que destruir o velho antes de criar o novo
- Nesse caso, costuma-se dizer que o objeto
pertence à função pois a função decide se o
objeto continua vivendo ou não - Eu realmente necessito de vários histogramas na
memória - Ou eu ponho nomes diferentes para cada
histograma... - ...ou eu mantenho os ponteiros de cada histograma
construído com o mesmo nome - Nesse caso, costuma-se dizer que o objeto não
pertence à função pois ela não controla a vida do
mesmo
26Caso 1 Eu só quero 1 histograma por vez
- Usar o ROOT para verificar se o objeto já existe
na memória e deletá-lo, caso necessário
void hist() TH1F h gROOT-gtFindObject("h")
if (h) delete h h new TH1F("h","teste",50,
0,10)
Esse procedimento é lento pois, a cada chamada da
função, a mesma precisa procurar pelo objeto.
Porém, é seguro.
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 0ilt10000i) hist() root.exe 4
m.PrintMem("") TMemStat total
35.445312 heap 10.857464 ( 0.000056)
Não foi alocada memória adicional
27Caso 2 o usuário controla o número de histogramas
- Vamos fazer direito
- Cada objeto possui um nome distinto
- A função retorna um ponteiro do objeto criado
TH1F hist(int index) TString nome "hist"
nomeindex // cria um histograma cujo nome é
histxxxx TH1F h new TH1F(nome,nome,50,0,10)
return h // retorna o ponteiro do objeto recem
criado
Houve aumento da memória utilizada...
...mas o usuário tem controle sobre ela
root.exe 1 TH1F hist10000 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
0ilt10000i) histi hist(i) root.exe 5
m.PrintMem("") TMemStat total
46.007812 heap 22.093968 (11.230336)
root.exe 6 for(int i 0ilt10000i) delete
histi root.exe 7 m.PrintMem("") TMemStat
total 46.007812 heap 10.920744
(-11.173224)
28Quando gerenciamento de memória é importante
- Do ponto de vista do programador
- Sempre
- Do ponto de vista do cientista
- Quando não fazer gerenciamento causar problema
Na prática, deve-se tomar cuidado com a memória.
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
memória disponível, o que pode acarretar no
término do programa por falta de memória ou na
completa degradação da performance devido ao fato
do computador começar a fazer swap em
disco. Programinhas onde somente são criados
alguns objetos, apesar de não ser
elegante, pode-se viver com um pequeno vazamento
de memória.
29Como 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.ht
m
30... Para finalizar