1 / 30

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

... para pessoas que não sabem c++. Alexandre Suaide aula 2. O lego. Organizaçã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

Télécharger la présentation

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

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


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

  2. O lego

  3. Organizaçã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

  4. Macros 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()

  5. Exemplos simples hello.C void hello() { cout <<"Hello world"<<endl; } root.exe [0] .L hello.C root.exe [1] hello() • Para executar • Método 1 • Método 2 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-4*RMS, mean+4*RMS); for(int i = 0;i<2000;i++) h->Fill(gRandom->Gaus(mean,RMS)); h->Draw(); }

  6. 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 gSystem é uma variável de ambiente do ROOT (classe TSystem) root.exe [0] gSystem->Load(“macro.so”) • Ex: macro hist.C compileMacro hist.C root root.exe [0] gSystem->Load(“hist.so”) root.exe [1] hist(20,3)

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

  8. Criando 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

  9. 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-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.

  10. Exemplo TTeste.h #include "TObject.h" class TTeste: public TObject { public: TTeste(); virtual ~TTeste(); ClassDef(TTeste,1) }; TTeste.cxx #include "TTeste.h" #include <iostream> using namespace std; ClassImp(TTeste) TTeste::TTeste() { cout <<"Esse é o construtor"<<endl; } TTeste::~TTeste() { cout <<"Esse é o destrutor"<<endl; } Versão da classe

  11. Compilando 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

  12. Algumas 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]

  13. ScanRoot 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

  14. Idé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

  15. 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]> • 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 [-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

  16. A 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

  17. 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()

  18. Analisando 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)

  19. Como 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()

  20. 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

  21. 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

  22. 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

  23. TMemStat • 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 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 vários objetos com o mesmo nome.

  24. TBenchmark • 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 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

  25. 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

  26. Caso 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); } 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) Não foi alocada memória adicional

  27. 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 [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) 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)

  28. 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 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.

  29. Como 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

  30. ... Para finalizar

More Related