domingo, 21 de novembro de 2010

Juntando arquivos PDF num só

Num dia desses gerei dois documentos em PDF, por softwares distintos. A união dos conteúdos destes documentos era necessária, mas tornar-se-ia complicada e, muito provavelmente, perder-se-ia a fomatação de algum.

Para resolver esta questão procurei um jeito de unir os dois arquivos, tornando-os em um arquivo PDF apenas, cujo conteúdo poderia ser usado e entendido sem problemas. A solução surgiu no site Linux.com, na página intitulada: Putting together PDF files, que retransmito aqui.

Suponha que você gerou um texto no OpenOffice Writer e uma planilha eletrônica no OpenOffice Calc, dos quais foram produzidos dois arquivos PDF: texto.pdf e planilha.pdf. Por questões de pressa, você não quer perder tempo colando, copiando e arrumando a planilha no texto. Um arquivo PDF contendo estes dois é gerado facilmente digitando o comando abaixo num terminal do linux:

gs -dBATCH -dNOPAUSE -q -sDEVICE=pdfwrite -sOutputFile=textoFinal.pdf texto.pdf planilha.pdf

no qual tem-se:

gs -> chama o programa Ghostscript, que processará os arquivos PDF

-dBATCH -> sai do Ghostscript após processar os arquivos PDF

-dNOPAUSE -> faz o Ghostscript processar cada página sem pausas que permitam interação com o usuário

-q -> não deixa o Ghostscript exibir mensagens enquanto está em operação

-sDEVICE=pdfwriter -> avisa ao Ghostscript que deve ser usado o escritor PDF embutido (que acompanha o Ghostscript)

-sOutputFile=textoFinal.pdf -> informa ao Ghostscript o nome do arquivo que conterá a combinação dos arquivos texto.pdf e planilha.pdf.

O site que apresenta esta solução para a união de arquivos PDF mostra dois outros métodos. Entretanto, como esta página foi publicada em junho de 2004, uma das alternativas não é encontrada pelo link disponibilizado e o outro método usa um software pago.

O Ghostscript vem normalmente instalado na maioria das distribuições Linux. Isto torna mais prático o uso do comando acima para unir vários arquivos PDF num único arquivo PDF.

Um conhecimento mais aprofundado sobre o Ghostcript pode enriquecer ainda mais este processamento, mas isto foge o propósito deste post. Quem sabe, futuramente ...

quinta-feira, 18 de novembro de 2010

Instalando o NCL no Fedora 12 ou superior

ATUALIZAÇÃO (22/04/2014):

Isso não é uma novidade propriamente dita, mas coloco essa atualização para que não ocorra mal entendidos na hora da instalação do NCL via comando yum, no sistema Fedora. A instalação do NCL no sistema Fedora não aparenta mais ter os problemas apontados abaixo.

Assim, de acordo com algumas experiências, tudo funciona de maneira normal no NCL instalado via comando yum no Fedora. Portanto, num sistema Fedora, instala-se facilmente o NCL com o comando:

yum install ncl*

sendo que este comando deve ser usado como administrador do sistema. O "*" com o "ncl" garante que todos os demais pacotes para o NCL sejam instalados. OBS.: Não há espaço entre "ncl" e "*".

Entretanto, cabe lembrar que para esse método de instalação (via comando yum) não é dado suporte pela equipe de desenvolvimento do NCL, mas é muito provável que o usuário responsável por esse método ajude ao se colocar alguma dúvida na lista de discussão do NCL.

------------------------- // ----------------------------------------

ATUALIZAÇÃO (29/09/2011):

Recentemente, evidenciei um problema sério com o NCL instalado via repositórios do Fedora. Ao tentar utilizar funções de manipulação de data, em particular a função ut_calendar, o NCL é abortado e recebo o seguinte aviso: Falha de segmentação (segmentation fault). Ainda não investiguei a causa, mas parece-me um problema com o pacote udunits2, que é instalado junto com o NCL, como dependência.

Portanto, em função deste problema, que surgiu em diferentes computadores, É FORTEMENTE NÃO RECOMENDADA a instalação do NCL por meio do procedimento apresentado abaixo. Ao menos enquanto não for encontrada uma solução.

Caso ele já tenha sido instalado, desinstale os pacotes instalados (apresentados na Figura abaixo) com o comando yum remove , sendo o nome do pacote a ser desinstalado.

Instale o NCL usando um dos dois métodos padrão citados abaixo.

--------------------- // -----------------------------------

Aquele que deseja instalar o NCL em um sistema Linux conhece, ao ler as informações sobre a sua instalação no site www.ncl.ucar.edu, que há dois métodos padrão para tal procedimento:

