IDL

O IDL (sigla de Interactive Data Language) é uma linguagem de programação cientifica utilizada nas mais diversas áreas de pesquisa. Permite ao usuário importar diversos formatos de dados (ascii, netCDF, HDF4, HDF5, GRIB, PNG, TIFF, DICOM, etc), processar e visualizá-los em gráficos 2D e 3D, superfícies, imagens e animações, em diferentes sistemas operacionais. Muito de sua sintaxe veio do Fortran e do C. Uma alternativa livre é o GDL (GNU Data Language) e sua compatibilidade pode ser vista nesse link.

Janela do IDL (modo gráfico).
Janela do IDL (modo gráfico).

Instalação

Ao arquivo original (com licença) para instalação idlVERSAOPLATAFORMA.tar.gz, execute os seguintes comandos como super usuário (como exemplo, a versão é a ‘8.2 sp2’, plataforma ‘platform’ e arquitetura ‘x86’):

# Criar pasta default para receber os arquivos de instalação
$ sudo mkdir /usr/local/exelis
# Dar acesso de leitura e escrita à pasta
$ sudo chmod a+rx /usr/local/exelis
# Copie o arquivo baixado para essa pasta (ou baixe diretamente nela)
$ cd /usr/local/exelis
$ sudo cp /path/idl82sp2platform.tar.gz .
# Descomprima e descompacte o arquivo
$ sudo tar -vzxf idl82sp2platform.tar.gz
# Execute o programa de instalação e siga os passos no prompt de comando
$ sudo ./install.sh
# (caso não tenha) Executar rotina para gerar arquivo para ser enviado ao suporte para pedir a licença
$ sudo cd idl82/bin/bin.x86/; sudo ./lmhostid > Lic_IDL; hostname >> Lic_IDL

Dentre os passos da instalação, estão aceitar os termos de licença e digitar o endereço de instalação (se não digitar nada será utilizada o padrão, que é “/usr/local/exelis”), IDL Help files, DICOM Network Services e criar links simbólicos.

A respeito da licença (considerando que sua versão não tenha tapa olho), é de costume haver um computador que atue como servidor de licenças. No servidor, deve-se copiar o arquivo “license.dat” (enviado pelo suporte) para o diretório “exelis/license”. Depois, inserir o script “servidor_licenca_idl82.sh” a seguir na pasta “/etc/init.d/” (ou inserir no arquivo “/etc/rc.local” a linha de comando executada no “start”):

#!/bin/sh
###BEGIN INIT INFO
# Provides: servidor_licenca_idl82.sh
# Required-Start: $local_fs $network $remote_fs 
# Required-Stop:  $local_fs $network $remote_fs
# Default-Start:  2 3 4 5 
# Default-Stop:   0 1 6
# Short-Description: ativa idl8.2
# Description:    Enable service provided by IDL
###END INIT INFO
case "$1" in
	start)	
	        echo "licenca idl 8.2 iniciada na rede"
		/usr/local/exelis/idl82/bin/bin.linux.x86_64/lmgrd -c /usr/local/exelis/license/license.dat -l /var/log/lmgrd.log
                ;;
 	stop)
    		echo "Mata licenca idl 8.2 "
    		killall -9 /usr/local/exelis/idl82/bin/bin.linux.x86_64/lmgrd
    		;;
  	*)
    		echo "Use: {start|stop}"
    		exit 1
    		;;
esac
exit 0

Não esquecer de dar permissão de execução para o script. Para parar/iniciar o serviço, usar o comando “/etc/init.d/servidor_licenca_idl.sh stop/start”.

Ao executar o idl, caso apareça um erro do tipo “error while loading shared libraries: libXp.so.6”, basta instalar a devida biblioteca através do comando “sudo apt-get install libxp6” ou baixando diretamente do repositório do Debian http://ftp.br.debian.org/debian/pool/main/libx/libxp/ e instalando através do comando “sudo dpkg -i libxp6_1.0.2-2_amd64.deb” (por exemplo).

