para pessoas que n o sabem c
Download
Skip this Video
Download Presentation
... para pessoas que não sabem c++

Loading in 2 Seconds...

play fullscreen
1 / 30

... para pessoas que não sabem c++ - PowerPoint PPT Presentation


  • 83 Views
  • Uploaded on

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

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about ' ... para pessoas que não sabem c++' - chadwick-morse


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.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
organiza o das aulas
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
macros no root
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()
exemplos simples
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();

}

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

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)

alguns cuidados na hora de compilar macros
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();

}

criando sem perder a classe
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
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-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.
exemplo
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

compilando classes
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
algumas regras para o comando compile
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]
scanroot e peltools
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
id ia por tr s do scanroot
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
scanroot
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

a interface gr fica
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
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()
analisando dados
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)
como fazer histogramas
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()
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

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

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

tbenchmark
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

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
caso 1 eu s quero 1 histograma por vez
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

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

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

como conseguir mais informa o
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
ad