1) instalar os binários compilados pelos desenvolvedores do NCL, que requer o conhecimento da versão do GCC (GNU Compiler Collection), qual a distribuição Linux na qual ele será instalado e em que tipo de máquina o Linux se encontra, ou

2) compilar o código fonte do NCL; procedimento que necessita da compilação e/ou instalação de outros softwares.

O primeiro é o recomendado pelos desenvolvedores do NCL, pois não requer conhecimentos avançados de compilação e instalação em sistema Linux. Basta que o usuário certifique-se que o seu sistema satisfaça os itens requeridos - listados acima - e instale os arquivos nos locais apropriados. Maiores detalhes podem ser encontrados aqui.

O segundo método, apesar de permitir uma instalação mais personalizada (uma vez que o usuário habilitará apenas os recursos do NCL que lhe interessam), exige maior conhecimento sobre a compilação e instalação de programas a partir de códigos fontes. Provavelmente, este processo tomará muito mais tempo do usuário que o primeiro. Mais informações são encontradas aqui.

Infelizmente, nem todas as versões do GCC são contempladas com uma versão já compilada do NCL. Este fato, aliado à dificuldade do segundo processo de instalação, dificulta o uso do NCL por usuários iniciantes no ambiente Linux.

Nas últimas versões da distribuição Fedora (a partir da 12ª), o NCL está disponível nos repositórios de instalação desta distribuição, permitindo que o usuário instale o NCL por um terceiro caminho.

Para instalá-lo, digite no terminal (ou console), como root (administrador), a linha de comando abaixo:

yum install ncl*

na qual yum é o comando de instação e desinstalação de pacotes (nome dado a conjuntos de arquivos que constituem um programa), e install é a opção que informa ao comando yum que deseja-se instalar todos os pacotes cujos nomes começam com ncl.

Este procedimento requer conexão com a internet para que o yum acesse os repositórios de instalação do Fedora. Após a verificação da disponibilidade de pacotes, o comando yum mostrará todos os pacotes necessários à instalação do NCL, conforme mostrado abaixo.




Para instalar, basta digitar "s", para sim, e aguardar a finalização da instalação do NCL.

Para usar, basta digitar "ncl" no terminal. Se você está começando, dê uma olhada na documentação do NCL, em seu site, para ver detalhes do seu uso.

Instalação mal sucedida?

Tanto o usuário experiente quanto o usuário iniciante podem pensar, após alguns testes com o NCL, que ocorreu algum tipo de erro em sua instalação. Esta constatação surgirá ao se tentar rodar scripts do NCL - sejam aqueles disponibilizados nos exemplos do site, sejam aqueles escritos por usuários antigos - que requerem o carregamento à memória de scripts auxiliares como o gsn_code.ncl, o gsn_csm.ncl ou o contributed.ncl, por exemplo.

Na realidade não houve erro na instalação, mas sim uma diferença na localização destes arquivos, entre aquela usada por padrão e aquela usada na instalação do NCL no Fedora por este outro método. Por padrão, estes scritps são carregados da sequinte maneira, logo no início de um script NCL:

load "$NCARG_ROOT/lib/ncarg/nclscripts/csm/gsn_code.ncl"

na qual load é o comando do NCL para carregar scripts na memória e $NCARG_ROOT é a variável de ambiente do Linux que indica onde o NCL está instalado. No Fedora, estes scripts estão instalados em /usr/share/ncarg/nclscripts. Como resultado, um script que usa a localização padrão destes arquivos auxiliares não funcionará. Para resolver isto, basta corrigir a localização dos mesmos, usando:

load "$NCARG_ROOT/share/ncarg/nclscripts/csm/gsn_code.ncl"

Neste caso, a variável $NCARG_ROOT é igual a /usr. Outro ponto negativo deste modo de instalação do NCL é a obtenção de suporte por meio da lista de e-mails disponibilizada pelos desenvolvedores do NCL. Como este método não é padrão e não é gerenciado por eles, os desenvolvedores não têm conhecimento pleno a respeito da compilação do NCL para disponibilização nos repositórios do Fedora, tornando complicada a obtenção de ajuda.

terça-feira, 10 de agosto de 2010

Instalando GrADS no Fedora 12

Eventualmente, ajudo alguns amigos com o GrADS. Entretanto, nos últimos tempos não o tenho instalado quando coloco um novo sistema em meu computador. Assim, para tentar ajudar os amigos vou correndo baixar o GrADS e instalá-lo.

Na última vez deparei-me com um problema interessante. Instalei o GrADS conforme explicado em sua documentação, mas ele não funcionava. Ao tentar executá-lo recebia a seguinte mensagem de erro:

gradsnc: error while loading shared libraries: libtermcap.so.2: cannot open shared object file: No such file or directory

De pronto fui pesquisar em sites que fornecem pacotes para o Fedora (versão 12, no meu caso!) para tentar encontrar algum que fornecesse a tal biblioteca. Infelizmente, nenhum pacote fornece esta biblioteca, que seriam a libtermcap e libtermcap-devel. Socorro final: fóruns de discussão, lista de usuários etc.

A solução foi encontrada no Fedoraforum.org (http://fedoraforum.org/forum/showthread.php?t=210569) que retransmito aqui.

Causa do problema: Os pacotes libtermcap-2.0.8-47.i386 e libtermcap-devel-2.0.8-47.i386 foram tornados obsoletos pelos pacotes ncurses-libs-5.7-3.20090207.fc12.i686 e ncurses-devel-5.7-3.20090207.fc12.i686. Nestes pacotes não há nenhuma biblioteca chamada libtermcap.so.2.

Solução: o pacote ncurses-libs-5.7-3.20090207.fc12.i686 fornece uma biblioteca chamada /lib/libtinfo.so.5.7, da qual pode-se criar um link simbólico que aponta para libtermcap.so.2 com o seguinte comando:

ln -s /lib/libtinfo.so.5.7 /usr/lib/libtermcap.so.2

Pronto!
É só usar o GrADS!

Nota importante:

Tenha muito cuidado ao aplicar uma possível solução ao seu problema. Use SEMPRE QUE POSSÍVEL os mecanismos de instalação e manutenção do seu sistema para resolver um problema. SOMENTE EM ÚLTIMO CASO, use procedimentos alternativos. Se alguma coisa ocorrer errado, o seu sistema pode parar ou sofrer danos sérios!

No site do fórum mencionado acima, uma das mensagens sugere a instalação de pacotes de uma versão anterior do Fedora, pois a solução transcrita acima não funcionou para a pessoa que pediu ajuda. No meu caso, eu testei a instalação destes pacotes usando o yum, o instalador de pacotes do Fedora. Baixei os arquivos sugeridos e entrei com o seguinte comando:

sudo yum --nogpgcheck localinstall libtermcap-2.0.8-47.i386.rpm libtermcap-devel-2.0.8-47.i386.rpm
Plugins carregados: presto, refresh-packagekit
Configurando o processo de pacote local
Examinando libtermcap-2.0.8-47.i386.rpm: libtermcap-2.0.8-47.i386
Marcando libtermcap-2.0.8-47.i386.rpm para ser instalado
O pacote libtermcap-2.0.8-47.i386 foi tornado obsoleto pelo ncurses-libs-5.7-3.20090207.fc12.i686, o qual já está instalado
Examinando libtermcap-devel-2.0.8-47.i386.rpm: libtermcap-devel-2.0.8-47.i386
Marcando libtermcap-devel-2.0.8-47.i386.rpm para ser instalado
O pacote libtermcap-devel-2.0.8-47.i386 foi tornado obsoleto pelo ncurses-devel-5.7-3.20090207.fc12.i686, o qual já está instalado
Nada a ser feito

Traduzindo, o sistema está avisando que os pacotes são obsoletos.

É melhor procurar outra solução!

NUNCA aplique "soluções" cegamente! SEMPRE teste antes!!!

Até a próxima!

quarta-feira, 7 de julho de 2010

Substituindo caracteres acentuados em strings, no NCL

Num destes dias me deparei com uma tarefa bem interessante: criar arquivos individuais (formato ASCII), cujos nomes são compostos de strings retirados dos dados lidos. Neste caso específico, os dados eram as coordenadas espaciais dos limites municipais dos municípios do Estado de São Paulo.

Estes dados estão disponíveis para download no site do IBGE e estão no formato shapefile, que é um formato de dados vetoriais geoespaciais. O NCL suporta a leitura deste tipo de arquivo e vários exemplos estão disponíveis em http://www.ncl.ucar.edu/Applications/shapefiles.shtml. Logo colocarei um exemplo bem prático aqui.

O ponto principal e motivador deste "post" é que os nomes dos municípios, nestes arquivos, estão acentuados. Do ponto de vista de exibição do nome não há nenhum problema. Entretanto, quanto tenta-se automatizar a procura de algum município ou a geração de arquivos com as suas coordenadas limites, tendo seu nome como o nome do arquivo, as coisas complicam. Por padrão, o NCL não aceita caracteres acentuados (veja mais sobre isso em um post anterior).

Portanto, faz-se necessário um tratamento prévio das strings com o nome dos municípios antes de usá-los apropriadamente. Como a dor ensina a gemer tive que me virar para resolver este probleminha. A solução: comparar os valores decimais dos caracteres (tabela ASCII/ANSI) e substituí-los pelos mesmos caracteres sem acento.

Abaixo está uma função que criei para isto:

undef("ansi2ascii")
function ansi2ascii( string1:string )
local dummy,idxANSI,dimsANSI,i
begin
; quebra a string passada a funcao
; em um arranjo unidimensional de
; caracteres
dummy = chartoint( stringtochar( string1 ) )

; indices da tabela ANSI (ASCII extendido) com os valores
; correspondentes aos caracteres acentuados
; neste arranjo, tem-se, para cara linha:
; coluna 0 => indice inferior
; coluna 1 => indice superior
; coluna 2 => indice do caracter substitutivo
idxANSI = (/ (/192,197,65/),\ ; caractere A
(/200,203,69/),\ ; caractere E
(/204,207,73/),\ ; caractere I
(/210,214,79/),\ ; caractere O
(/217,220,85/),\ ; caractere U
(/224,229,97/),\ ; caractere a
(/232,235,101/),\ ; caractere e
(/236,239,105/),\ ; caractere i
(/242,246,111/),\ ; caractere o
(/249,252,117/),\ ; caractere u
(/199,199,67/),\ ; caractere Ç
(/231,231,99/),\ ; caractere ç
(/209,209,78/),\ ; caractere Ñ
(/241,241,110/),\ ; caractere ñ
(/39,39,32/) /) ; caractere ' (apóstrofo)

; dimensoes do arranjo com codigos ASCII/ANSI.
dimsANSI = dimsizes( idxANSI )

do i = 0, dimsANSI(0)-1
; substitui os caracteres acentuados de acordo com os
; codigos passados no arranjo idxANSI
dummy = where( dummy.ge.idxANSI(i,0) .and. dummy.le.idxANSI(i,1),\
idxANSI(i,2), dummy )
end do

; converte o arranjo unidimensional de caracteres a uma string
RESULT = chartostring( inttochar( dummy ) )

; retorna a string
return( RESULT )
end

Suponha que, lendo o conteúdo de um arquivo, obtém-se uma string contendo: "NCL não aceita acentuação". Esta string é colocanda numa variavel myString. Aplicando a função acima neste variável:

myStr = ansi2ascii( myString )

resultará no conteúdo "NCL nao aceita acentuacao" para a variável myStr. O conteúdo desta nova variável pode ser manipulado normalmente dentro do NCL.

A função utiliza índices inferior e superior para cada caractere. Isto porque a tabela ANSI está organizada de uma forma que todas as acentuações em um dado caractere estão dispostas sequencialmente. Veja o caso dos caracteres A acentuados: À=192; Á=193; Â=194; Ã=195; Ä=196; Å=197.

Usando isto em favor próprio, basta verificar se o código decimal ANSI de um dos caracteres da string analisada encontra-se entre 192 e 197. Caso positivo, substituí-se seu valor por 65, o código ASCII do caractere A.

Note que a função é bem flexível. Se mais caracteres devem ser procurados e substituídos, basta adicionar seu(s) código(s) no arranjo idxANSI, dentro da função. Nada mais precisa ser feito. Outro ponto que deve ser observado é o caso de caracteres únicos, como por exemplo, ñ, Ñ, ç e Ç. Nestes casos, basta definir os índices inferior e superior com o mesmo valor. Veja na própria função como isto é feito.

Pronto, tarefa realizada e menos um problema em aberto!

Até a próxima.

PS.: Lembre-se, toda e qualquer função ou biblioteca de funções deve ser carregada no "preâmbulo" do script, ou seja, antes corpo principal do script, entre begin ... end.

domingo, 28 de fevereiro de 2010

Funções externas no NCL

O NCL possui uma grande variedade de funções e subrotinas, como pode ser visto em http://www.ncl.ucar.edu/Document/Functions/, que mostra as funções do NCL organizadas por categorias. Mesmo com todas estas funções alguma operação bem específica pode não possuir uma função ou subrotina no NCL e você deverá produzir um programa para que ela seja realizada.

Dependendo da complexidade da operação, a utilização das funções da linguagem de script do NCL para criar este programa pode torná-lo ineficaz, levando muito tempo para completar a operação ou mesmo não conseguindo realizá-la. Nestas situações é melhor utilizar uma subrotina ou função externa, criada em outra linguagem de programação.

Um exemplo de uma operação não existente no NCL é a de adicionar linhas a um arquivo ASCII já existente. Aqui vou mostrar como é possível adicionar uma função deste tipo ao NCL por meio da linguagem Fortran 90. O NCL possibilita a utilização de subrotinas ou funções escritas em Fortran (77 ou 90) e em C nos seus scripts. Maiores informações sobre este procedimento podem ser obtidas em http://www.ncl.ucar.edu/Document/Manuals/Ref_Manual/NclExtend.shtml.

Apresento abaixo os três passos necessários para a utilização da subrotina escrita em Fortran 90.

Passo 1) Escrever a subrotina em Fortran 90, que será salva num arquivo chamado adicionaLinha.f90:

