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
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
Mtodo 2
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)
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
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.
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
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
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
******************************************* ** ** ** 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
openInput(filename)
openOutput(filename,outNumber)
loadL2(filename)
Abre um novo arquivo FIL para gravao Carrega definio de trigger de software
saveHist(filename) go(N)
tools()
help()
Analisando dados
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)
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
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
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();
TMemStat
Essa mensagem aparece porque tenta-se criar vrios objetos com o mesmo
TBenchmark
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
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.
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)
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.
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