#|=============================================================================== #|Convert_arc | CLASS - Conversor de dados | MCT-INPE-CPTEC | #|------------------------------------------------------------------------------| #| Esta classe organiza os processo de conversao de diferenes tipos de dados | #| e diferentes formatos, que estao armazenados em um determinado repositorio | #| DATAIN. | #| Os dados do DATAIN sao selecionados pelo programa SELETOR | #| Apos selecao os dados sao convetidos pelo programa CONVERTER e armazenados| #| em DATAOUT | #| | #| E utilizada para converte dados em formato BUFR para formato ODS utilizando | #| o programa CONVERTER = "bufr2netcdf.x", ou qualquer ontro converter, desde | #| e que os paramentros necessarios estejam definidos no arquivos | #| "tipo-dados.conf" | #| | #|------------------------------------------------------------------------------| #| Objetos desta classe: | #| DATAIN = REPOSITORIO DOS DADOS DE ENTRADA | #| DATAOUT = REPOSITORIO DOS DADOS CONVERTIDOS | #| CONVERTER = PROGRAMA CONVERSOS DE DADOS | #| SELECTOR = PROGRAMA SELETOR DE DADOS - SELECIONA CONFORME UMA DATA E HORA | #|------------------------------------------------------------------------------| #| Metodos desta classe: | #| new : Metodo constutor: Cria um objeto desta classe | #| name : troca ou obtem nome do objeto desta classe | #| run : roda o objeto, processando a conversao | #|------------------------------------------------------------------------------| #| Dependencias: | #|------------------------------------------------------------------------------| #| HISTORICO #| 2006-05 - Sergio Henrique: Versao original package Convert_arc; use strict; require Exporter; our @ISA =qw(Exporter); our @EXPORT =qw(new name); use Getopt::Std; # Biblioteca para argumentos de linha de comando use Time::Local; # Biblioteca padrao para processar data e hora # Exemplo $time=timelocal($seg,$min,$horas,$dia,$mes-1,$ano-1900); # OU $time=timegm($seg,$min,$horas,$dia,$mes-1,$ano-1900); # # Exemplo 2 > Somando 24 horas a uma data # my $newtime=$time + 60*60*24; # #Exemplo 3 < subtraindo 10 minutos # my $newtime=$time -60*10; # # Exemplo 4 Imprimindo a data # print scalar(localtime($timei)),"\n"; # # Exemplo 5 Comparando datas # if (($timef > $time) && ($timei< $time) { # use Cwd; # biblioteca para obter o path ou diretorio de trabalho use Glib; # Biblioteca de de subrotinas de uso geral use seletor_padrao; use seletor_bufrtime; use File::Copy; #|=============================================================================== #|new | Metodo construtor | MCT-INPE-CPTEC | #|------------------------------------------------------------------------------| #| Carrega arquivos de configuracao (nome_da_classe.conf) | | #|------------------------------------------------------------------------------| sub new { my $proto = shift; my $class = ref($proto) || $proto; #Obtem uma referencia para estanciar objetos desta classe my $self = {}; # Array de propriedades desta classe $self->{NAME} = shift; # Propriedade NAME #{ OBTEM DIRETORIO DE TRABALHO (ROOT) my $key=keys(%ENV); my $root; if ($key="CONVERDIR"){$self->{ROOT}=$ENV{$key};} print "$self->{ROOT}\n"; #} #{ Define as propriadades iniciais desta classe de objetos $self->{DATAIN}=undef; $self->{DATAOUT}=undef; $self->{CONVERTER}=undef; $self->{SELETOR}=undef; $self->{SETPARM}=undef; $self->{INFILE}="*"; $self->{OUTFILE}=undef; $self->{NCGEN}=undef; $self->{FLUXO}=undef; $self->{CODES}=undef; $self->{SUBTYPES}=undef; $self->{OBSDATE}=undef; $self->{CFILE}=undef; $self->{TMPDIR}=undef; $self->{MODO}=" normal"; $self->{TIMEWINDOW}=3*60*60; $self->{FILA}="none"; #{ FAZENDO A LEITURA DO ARQUIVO DE CONFIGURACAO my $filename=$self->{ROOT}."convert_".$self->{NAME}.".conf"; open (UN, "< ".$filename) or die "Can't open". $filename; my $line; while($line=) { my $i=index($line,"=")+1; my $l=length($line)-$i-1; if (index($line,"datain=")>0) {$self->{DATAIN}=substr($line,$i,$l);} if (index($line,"dataout=")>0){$self->{DATAOUT}=substr($line,$i,$l);} if (index($line,"converter=")>0) {$self->{CONVERTER}=substr($line,$i,$l);} if (index($line,"selector=")>0){$self->{SELETOR}=substr($line,$i,$l);} if (index($line,"infile=")>0){$self->{INFILE}=substr($line,$i,$l);} if (index($line,"outfile=")>0){$self->{OUTFILE}=substr($line,$i,$l);} if (index($line,"fluxo=")>0){$self->{FLUXO}=substr($line,$i,$l);} if (index($line,"setparm=")>0){$self->{SETPARM}=substr($line,$i,$l);} if (index($line,"ncgen=")>0){$self->{NCGEN}=substr($line,$i,$l);} if (index($line,"codes=")>0){$self->{CODES}=substr($line,$i,$l);} if (index($line,"subtypes=")>0){$self->{SUBTYPES}=substr($line,$i,$l);} if (index($line,"cfile=")>0){$self->{CFILE}=substr($line,$i,$l);} if (index($line,"tmpdir=")>0){$self->{TMPDIR}=substr($line,$i,$l);} } close(UN); #} Fim da leitura #{ Definindo data da observacao com base na data do sistema my ($minuto,$hora,$dia,$mes,$ano)=(localtime)[1,2,3,4,5]; $self->{OBSDATE}=timelocal(0,0,$hora,$dia,$mes,$ano); $self->{OBSDATE}=wsynoptic($self->{OBSDATE}); #} print "$self->{DATAIN}\n"; print "$self->{DATAOUT}\n"; # Abencoa classe "Convert_arc" fornecendo seu proprio nome ($self) # e um indereco $class para criacao de multiplas estancias desta classe # e para permitir que a classe seja utilizada no programa principal #{ bless ($self, $class); #} return $self; } # Fim do Metodo Construtor #|=============================================================================== #|Metodo name |Nomear ou "dizer" o nome do objeto desta classe| MCT-INPE-CPTEC | #|------------------------------------------------------------------------------| #| | #|------------------------------------------------------------------------------| #| DEPENDENCIAS #|------------------------------------------------------------------------------| #| HISTORICO sub name { my $self = shift; if (@_) { $self->{NAME} = @_[0] } return $self->{NAME}; } #|=============================================================================== #|Metodo run | Roda conversao | MCT-INPE-CPTEC | #|------------------------------------------------------------------------------| #| Este metodo roda a conversao de dados para ODS segundo as propriedades #| desta classe, que estao definidas nos arquivos convert_tipo.conf #| #| O processo de conversao envolve os seguintes passos: #| a) identidicacao dos arquivos de entrada (diretorio DATAIN) #| b) Selecao dos aquivos conforme data e tipo #| c) Concatenacao dos arquivos de entrada em um unico arquivos #| (CFILE no diretorio SELECTED) #| d) Processar a conversao do arquivos CFILE para formato intermediario (CDL) #| e) Converter o CDL para ODS usando o software NCGEN #| #| Os arquivos de entrada podem estar em diretorios do seguintes tipos: #| {DATAIN}FLUXO_XXX/TTTT/SS/YYYY/MM/DD #| #| onde YYYYMM = ano e mes #| FLUXO_XXX = Tipo do Fluxo #| DD = Dia #| TTTT = Codigo de telecomunicacoes (opcional) Ex.: IUCN, IUCS, etc. #| SS = SUBTIPO DE DADOS (opcional) Ex.: ir,wv, etc #| #|------------------------------------------------------------------------------| #| DEPENDENCIAS #| #|------------------------------------------------------------------------------| #| HISTORICO #| 20060530 - Sergio Henrique - Versao original sub run { #{ configuracoes do sistema operacional # # barra de separacao (windows: b$="\\" ) (linux: b$="/") # opcao do mkdir (windows: $p=" ") (linux $="-p") my $b="/"; my $p="-p"; #} #---------------------------------------------------------------------------| # Prepara script e roda o script de conversao em csh | # Nome do script: run_conver_arc_at:data_da_execucao | # --------------------------------------------------------------------------| #{ Gerando nome do script my $self = shift; my $root=$self->{ROOT}; my $setout=$root."setout".$b; my $scr1;my $scrhora; my $scrdia; my $scrmes; my $scrano; ($scr1,$scrhora,$scrdia,$scrmes,$scrano)=(localtime)[1,2,3,4,5]; `mkdir $p $setout`; my $scriptname=$setout."run_conver_arc_at".$scrano.$scrmes.$scrdia.$scrhora.$scr1.".sh"; #} #{ Obtendo data da observacao no calendario gregoriano my ($seg,$minuto,$H,$D,$M,$Y,$SM,$J)=localtime($self->{OBSDATE}); $M=$M+1; $Y=$Y+1900; if ($D<10){$D="0".$D;} if ($M<10){$M="0".$M;} if ($H<10){$H="0".$H;} if ($J<10){$J="0".$J;} if ($J<100){$J="0".$J;} #} # Verificando se o nome dos arquivo de entrada possui a especificacao de hora # Caso tenha especificacao de hora, entao sera feita uma busca por todos os # horarios dentro da janela de tempo. # Para isto o passo-de-tempo sera de uma hora (step=1 hora) caso contrario # step=1 dia my $infile=$self->{INFILE}; # Obtendo nome dos arquivos de entrada e saida e cfile # substituindo as variaveis de ano,mes,dia e hora pelos seus # repectivos valores #{ my $cfile=$self->{CFILE}; $cfile=~s/\$Y/$Y/; $cfile=~s/\$M/$M/; $cfile=~s/\$D/$D/; $cfile=~s/\$H/$H/; $cfile=~s/\$J/$J/; my $outfile=$self->{OUTFILE}; $outfile=~s/\$Y/$Y/; $outfile=~s/\$M/$M/; $outfile=~s/\$D/$D/; $outfile=~s/\$H/$H/; $outfile=~s/\$J/$J/; #} #{ Criando diretorios se necessario my $selected=$self->{TMPDIR}.$Y.$M.$b.$D; my $dataout=$self->{DATAOUT}.$Y.$M.$b.$D.$b; `mkdir $p $selected`; `mkdir $p $self->{DATAIN}`; `mkdir $p $dataout`; $cfile=$selected.$b.$cfile; $outfile=$dataout.$outfile; print "infile=$infile\n"; print "cfile=$cfile\n"; print "outfile=$outfile\n"; #} #{ Obtendo lista de arquivos de entrada para janela de tempo da assimilacao print "Modo=$self->{MODO}\n"; if (index($self->{MODO},'normal')>0){ if (index($self->{SELETOR},"bufrtime")>0) { my $seletor1 = seletor_bufrtime->new; $seletor1->{CODES}=$self->{CODES}; $seletor1->{SUBTYPES}=$self->{SUBTYPES}; $seletor1->{DATAIN}=$self->{DATAIN}; $seletor1->{SELETOR}=$self->{SELETOR}; $seletor1->{INFILE}=$infile; $seletor1->{FLUXO}=$self->{FLUXO}; $seletor1->{OBSDATE}=$self->{OBSDATE}; $seletor1->{CFILE}=$cfile; $seletor1->{TMPDIR}=$self->{TMPDIR}; $seletor1->{TIMEWINDOW}=$self->{TIMEWINDOW}; $seletor1->run; } else { my $seletor1 = seletor_padrao->new; $seletor1->{CODES}=$self->{CODES}; $seletor1->{SUBTYPES}=$self->{SUBTYPES}; $seletor1->{DATAIN}=$self->{DATAIN}; $seletor1->{SELETOR}=$self->{SELETOR}; $seletor1->{INFILE}=$infile; $seletor1->{FLUXO}=$self->{FLUXO}; $seletor1->{OBSDATE}=$self->{OBSDATE}; $seletor1->{CFILE}=$cfile; $seletor1->{TMPDIR}=$self->{TMPDIR}; $seletor1->{TIMEWINDOW}=$self->{TIMEWINDOW}; $seletor1->run; } } #} #{ Rodando a conversao para ODS #------------------------------------------------------------------------------------------ # Aqui e feita a conversao do arquivo concatenado ($cfile) para o formato ODS # Devido a problemas visibulidade de alguns comandos tais como "UNLIMIT" e "SETENV" do # PERL para a linguagem nativa do sistema (CSH), ao inves de se rodar diretamente o # programa conversos, optou-se por gerar um script na linguagem nativa, que pos sua vez # roda o programas conversor, evitando-se assim problemas com UNLIMIT e SETENV # # Portanto temos 3 procedimentos # 1 - Ler arquivos $setparm que contem os paramentros UNLIMIT E SETENV (caso exista) # 2 - gerar o script usando o $setparm e as demais informacoes necessarias # 3 - Rodar o scripts #------------------------------------------------------------------------------------------ #{ Lendo $setparm e gerando script my $setparm=$self->{SETPARM}; open(UN,">$scriptname"); print UN "#!/bin/csh \n"; print UN "# \n"; print UN "#PBS -S /bin/csh \n"; print UN "#PBS -l cpunum_prc=1 \n"; print UN "#PBS -l tasknum_prc=1 \n"; print UN "#PBS -l memsz_job=1Gb \n"; print UN "#PBS -q $self->{FILA} \n"; print UN "#PBS -o turi-e:$scriptname.o \n"; print UN "#PBS -e turi-e:$scriptname.e \n"; print UN "#PBS -N $self->{NAME} \n"; if($setparm) { open(SC,"< ".$setparm ) or die "Can't open ".$setparm; my $line; while($line=) { print UN $line; } close(SC); } my $W=$self->{TIMEWINDOW}/60/60; print UN "set Y=".$Y."\n"; print UN "set M=".$M."\n"; print UN "set D=".$D."\n"; print UN "set H=".$H."\n"; print UN "set W=".$W."\n"; print UN "set IN=".$cfile."\n"; print UN "set CDL=".$outfile."\n"; print UN "set ODS=".$outfile.".ods\n"; print UN $self->{CONVERTER}."\n"; print UN $self->{NCGEN}."\n"; print UN "rm $outfile.cdl\n"; print UN "rm $outfile.dat\n"; close(UN); `chmod 755 $scriptname`; #} #{ Rodando script my $log; print "$self->{FILA}\n"; if ( index(" ".$self->{FILA},"none")>0 ){ print "Running $scriptname ... \n\n"; $log=(`$scriptname > $scriptname.stdout`); }else{ print "Submiting $scriptname \n at $self->{FILA}\n"; $log=(`qsub $scriptname`); } print "$log\n"; } # Fim do metodo run #|=============================================================================== #|Metodo obsdate | Atribui ou retorna data juliana da observacao| MCT-INPE-CPTEC| #|------------------------------------------------------------------------------| sub obsdate { my $self = shift; if (@_) { $self->{OBSDATE}=wsynoptic(@_[0]); my ($seg,$minuto,$hora,$dia,$mes,$ano)=localtime($self->{OBSDATE}); $mes=$mes+1; $ano=$ano+1900; print "Horario sinotico = ".$dia."/".$mes."/".$ano." ".$hora.":00\n"; } return $self->{OBSDATE}; } #|=============================================================================== #|Metodo TimeWindow | Define ou retorna a janela de tempo | MCT-INPE-CPTEC| #|------------------------------------------------------------------------------| #| Obs.: Internamente a janela de tempo TIMEWINDOW e representada em segundos #| Portanto, aqui e feita a transformacao de horas para segundos sub TimeWindow { my $self = shift; if (@_) { $self->{TIMEWINDOW}=@_[0]*60*60; } my $aux=$self->{TIMEWINDOW}/60/60; return $aux; } #|=============================================================================== #|Metodo FILA | Define a fila para submissao do processo | MCT-INPE-CPTEC| #|------------------------------------------------------------------------------| #| Obs.: Internamente a janela de tempo TIMEWINDOW e representada em segundos #| Portanto, aqui e feita a transformacao de horas para segundos sub fila { my $self = shift; if (@_) { $self->{FILA}=@_[0]; } return $self->{FILA}; } #|=============================================================================== #|Metodo Modo | Define o mode de execucao o | MCT-INPE-CPTEC| #|------------------------------------------------------------------------------| #| Obs.: Internamente a janela de tempo TIMEWINDOW e representada em segundos #| Portanto, aqui e feita a transformacao de horas para segundos sub modo { my $self = shift; if (@_) { $self->{MODO}=@_[0]; } return $self->{MODO}; }