No computador cliente, o arquivo de licença deve estar localizado em “/usr/local/exelis/license/license.dat” e conter o hostname (ou IP) do servidor da licença – verifique se consegue acessar a máquina pelo hostname ou pelo IP. Também será preciso definir uma variável de ambiente, incluindo no arquivo “/etc/profile” a seguinte linha: “export LM_LICENSE_FILE=1700@IP_SERVIDOR” – lembre de editar o arquivo como “sudo”.

Uso

Você pode executar o IDL em modo gráfico, através do comando “idlde” (de desktop). O modo gráfico oferece janelas à esquerda com as variáveis utilizadas e seus conteúdos, abaixo o console para digitar os comandos e à direita as abas contendo as rotinas trabalhadas (arquivos .pro). Acima, existem os botões de compilar e executar o arquivo trabalhado, assim como pausar e parar a execução. Compilar é a tradução do código fonte de uma linguagem de programação de alto nível para uma linguagem de programação de baixo nível, etapa anterior à execução.

O IDL também pode ser executado através do terminal, acessado pelo comando “idl”. No terminal do IDL, digite “.compile nome_do_arquivo” para compilar o arquivo e “.run nome_do_arquivo” para executar. Também é possível executar comandos do bash nesse terminal usando cifrão ($) antes, por exemplo “$pwd” para saber o atual diretório.

Caso a rotina seja executada via terminal Linux (em vez do terminal IDL visto anteriormente), a rotina deverá ser iniciada com “.run” escrito na primeira linha, e procedures incorporadas devem ser declaradas iniciando com “.run” e o nome dela:

ANTES

@rotina_externa.pro

DEPOIS

.run rotina_externa.pro
.run

No exemplo a seguir, a rotina é executada através do programa IDL no terminal Linux. A saída do programa e a saída de erros, em vez de serem impressa na tela, são guardadas no arquivo “rotina.log” (isso é opcional):

$ /usr/local/bin/idl < rotina.pro > rotina.log 2>&1
$ idl -e "rotina" -args $arg1 $arg2 > rotina.log 2>&1 # Alternativa, recebendo argumentos de entrada

A respeito da execução recebendo argumentos de entrada, o script desse exemplo deve conter as seguintes linhas (não precisa dos “.run” anteriores):

PRO rotina
args = command_line_args()
arg1 = args[0]
arg2 = args[1]

Comentários são iniciados pelo caractere “ponto e vírgula” (;) e o cifrão ($) indica para o IDL continuar a linha de comando na próxima linha digitada.

Variáveis

Vejamos os diferentes tipos de variáveis assumindo que “a” deverá ser declarado como:

  • Integer: a = 5
  • Long Integer: a = 5L (pode ser a letra L minúscula, mas fica parecendo o número 1)
  • Floating Point: a = 5.0
  • Double Precision: a = 5.0D
  • Complex: a = complex(5,0)
  • String: a = ‘5’

Para imprimir a variável na tela, use o seguinte comando (a linha seguinte mostra a conversão do resultado da multiplicação realizada para “long”):

IDL> print,a
IDL> print, long(1024 * a)

Arrays

Vetor (array uni-dimensional) é uma variável que armazena várias variáveis do mesmo tipo, enquanto que matriz (array multi-dimensional) é um vetor de vetores. Cada item do vetor (ou matriz) é acessado por um número chamado de índice.

Os comandos abaixo criam um vetor de 100 números, indexados de 0 a 99, (o tamanho pode ser dado pelo comando “n_elements(array)”) e uma matriz 10x7x5, ou seja, 10 colunas por 10 linhas por 5 planilhas:

IDL> V1D = fltarr(100)
IDL> V3D = fltarr(10,7,5)

Para acessar os valores, o índice é colocado entre os parênteses, e para criar vetores elemento por elemento, eles são colocados entre colchetes e separados por vírgulas (caso seja uma string, seu conteúdo deverá estar entre aspas simples) :

IDL> multi = lindgen (4, 6) ; cria matriz de quatro colunas e seis linhas
IDL> print, multi [1, 0] ; imprime o que tiver na posição coluna 1, linha 0
IDL> print, multi [*, 4] ; imprime a quinta linha
IDL> print, multi [2: 3, 1: 2] ; imprime entre a 3ª e a 4ª coluna e a 2ª e 3ª linha