subroutine addline(arquivo, dimLinha, fmt1, fmt2, linha)

implicit none


integer,parameter :: unidES=30
logical :: existeArq
integer,intent(in) :: dimLinha,fmt1,fmt2
character(len=255),intent(in) :: arquivo
real,dimension(dimLinha),intent(in) :: linha

inquire(file=trim(adjustl(arquivo)),exist=existeArq)

if (.NOT.existeArq) then

print *,"Aviso: arquivo nao existe, arquivo sendo criado!"
open(unidES,file=trim(adjustl(arquivo)),status='new')
write(unidES,'(F.)') linha(1:dimLinha)

else

open(unidES,file=trim(adjustl(arquivo)),access='append')
write(unidES,'(F.)') linha(1:dimLinha)

end if

close(unidES)

end subroutine addLine


Passo 2) Criar um arquivo auxiliar que permite o NCL entender a sintaxe do programa em Fortran 90 apresentado no Passo 1. Este arquivo contém uma declaração da subrotina em Fortran 90 na sintaxe do Fortran 77 (Note a diferença entre as declarações das variáveis da subrotina.). Neste exemplo, o arquivo auxiliar se chamará adicionaLinha.stub:

C NCLFORTSTART
subroutine addline(arquivo,dimLinha,fmt1,fmt2,linha)
character*(*) arquivo
integer dimLinha,fmt1,fmt2
real linha(dimLinha)
C NCLEND

