para pessoas que não sabem c++ alexandre suaide aula 2

30
... para pessoas que não sabem c+ + Alexandre Suaide aula 2

Upload: internet

Post on 16-Apr-2015

115 views

Category:

Documents


2 download

TRANSCRIPT

Page 1: para pessoas que não sabem c++ Alexandre Suaide aula 2

... para pessoas que não sabem c++

... para pessoas que não sabem c++

Alexandre Suaideaula 2

Page 2: para pessoas que não sabem c++ Alexandre Suaide aula 2

O legoO lego

Page 3: para pessoas que não sabem c++ Alexandre Suaide aula 2

Organização das aulasOrganizaçã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

Page 4: para pessoas que não sabem c++ Alexandre Suaide aula 2

Macros no ROOTMacros 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()

Page 5: para pessoas que não sabem c++ Alexandre Suaide aula 2

Exemplos simplesExemplos simples

• Para executar– Método 1

– Método 2

void hello(){ cout <<"Hello world"<<endl;}

root.exe [0] .L hello.Croot.exe [1] hello()

root.exe [0] .x hello.C

hello.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();}

hist.C

• Passando parâmetros– Método 1

– Método 2

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

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

Page 6: para pessoas que não sabem c++ Alexandre Suaide aula 2

Compilando macros... Tornando a execução mais rápida

Compilando 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 root.exe [0] gSystem->Load(“macro.so”)

• Ex: macro hist.CcompileMacro hist.Crootroot.exe [0] gSystem->Load(“hist.so”)root.exe [1] hist(20,3)

gSystem é uma variável de ambiente do ROOT

(classe TSystem)

Page 7: para pessoas que não sabem c++ Alexandre Suaide aula 2

Alguns cuidados na hora de compilar macrosAlguns 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-4*RMS, mean+4*RMS); for(int i = 0;i<2000;i++) h->Fill(gRandom->Gaus(mean,RMS)); h->Draw();}

Page 8: para pessoas que não sabem c++ Alexandre Suaide aula 2

Criando sem perder a classeCriando 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

Page 9: para pessoas que não sabem c++ Alexandre Suaide aula 2

Regras para criação de classes(necessárias somente se você quiser integração total com o

ROOT)

Regras 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-E. 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.

Page 10: para pessoas que não sabem c++ Alexandre Suaide aula 2

ExemploExemplo

#include "TObject.h"class TTeste: public TObject{ public: TTeste(); virtual ~TTeste();

ClassDef(TTeste,1)};

TTeste.h

#include "TTeste.h"#include <iostream>using namespace std;

ClassImp(TTeste)

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

TTeste.cxx

Versão da classe

Page 11: para pessoas que não sabem c++ Alexandre Suaide aula 2

Compilando classesCompilando 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

Page 12: para pessoas que não sabem c++ Alexandre Suaide aula 2

Algumas regras para o comando compileAlgumas 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]

Page 13: para pessoas que não sabem c++ Alexandre Suaide aula 2

ScanRoot e PelToolsScanRoot 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

Page 14: para pessoas que não sabem c++ Alexandre Suaide aula 2

Idéia por trás do ScanRootIdé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

Page 15: para pessoas que não sabem c++ Alexandre Suaide aula 2

ScanRootScanRoot

• Iniciando o programa. – Digite:

– Para um help, 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

type menu() to open the ScanRoot Menu

ScanRoot [0]>scanroot -h

******************************************* ** ** ** 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 Menufile1, file2,... open root files and display the browser

Page 16: para pessoas que não sabem c++ Alexandre Suaide aula 2

A interface gráficaA 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

Page 17: para pessoas que não sabem c++ Alexandre Suaide aula 2

Além da interface gráfica, há comandos para o prompt

Alé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 (N=0 processa o arquivo inteiro)– tools()

• Abre a janela de PelTools– help()

Page 18: para pessoas que não sabem c++ Alexandre Suaide aula 2

Analisando dadosAnalisando 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)

Page 19: para pessoas que não sabem c++ Alexandre Suaide aula 2

Como fazer histogramasComo 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()

Page 20: para pessoas que não sabem c++ Alexandre Suaide aula 2

Mantendo a memória em ordem Mantendo 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 i=0;i<10;i++) 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

Page 21: para pessoas que não sabem c++ Alexandre Suaide aula 2

Algumas ferramentas no auxílio de gerenciamento

Algumas 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

Page 22: para pessoas que não sabem c++ Alexandre Suaide aula 2

Procurando objetos na memória (gROOT)Procurando objetos na memória (gROOT)

• O ROOT mantém uma lista de objetos criados na memória. 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 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->FindObject(“h”);

– TROOT::ls();• Lista o conteúdo da memória do ROOT

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

Page 23: para pessoas que não sabem c++ Alexandre Suaide aula 2

Essa mensagem aparece porque tenta-se criar vários

objetos com o mesmo nome.

TMemStatTMemStat

• TMemStat fornece informação sobre o uso de memória no ROOT– TMemStat::PrintMem(“”);

• Fornece a quantidade de memória sendo usada e quanto essa memória cresceu/diminuiu desde a última solicitação

root.exe [60] TMemStat mroot.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)

Page 24: para pessoas que não sabem c++ Alexandre Suaide aula 2

TBenchmarkTBenchmark

• 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 broot.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+00root.exe [70] b.GetCpuTime("")(Float_t)4.69999998807907104e-01

Page 25: para pessoas que não sabem c++ Alexandre Suaide aula 2

Como resolver o nosso problema de memory leak

Como 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

Page 26: para pessoas que não sabem c++ Alexandre Suaide aula 2

Caso 1: Eu só quero 1 histograma por vezCaso 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->FindObject("h"); if (h) delete h; h = new TH1F("h","teste",50,0,10);}

Não foi alocada memória adicional

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 =0;i<10000;i++) hist()root.exe [4] m.PrintMem("")

TMemStat:: total = 35.445312 heap = 10.857464 ( +0.000056)

Page 27: para pessoas que não sabem c++ Alexandre Suaide aula 2

Caso 2: o usuário controla o número de histogramas

Caso 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"; 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}

Houve aumento da memória utilizada...

...mas o usuário 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)

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)

Page 28: para pessoas que não sabem c++ Alexandre Suaide aula 2

Quando gerenciamento de memória é importante

Quando 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 feitode 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óriadisponível, o que pode acarretar no término do programa por falta de memória ouna completa degradação da performance devido ao fato do computador começara 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.

Page 29: para pessoas que não sabem c++ Alexandre Suaide aula 2

Como conseguir mais informaçãoComo 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.

htm

Page 30: para pessoas que não sabem c++ Alexandre Suaide aula 2

... Para finalizar... Para finalizar