Leitura e gravação de arquivos

Os seguintes comandos imprimem um texto na tela e esperam o usuário digitar um valor a ser recebido:

print, "Time Constant (tau)"
read, tau

Para ler/gravar arquivos, primeiro é necessário abrir um arquivo. Quando um arquivo é aberto, deve ser associado um número inteiro (Logical Unit Number, ou LUN). O arquivo pode ser aberto somente para leitura (OPENR), para gravação (OPENW) ou atualização (OPENU). Para leitura de arquivo é usado o comando READF e para escrita, PRINTF. O arquivo sempre deverá ser fechado, através do comando CLOSE acompanhado de seu respectivo número após a vírgula. Veja sua utilização nos exemplos mais abaixo.

Comparação

Os seguintes operadores de comparação retornam 1 para verdadeiro e 0 para falso:

  • EQ – ‘equals’
  • NE – ‘not equal’
  • LE – ‘less than or equal’
  • LT – ‘less than’
  • GE – ‘greater than or equal’
  • GT – ‘greater than’

Podem ser usados em conjunto, através dos operadores AND (todas as condições devem ser verdadeiras, ou && para comparação lógica), OR (alguma das condições deve ser verdadeira, ou || para comparação lógica) e XOR (negação, ou ~ para comparação lógica). Veja esse exemplo com o comando WHERE, que avalia uma expressão e retorna um índice unidimensional de cada elemento em um vetor para todas as expressões verdadeiras (ele retorna a posição, não os valores dos dados):

IDL> x = findgen (360) *!dtor
IDL> data = sin(x)
IDL> indices = where ( data gt 0.4 and data lt 0.5, count)
IDL> print, count ; imprime o número total de elementos encontradas
12
IDL> data [indices] = 1.0 ; atribui valor 1 para todos os elementos encontrados

Muito comum também o uso de IF/ELSE para comparações:

IDL> if (a eq 1) then print, 'a vale 1' else print, 'a não vale 1'

Comandos de “loop”

Para repetir uma sequência de comandos, são utilizados os comandos FOR, REPEAT, WHILE. Veja um exemplo de uma linha de uso do FOR (i é o contador):

IDL> for i = 1,4 do print, i, i^2 ; imprime 1 1 2 4 3 9 4 16

Agora o mesmo exemplo, só que agora usando WHILE e com mais de uma linha (nesse caso, é preciso introduzir DO BEGIN e ENDWHILE para sinalizar início e término da sequência de comandos a serem executados):

i=1
while (i lt 4) do begin
print, i, i^2
i=i+2
endwhile

Procedures e funções

Utilizadas para tornar o código mais elegante, geralmente quando um conjunto de instruções é repetido várias vezes em diferentes rotinas. Quando criadas, as procedures e as funções podem ser chamadas a partir de qualquer rotina, desde que identificada a localização caso não estejam no mesmo diretório. Procedures incluem a rotina principal e começam com a palavra pro, seguida do nome (o mesmo do nome do arquivo) e das variáveis de entrada. Ao final, colocar a palavra END. Veja o exemplo abaixo da chamada de uma procedure:

pro initialize, nuclei, t, tau, dt

As funções são como as procedures, exceto que elas retornam um argumento e os parâmetros de entrada ao dados entre parênteses:

; Função
function radius,x,y,z
r = sqrt(x^2 + y^2 + z^2)
return, r
end

; Rotina chamando função
x1 = 5.76
x2 = 4.2
x3 = 8.0
hypotenuse = radius(x1,x2,x3)

Exemplos

Segue uma rotina desenvolvida para ler um arquivo (até o final, EOF) contendo linhas com informações espaciais e temporais de um evento (2014-01-10_1945.dat) e imprimir em outro arquivo o resultado da busca com a distância do evento (msg.dat). No caso, se o evento ocorrer entre 10 minutos em um raio menor de 50 km, a informação é grava em um arquivo. A saída é formatada segundo a função FORMAT, onde o que está entre aspas é string fixa, i4 indica o número de algarismos de número inteiro e f7.2 indica também a precisão de casas decimais de um número ‘float’ (antes do ponto é o número total de algarismos contando o ponto e depois é o número de casas depois da vírgula).