Passo 3) Criar um arquivo objeto compartilhado (.so) usando o comando WRAPIT (http://www.ncl.ucar.edu/Document/Tools/WRAPIT.shtml), que vem com o próprio NCL. O comando WRAPIT possui várias opções. Neste exemplo, uso uma em especial, a -in, que manda o WRAPIT usar o compilador Fortran da Intel (http://software.intel.com/en-us/articles/non-commercial-software-download/) para criar o objeto compartilhado (Por favor, veja nas notas incluídas ao final deste texto do porquê da utilização deste compilador), sendo executado da seguinte forma:

WRAPIT -in adicionaLinha.stub adicionaLinha.f90

Ao final da execução desta linha de comando um arquivo adicionaLinha.so será criado. É este arquivo que pode ser usado em scripts do NCL para executar a operação programada na subrotina escrita em Fortran 90. Abaixo passo um script em NCL para testar esta função externa:

external ADDLINE "./adicionaLinha.so"

begin

arq = "teste.txt"
a = (/1.,2.,3.,4.,5.,6.,7.,8.,9.,10./)
dimA = dimsizes(a)
fmt1 = 5
fmt2 = 1

ADDLINE::addline(arq,dimA,fmt1,fmt2,a)


end

Pronto! Uma nova função foi adicionada ao NCL graças a sua interação com outras linguagens de programação, como o Fortran 90. A execução do script em NCL escrito acima resultará num arquivo chamado teste.txt. Caso este arquivo já exista no diretório de execução do script será adicionada uma nova linha ao final do arquivo. Faça um teste, execute mais de uma vez este mesmo script!

É isso aí, espero que esta dica seja útil.



NOTA) Por que é usado o compilador Fortran da Intel?

O compilador Fortran da Intel (de uso não comercial) é usado neste exemplo por possuir algumas características do Fortran 95, como a possibilidade de criação de Expressões Variáveis de Formato (http://www.intel.com/software/products/compilers/docs/flin/main_for/lref_for/source_files/pghvarfm.htm). Isto é aplicado na subrotina escrita em Fortran 90, nas linhas com o comando write:

write(unidES,'(F.)') linha(1:dimLinha)

Nesta linha, as variáveis dimLinha, fmt1 e fmt2 são usadas para controlar o formato dos valores da variável numérica linha que serão impressos no arquivo ASCII. Essa característica proporciona a criação de uma subrotina mais flexível.