#!@DASPERL ! +-======-+ ! Copyright (c) 2003-2018 United States Government as represented by ! the Admistrator of the National Aeronautics and Space Administration. ! All Rights Reserved. ! ! THIS OPEN SOURCE AGREEMENT ("AGREEMENT") DEFINES THE RIGHTS OF USE, ! REPRODUCTION, DISTRIBUTION, MODIFICATION AND REDISTRIBUTION OF CERTAIN ! COMPUTER SOFTWARE ORIGINALLY RELEASED BY THE UNITED STATES GOVERNMENT AS ! REPRESENTED BY THE GOVERNMENT AGENCY LISTED BELOW ("GOVERNMENT AGENCY"). ! THE UNITED STATES GOVERNMENT, AS REPRESENTED BY GOVERNMENT AGENCY, IS AN ! INTENDED THIRD-PARTY BENEFICIARY OF ALL SUBSEQUENT DISTRIBUTIONS OR ! REDISTRIBUTIONS OF THE SUBJECT SOFTWARE. ANYONE WHO USES, REPRODUCES, ! DISTRIBUTES, MODIFIES OR REDISTRIBUTES THE SUBJECT SOFTWARE, AS DEFINED ! HEREIN, OR ANY PART THEREOF, IS, BY THAT ACTION, ACCEPTING IN FULL THE ! RESPONSIBILITIES AND OBLIGATIONS CONTAINED IN THIS AGREEMENT. ! ! Government Agency: National Aeronautics and Space Administration ! Government Agency Original Software Designation: GSC-15354-1 ! Government Agency Original Software Title: GEOS-5 GCM Modeling Software ! User Registration Requested. Please Visit http://opensource.gsfc.nasa.gov ! Government Agency Point of Contact for Original Software: ! Dale Hithon, SRA Assistant, (301) 286-2691 ! ! +-======-+ # Simple perl script to convert HDF files to GRID. Uses lats4d. # # Revision history: # # 10feb2000 da Silva First crack. (in sh script) # 6/19/2000 Joon Yoon Completely Rewritten in Perl # 07May2001 da Silva Clean up. # use FindBin; # find location of the this script use lib "$FindBin::Bin"; # make perl libraries available use Env; # make env vars readily available use File::Basename; # for basename(), dirname() use File::Copy; # for copy() use Getopt::Long; # command line options use Time::Local; # time functions use Shell qw(cat rcp rsh scp ssh); # make C-shell commands available # command line options # -------------------- $rc = GetOptions("v", "d", "zrev" ); manpage() if ( $#ARGV < 0 || $ARGV[0] eq 'help' || !$rc ); $myname = basename ("$0"); init(); foreach $nextarg ( @ARGV ) { $doh = `file $nextarg`; @doh = split ":", $doh; $doh = @doh[$#doh]; if ($doh =~ /data/) { print "Looks like an HDF data file...\n"; coards2grib($nextarg); } else { print "Looks like an ascii text file...\n"; ieee2grib($nextarg); } } exit 0; # ----------------------------------------------------------------------- sub init { $fvroot = dirname($FindBin::Bin); $ncdump = "ncdump"; $grads = "gradshdf"; $lats4d = "$fvroot/lib/grads/lats4d.gs"; $log = "$myname" . ".$$" . ".log"; $args = $#ARGV + 1 ; $hybrid = ""; die ">>> ERROR <<< cannot find $lats4d" unless ( -e $lats4d ); $increment = 0; $time_steps = 0; } #.......................................................................... sub ieee2grib { # For each file on input # ---------------------- my ($temp) = @_; $basen = basename ("$temp"); $ctl = $basen; open (NONHDF, "$temp") || die (" can't open $temp file "); $first_line = ; close (NONHDF); $bin = ((split " ",$first_line)[1]); if ( $ctl =~ m/\.ctl/ ) { print "ctl is already attached at end \n"; } else { print "ctl has been attached at end \n"; $ctl .= ".ctl"; } $basen =~ s/\.ctl//g; $tempctl = $basen . ".ctl_temp"; $cdl = $basen . ".cdl"; $temp_num = $level_start = $level_ttl = $temp_count = 0; $firsttime = 1; # Do the actual grib conversion # ----------------------------- if ( $opt_d ) { print "bin = $bin \n"; print "basen = $basen \n"; print "ctl = $ctl \n"; print "log = $log \n"; print "HYBRID = $HYBRID \n"; } $cmd = "$grads -blc \'run $lats4d -q -v -i $ctl -o $basen -format ieee\'"; $rc = System ($cmd, $log); die ">>> ERROR <<< running GrADS" if ( $rc ); open (LOG, "$log") || die ("Couldn't open $log file"); @log_file = ; close (LOG); $SUCCESSFUL = 0; foreach $temp3 (@log_file) { if ($temp3 =~ /SUCCESS/ ) { $SUCCESSFUL = 1 }; } die ">>> ERROR <<< gribbing $hdf" if ( $SUCCESSFUL ); $levelfile = $ctl; open (LEVELFILE, "$levelfile") || die ("Can't open $levelfile file"); @level_file = ; close (LEVELFILE); foreach $temp_z (@level_file) { if (($temp_z =~ /levels =/) && $firsttime ) { $level_ttl = $temp_num; $firsttime=0; } elsif ($temp_z =~ /levels =/) { $level_start = $temp_num; } $temp_num++; } $levels = (); foreach $temp_z (@level_file){ if ($temp_count > $level_start) { $temp_z =~ s/\n//sg; $temp_z =~ s/\r//sg; $temp_z =~ s/^\n//sg; $levels = $levels . $temp_z; } $temp_count++; } $levels =~ s/}//sg; $levels =~ s/,//sg; $levels =~ s/;//sg; @levels_a = split (" ", $levels); $levels_r = ""; foreach $temp_z (@levels_a) { $levels_r = "$temp_z " . $levels_r; } $stat = rename $ctl,$tempctl; if ($stat == 0 ) { print "Error while renameing $ctl to $tempctl"; exit 2; } open (TEMPCTL, "$tempctl") || die("Can't open $tempctl file"); open (CTL, ">$ctl") || die ("Can't open $ctl file"); while () { $temp_buff = $_; if ($temp_buff =~ /levels/ ) { print CTL "$temp_buff"; print CTL "$levels_r\n"; } elsif ($temp_buff !~ /^\d/) { print CTL "$temp_buff"; } } close (CTL); close (TEMPCTL); print "$myname: completed successfully\n" if ( $opt_v); # Cleanup mess # ------------ unlink($tempctl); unlink($log); unlink(".grads.lats.table"); } #.......................................................................... sub coards2grib { my ($hdf) = @_; my $basen = basename ("$hdf"); $basen =~ s/\.nc4//g; my $hdf = $basen . ".nc4"; my $cdl = $basen . ".cdl"; my $ctl = $basen . ".ctl"; my $tempctl = $basen . ".ctl_temp"; # Create CDL # ---------- # -c includes coordinate variables as well $rc = system ("$ncdump -c $hdf > $cdl"); die ">>> ERRORR <<< running $ncdump" if ( $rc ); # Do the actual grib conversion # ----------------------------- if ( $opt_d ) { print "grads = $grads \n"; print "hdf = $hdf \n"; print "basen = $basen \n"; print "ctl = $ctl \n"; print "tempctl = $tempctl \n"; print "log = $log \n"; } $cmd = "$grads -blc \'run $lats4d -q -v -i $hdf -o $basen -format grads_grib\' "; $rc = System ("$cmd", "$log"); die ">>> ERROR <<< running $cmd" if ( $rc ); cat("$log" ) if ( $opt_v ); # Check grads error code # ---------------------- open (LOG, "$log") || die ("Couldn't open $log file"); @log_file = ; close (LOG); $SUCCESSFUL = 0; foreach $temp3 (@log_file) { #print "$temp3 \n"; if ($temp3 =~ /SUCCESS/ ) { $SUCCESSFUL = 1 }; } die ">>> ERROR <<< gribbing $hdf" unless ($SUCCESSFUL ); # Fix levels # ---------- open(CDL, "$cdl") || die ("Can't open $cdl file"); @cdl_file = ; close(CDL); $temp_num =0; $level_start = 0; $level_ttl = 0; $firsttime = 1; foreach $temp (@cdl_file) { if ( $firsttime ) { if ( ($temp =~ /lev =/) || ($temp =~ /levels =/) ) { @temp_num = split (" ", $temp); $level_ttl = @temp_num[2]; $firsttime=0; } } elsif (($temp =~ /lev =/) || ($temp =~ /levels =/ )) { $level_start = $temp_num; } $temp_num++; } $temp_count=0; $temp_count_mid = 0; $levels = (); foreach $temp_line (@cdl_file){ if ($temp_count >= $level_start) { @templine = split (" ", $temp_line); foreach $temp (@templine){ $temp =~ s/,//sg; if ($temp_count_mid < $level_ttl ) { if ($temp =~ /(\d+)/ ){ $temp_count_mid++; $temp =~ s/\n//sg; $temp =~ s/\r//sg; $temp =~ s/^\n//sg; $levels .= " $temp "; } } } } $temp_count++; } $levels =~ s/}//sg; $levels =~ s/,//sg; $levels =~ s/;//sg; @levels_a = split (" ", $levels); $levels_r = ""; foreach $temp (@levels_a) { if ( $opt_zrev ) { $levels_r = "$temp " . $levels_r; } else { $levels_r = $levels_r . " $temp" } } $stat = rename $ctl,$tempctl; if ($stat == 0 ) { die "Error while renaming $ctl to $tempctl"; } open (TEMPCTL, "$tempctl") || die("Can't open $tempctl file"); open (CTL, ">$ctl") || die ("Can't open $ctl file"); while () { $temp_buff = $_; if ( ($temp_buff =~ /levels/ ) || ($temp_buff =~ /lev/)) { print CTL "$temp_buff"; print CTL "$levels_r\n"; } elsif ($temp_buff !~ /^\d/) { print CTL "$temp_buff"; } } close (CTL); close (TEMPCTL); print "$myname: completed successfully\n" if ( $opt_v); # Cleanup mess # ------------ unlink($tempctl); unlink($log); unlink(".grads.lats.table"); } #...................................................................... # # System: This routine saves stdout/stderr, redirects it to a specified file, # runs a shell command using this new stdout/stderr, and finally # restores the original stdout/stderr. # sub System { my ( $cmd, $logfile ) = @_; print "$myname: $cmd\n" if ( $opt_v ); open SAVEOUT, ">&STDOUT"; # save stdout open SAVEERR, ">&STDERR"; # save stderr open STDOUT, ">>$logfile" or die "can't redirect stdout"; open STDERR, ">>$logfile" or die "can't redirect stderr"; select STDERR; $| = 1; # make it unbuffered select STDOUT; $| = 1; # make it unbuffered $rc = system ( $cmd ); # run the shell command close STDOUT; close STDERR; open STDOUT, ">&SAVEOUT" ; # restore stdout open STDERR, ">&SAVEERR" ; # restore stdout return $rc; } #-------------- sub manpage { print <