.r dis1.pro
.run
dir_in = '/home/user/alerta/'
file_in = '2014-01-10_1945.dat'
file_out = 'msg.dat'
CD, dir_in
CLOSE,1
OPENR,1,dir_in + file_in
CLOSE,2
OPENW,2,dir_in + file_out

;Linhas comentadas foram utilizadas para teste, para ver o formato dos dados de entrada
;info = '2014-01-10,19:36,-16.47645,-52.6829888889'
;campos=STRSPLIT(info,',',/EXTRACT)
;lat1 = float(campos[2])
;lon1 = float(campos[3])
;temp=campos[1]
;campohm=STRSPLIT(temp,':',/EXTRACT)
;hora = long(campohm[0])
;minuto = long(campohm[1])

minmin = minuto - 10
minmax = minuto + 10
raio = 50.

a=0
m=0
d=0
hh=0
mm=0
seg=0

while eof(1) eq 0 do begin
READF,1, format='(i4,1x,6(1x,i2),i5,2(1x,f0),4x,i5,1x,f0)',a,m,d,hh,mm,seg,mili,milli,lat2,lon2,ellipse,error
dis,lon1,lat1,lon2,lat2,r1
if (r1 lt raio) AND (hh eq hora) AND (mm le minmax) AND (mm ge minmin) then printf,2,$
format='(i4,"-",i02,"-",i02,1x,i02,":",i02,":",i02," GMT Distancia = ",f7.2," km https://maps.google.com.br/maps?q=",f0,",",f0,">")'$
,a,m,d,hh,mm,seg,r1,lat2,lon2
endwhile
CLOSE,1
CLOSE,2

END

A procedure “dis” calcula a distância (r1) do evento localizado em (lat2,lon2) com relação à posição (lat1,lon1), informada no arquivo dis.pro (clique aqui para baixar), e retorna o valor de r1 (em km). Também é impresso um link html para abrir em um navegador e o Google Maps criar o mapa centrado nessa localização.

O comando “stop” interrompe a execução da rotina, o que permite testar o código até aquele ponto.

Comparação de palavras (extra)

Algo que achei interessante é a conversão de string para binário (BYTE), que pode ser seguida do cálculo do Coeficiente de correlação de Pearson (CORRELATE) para verificar se as palavras são iguais, mesmo que forem escritas com diferentes caracteres. Veja esse exemplo:

nome_escrito = 'VIÇOSA DO CEARÁ'
nome_cadastro = 'vicosa_do_ceara'
bin_nome_escrito = BYTE(nome_escrito)
bin_nome_cadastro = BYTE(nome_cadastro)
PRINT, CORRELATE(bin_nome_energia, bin_nome_raios)

Veja mais

Veja a segunda parte desse artigo, que trata de gráficos em IDL

Copie a biblioteca de procedures indo para a pasta onde deseja deixar os arquivos e execute os seguintes comandos:

$ cd /home/user/src_codes/
$ svn checkout http://idl-coyote.googlecode.com/svn/trunk/coyote # copia a biblioteca usando subversion
$ svn update # comando para atualizar a biblioteca

Edite o arquivo “.bashrc” na home do usuário para incluir as seguintes linhas:

IDL_STARTUP="/home/user/.idl/idl_startup.pro"
export IDL_STARTUP

Depois crie/edit o arquivo “idl_startup.pro” e inclua nele as linhas:

!PATH = '+/home/user/.idl/IDL_PATH/:' + !PATH
!PATH = Expand_Path(!Path)

Se estiver usando o IDL desktop, vá no menu “janela -> Preferências -> IDL -> Caminhos” e insira os caminhos “/usr/local/exelis/idl/lib” (biblioteca padrão) e “/home/user/src_codes/coyote”.

One comment

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.