Advertisement
xFil

/usr/local/bin/get_gfs.pl

Dec 14th, 2024
32
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 10.30 KB | None | 0 0
  1. #!/usr/bin/perl -w
  2. # w. ebisuzaki CPC/NCEP/NWS/NOAA 10/2006
  3. #
  4. # simple script to download gfs files
  5. # inspired by Dan Swank's get-narr.pl script
  6. # this script uses the tecnique described in
  7. #     https://www.cpc.ncep.noaa.gov/products/wesley/fast_downloading_grib.html
  8. #
  9. # arguments:  action YYYYMMDDHH HR0 HR1 DHR VAR_LIST LEV_LIST DIRECTORY
  10. #
  11. #   action = inv  (display inventory of 1st file)
  12. #            data (get data)
  13. #
  14. #   HR0, HR1, DHR: forecast hour parameters
  15. #            do f_hour = HR0, HR1, DHR                                  (fortran)
  16. #            for (f_hour = HR1; f_hour <= HR1; f_hour = f_hour + DHR)   (C)
  17. #
  18. #   VAR_LIST:   list of variable separated by colons, blanks replaced by underscore
  19. #            ex.  HGT:TMP:OZONE
  20. #   LEV_LIST:   list of levesl separated by colons, blanks replaced by underscore
  21. #            ex.  500_mb:sfc
  22. #
  23. #   DIRECTORY:  name of the directory in which to place the files
  24. #
  25. # v1.0  10/2006  who is going to find the first bug?
  26. # v1.0a 10/2006  better help page
  27. # v2.0beta  10/2006  no need for egrep, get_inv.pl and get_grib.pl
  28. # v2.0beta2  10/2006  no need for egrep, get_inv.pl and get_grib.pl
  29. # v2.0beta3  10/2006  update messages, ignore case on matches
  30. # v2.0 1/2009 J.M. Berg: no need for OUTDIR for inventory
  31. # v2.0.1 1/2011 change URL to http://nomads.ncep.noaa.gov
  32. # v2.0.2 10/2012 set check for bad year to > 2030
  33. # v2.1 1/2015 NCO change gfs naming conventions: added $FHR3, updated URLs
  34. # v2.1.2 5/2017 quote left brace, required by new versions of perl
  35. # v2.1.3 12/2018 conversion to https
  36. # v2.1.4 12/2018 changed URLs to https
  37. # v2.1.5 6/2019 changed URLs, help page
  38. # v2.1.6 4/2021 changed URLs
  39. #
  40. #------------ user customization section -----------------------------------------
  41.  
  42. # location of curl
  43. $curl="curl";
  44. $inv='.idx';
  45. $grb='';
  46.  
  47. # the URLs of the inventory and grib must be defined by $URL$inv and $URL$grb
  48. # symbolic variables supported YYYY MM DD HH FHR (forecast hour), FHR3 (3 digit forecast hour)
  49. #
  50. # grib2 files from operational nomads server
  51. #
  52. # 1x1 degree GFS
  53. # $URL='https://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/gfs.$YYYY$MM$DD/$HH/atmos/gfs.t${HH}z.pgrb2.1p00.f${FHR3}';
  54. # 0.5x0.5 degree GFS
  55. # $URL='https://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/gfs.$YYYY$MM$DD/$HH/atmos/gfs.t${HH}z.pgrb2.0p50.f${FHR3}';
  56. # 0.25 x 0.25 degree GFS
  57. $URL='https://nomads.ncep.noaa.gov/pub/data/nccf/com/gfs/prod/gfs.$YYYY$MM$DD/$HH/atmos/gfs.t${HH}z.pgrb2.0p25.f${FHR3}';
  58. #$URL='https://noaa-gfs-bdp-pds.s3.amazonaws.com/gfs.$YYYY$MM$DD/$HH/atmos/gfs.t${HH}z.pgrb2.0p25.f${FHR3}';
  59.  
  60. #  if you want a 1/4 degree grid .. you should learn to use grib-filter
  61. #  grib-filter will give regional subset and save downloading time
  62. #  see  www.cpc.ncep.noaa.gov/products/wesley/scripting_grib_filter.html
  63. #
  64. # grib2 files from www.ftp.ncep.noaa.gov (not operational)
  65. # $URL='https://www.ftp.ncep.noaa.gov/data/nccf/com/gfs/prod/gfs.$YYYY$MM$DD/$HH/gfs.t${HH}z.pgrb2.1p00.f${FHR3}';
  66. #
  67.  
  68. # if insecure web server, $insecure='k';
  69. $insecure='';
  70. #$insecure='-k';
  71.  
  72. # the windows dos prompt often has problems with pipes, slower code code to avoid pipes
  73. # $windows='no';
  74. $windows='yes';
  75.  
  76.  
  77. #------------- guts of script ---------------------------------------------------
  78. $version="2.1.6";
  79. if ($#ARGV != 7) {
  80.   print "get_gfs.pl $version get GFS forecasts from nomads.ncep.noaa.gov\n";
  81.   print "\nget_gfs.pl action YYYYMMDDHH HR0 HR1 DHR VAR_LIST LEV_LIST DIRECTORY\n\n";
  82.   print "   action = inv  (display inventory of first data file)\n";
  83.   print "            data (get data)\n";
  84.   print "   YYYYMMDDHH: starting time of the forecast in UTC (Coordinated Universal Time)\n";
  85.   print "   HR0, HR1, DHR: forecast hour parameters\n";
  86.   print "      fortran: do f_hour = HR0, HR1, DHR\n";
  87.   print "      C: for (f_hour = HR0; f_hour <= HR1; f_hour += DHR)\n";
  88.   print "      enumerate forecast hours from HR0 to HR1 by increments fo DHR\n";
  89.   print "   VAR_LIST: list of variable separated by colons, blanks replaced by underscore or all\n";
  90.   print "      ex.  HGT:TMP:OZONE, all\n";
  91.   print "   LEV_LIST:   list of levels separated by colons, blanks replaced by underscore or all\n";
  92.   print "      ex.  500_mb:sfc, all\n";
  93.   print "      Note: APCP has both 0-M hour acc fcst and N-N hour acc fcst in the GFS,\n";
  94.   print "         to get the 0-N hour acc fcst, set LEV_LIST to '0-'\n";
  95.   print "   DIRECTORY:  name of the directory in which to place the output files\n";
  96.   print "   To see the available variables and levels in a particular file, display the inventory\n";
  97.   print "\n                   EXAMPLES\n\n Displaying an inventory\n\n";
  98.   print "       get_gfs.pl inv 2018123100 0 0 0 all all .\n\n";
  99.   print " Downloading 500 hPa Height and Temp 0/3/6 hours forecasts to current directory\n\n";
  100.   print "       get_gfs.pl data 2018123100 0 6 3 HGT:TMP 500_mb .\n\n";
  101.   print " Downloading APCP 6/18 hours forecasts to current directory\n\n";
  102.   print "       get_gfs.pl data 2018123000 6 18 6 APCP all .   *downloads 2 types of APCP\n";
  103.   print "       get_gfs.pl data 2018123000 6 18 6 APCP 0- .    *downloads 0-N hour APCP (1 or 2 time)\n\n";
  104.   print " Of course the date code will have to be current.\n";
  105.   print "\nDec 30, 2018: This script has the current https URLs for the 1.0, 0.5 and 0.25\n";
  106.   print " degree GFS forecasts. To change, to a different resolution GFS forecasts,\n";
  107.   print "select the desired \$URL definition.\n";
  108.   print "  This program can be used for other forecasts on nomads.ncep.noaa.gov by\n";
  109.   print "changing the URL in this perl script. This program uses the partial\n";
  110.   print "downloading techinque.\n";
  111.   print "   https://www.cpc.ncep.noaa.gov/products/wesley/fast_downloading_grib.html\n";
  112.   print "\nTo get user-defined regional subsets of the GFS forecast from the\n";
  113.   print "nomads.ncep.noaa.gov server, use the grib_filter facility. \n";
  114.   print "This is more useful for high-resolution grids.\n";
  115.   exit(8);
  116. }
  117.  
  118. $action = $ARGV[0];
  119. $time = $ARGV[1];
  120. $hr0=$ARGV[2];
  121. $hr1=$ARGV[3];
  122. $dhr=$ARGV[4];
  123. $VARS=$ARGV[5];
  124. $LEVS=$ARGV[6];
  125. $OUTDIR = $ARGV[7];
  126.  
  127. $YYYY = substr($time,0,4);
  128. $MM = substr($time,4,2);
  129. $DD = substr($time,6,2);
  130. $HH = substr($time,8,2);
  131.  
  132. # check values
  133.  
  134. if ($action ne 'data' && $action ne 'inv') {
  135.    print "action must be inv or data, not $action\n";
  136.    exit(8);
  137. }
  138.  
  139. if ($YYYY < 2006 || $YYYY > 2040) {
  140.    print "bad date (year) code $time\n";
  141.    exit(8);
  142. }
  143. if ($MM < 1 || $MM > 12) {
  144.    print "bad date (month) code $time\n";
  145.    exit(8);
  146. }
  147. if ($DD < 1 || $DD > 31) {
  148.    print "bad date (day) code $time\n";
  149.    exit(8);
  150. }
  151. if ($HH < 0 || $HH > 23) {
  152.    print "bad date (hour) code $time\n";
  153.    exit(8);
  154. }
  155. if ($hr0 == $hr1) {
  156.    $dhr = 3;
  157. }
  158.  
  159. if ($dhr != 3 && $dhr != 6 && $dhr != 12 && $dhr != 24) {
  160.    print "dhr must be 3, 6, 12 or 24, not $dhr\n";
  161.    exit(8);
  162. }
  163.  
  164. if ($hr0 > $hr1) {
  165.    print "hr0 needs to be <= hr1\n";
  166.    exit(8);
  167. }
  168. if ($dhr <= 0) {
  169.    print "dhr needs to be > 0\n";
  170.    exit(8);
  171. }
  172. if (! -d $OUTDIR && $action ne 'inv') {
  173.    print "Directory $OUTDIR does not exist\n";
  174.    exit(8);
  175. }
  176.  
  177. $VARS =~ tr/:_/| /;
  178. if( $VARS =~ m/ALL/ig ) { $VARS = "."; }
  179. else { $VARS = ":($VARS):"; }
  180.  
  181. $LEVS =~ tr/:_/| /;
  182. if( $LEVS =~ m/ALL/ig ) { $LEVS = "."; }
  183. else { $LEVS = ":($LEVS)" ; }
  184.  
  185. $URL =~ s/\$YYYY/$YYYY/g;
  186. $URL =~ s/\$\{YYYY\}/$YYYY/g;
  187. $URL =~ s/\$MM/$MM/g;
  188. $URL =~ s/\$\{MM\}/$MM/g;
  189. $URL =~ s/\$DD/$DD/g;
  190. $URL =~ s/\$\{DD\}/$DD/g;
  191. $URL =~ s/\$HH/$HH/g;
  192. $URL =~ s/\$\{HH\}/$HH/g;
  193.  
  194. $output = '';
  195.  
  196. $fhr=$hr0;
  197. while ($fhr <= $hr1) {
  198.    if ($fhr <= 9) { $fhr="0$fhr"; }
  199.    $fhr3=$fhr;
  200.    if ($fhr <= 99) { $fhr3="0$fhr"; }
  201.    $url = $URL;
  202.    $url =~ s/\$FHR3/$fhr3/g;
  203.    $url =~ s/\$\{FHR3\}/$fhr3/g;
  204.    $url =~ s/\$FHR/$fhr/g;
  205.    $url =~ s/\$\{FHR\}/$fhr/g;
  206.    $file = $url;
  207.    $file =~ s/^.*\///;
  208.  
  209.    #
  210.    # read the inventory
  211.    #    $line[] = wgrib inventory,  $start[] = start of record (column two of $line[])
  212.    #
  213.  
  214.    if ($windows eq 'yes') {
  215.       $err = system("$curl $insecure -f -s $url$inv -o $OUTDIR/$file.tmp");
  216.       $err = $err >> 8;
  217.       if ($err) {
  218.          print STDERR "error code=$err,  problem reading $url$inv\n";
  219.          sleep(10);
  220.          exit(8);
  221.       }
  222.       open (In, "$OUTDIR/$file.tmp");
  223.    }
  224.    else {
  225.       open (In, "$curl $insecure -f -s $url$inv |");
  226.    }
  227.  
  228.    $n=0;
  229.    while (<In>) {
  230.       chomp;
  231.       $line[$n] = $_;
  232.       s/^[^:]*://;
  233.       s/:.*//;
  234.       $start[$n] = $_;
  235.       $n++;
  236.    }
  237.    close(In);
  238.    if ($n == 0) {
  239.        print STDERR "Problem reading file $url$inv\n";
  240.        sleep(10);
  241.        exit(8);
  242.    }
  243.  
  244.    #
  245.    # find end of record: $last[]
  246.    #
  247.  
  248.    $lastnum = $start[$n-1];
  249.    for ($i = 0; $i < $n; $i++) {
  250.       $num = $start[$i];
  251.       if ($num < $lastnum) {
  252.          $j = $i + 1;
  253.          while ($start[$j] == $num) { $j++; }
  254.          $last[$i] = $start[$j] - 1;
  255.       }
  256.       else {
  257.          $last[$i] = '';
  258.       }
  259.    }
  260.  
  261.    if ($action eq 'inv') {
  262.       for ($i = 0; $i < $n; $i++) {
  263.          print "$line[$i]:range=$start[$i]-$last[$i]\n";
  264.       }
  265.       exit(0);
  266.    }
  267.  
  268.    #
  269.    # make the range field for Curl
  270.    #
  271.  
  272.    $range = '';
  273.    $lastfrom = '';
  274.    $lastto = '-100';
  275.    for ($i = 0; $i < $n; $i++) {
  276.       $_ = $line[$i];
  277.       if (/$LEVS/i && /$VARS/i) {
  278.          $from=$start[$i];
  279.          $to=$last[$i];
  280.  
  281.          if ($lastto + 1 == $from) {
  282.             $lastto = $to;
  283.          }
  284.          elsif ($lastto ne $to) {
  285.             if ($lastfrom ne '') {
  286.                if ($range eq '') { $range = "$lastfrom-$lastto"; }
  287.                else { $range = "$range,$lastfrom-$lastto"; }
  288.             }
  289.             $lastfrom = $from;
  290.             $lastto = $to;
  291.         }
  292.       }
  293.    }
  294.    if ($lastfrom ne '') {
  295.       if ($range eq '') { $range="$lastfrom-$lastto"; }
  296.       else { $range="$range,$lastfrom-$lastto"; }
  297.    }
  298.  
  299.    if ($range ne '') {
  300.       $err = system("$curl $insecure -f -v -s -r \"$range\" $url$grb -o $OUTDIR/$file.tmp");
  301.       $err = $err >> 8;
  302.       if ($err != 0) {
  303.          print STDERR "error in getting file $err $url$grb\n";
  304.          sleep(20);
  305.          exit $err;
  306.       }
  307.       rename "$OUTDIR/$file.tmp", "$OUTDIR/gfs";
  308.       $output = "$output $OUTDIR/$file";
  309.    }
  310.    else {
  311.       print "no matches (no download) for $file\n";
  312.    }
  313.    $fhr += $dhr;
  314. }
  315. print "\n\nfinished download\n\n$output\n";
  316. exit(0);
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement