1 !*****************************************************************************!
4 ! Questions, comments, suggestions, even complaints should be directed to: !
10 ! Subroutine READ_NAMELIST !
11 ! Subroutine PARSE_TABLE !
12 ! Subroutine CLEAR_STORAGE !
13 ! Subroutine RD_GRIB !
14 ! Subroutine RD_GRIB2 !
15 ! Subroutine PUT_STORAGE !
17 ! Subroutine C_CLOSE !
20 ! Subroutine FILE_DELETE !
22 ! Kevin W. Manning, NCAR/MMM - original 'pregrid' code, 1998-2001 !
23 ! Jim Bresch, Michael Duda, Dave Gill, NCAR/MMM - adapted for WPS, 2006 !
25 !*****************************************************************************!
27 !*****************************************************************************!
29 ! This program reads GRIB-formatted data and puts it into intermediate format !
30 ! for passing data to a horizontal interpolation program. The intermediate !
31 ! format can be for WPS, SI, or MM5. !
33 ! The program tries to read from files called "GRIBFILE.AAA", "GRIBFILE.AAB", !
34 ! "GRIBFILE.AAC", ... "GRIBFILE.ABA", "GRIBFILE.ABB", ... "GRIBFILE.ZZZ" until!
35 ! it cannot find a file. This naming format allows for up to 17576 files, !
36 ! which should be enough for most applications. !
38 ! The program searches through those "GRIBFILE.???" files, and pulls out all !
39 ! the requested fields which fall between a starting date and an ending date. !
40 ! It writes the fields from a given time period to a file named according to !
41 ! the date and hour, i.e., "FILE:YYYY-MM-DD_HH" !
43 !*****************************************************************************!
52 use misc_definitions_module
58 subroutine read_namelist(hstart, hend, delta_time, ntimes,&
59 ordered_by_date, debug_level, out_format, prefix, &
60 add_lvls, new_plvl, interp_type, ec_rec_len, pmin)
62 use misc_definitions_module
64 character(len=19) :: hstart, hend
67 logical :: ordered_by_date
68 integer :: debug_level
69 character(len=3) :: out_format
70 character(len=MAX_FILENAME_LEN) :: prefix
72 real, dimension(:) :: new_plvl
73 integer :: interp_type, ec_rec_len
75 end subroutine read_namelist
78 integer :: nunit1 = 12
79 character(LEN=132) :: gribflnm = 'GRIBFILE.AAA ' ! won't work with len=12
81 integer :: debug_level
83 integer , parameter :: maxlvl = 250
85 real , dimension(maxlvl) :: plvl, new_plvl
88 integer :: interp_type, ec_rec_len
93 real :: startlat, startlon, deltalat, deltalon
95 character (LEN=9) :: field
96 character (LEN=3) :: out_format
97 character (LEN=MAX_FILENAME_LEN) :: prefix
101 integer, dimension(255) :: iuarr = 0
103 character (LEN=19) :: HSTART, HEND, HDATE
104 character(LEN=19) :: hsave = '0000-00-00_00:00:00'
109 logical :: ordered_by_date
110 integer :: grib_version
111 integer :: vtable_columns
114 call mprintf(.true.,STDOUT,' *** Starting program ungrib.exe *** ')
115 call mprintf(.true.,LOGFILE,' *** Starting program ungrib.exe *** ')
117 ! Read the namelist, and return the information we want:
119 call read_namelist(hstart, hend, interval, ntimes, &
120 ordered_by_date, debug_level, out_format, prefix, &
121 add_lvls, new_plvl, interp_type, ec_rec_len, pmin)
123 call mprintf(.true.,INFORM,"Interval value: %i seconds or %f hours", &
124 i1=interval, f1=float(interval)/3600.)
126 call mprintf(.true.,STDOUT,'Path to intermediate files is %s',s1=get_path(prefix))
127 call mprintf(.true.,LOGFILE,'Path to intermediate files is %s',s1=get_path(prefix))
130 ! Determine GRIB Edition number
132 ! NCAR/RDA's EC 113 data are grib1 with a non-standard record length
133 if ( ec_rec_len .eq. 0 ) then
134 call edition_num(nunit1, gribflnm, grib_version, ierr)
135 call mprintf((ierr.eq.3),ERROR,"GRIB file problem")
140 if (grib_version.eq.2) then
142 #if defined (USE_PNG) && (USE_JPEG2000)
143 call mprintf(.true.,INFORM, &
144 "Linked in png and jpeg libraries for Grib Edition 2")
146 call mprintf(.true.,STDOUT,"WARNING - Grib Edition 2 data detected, and")
147 call mprintf(.true.,STDOUT," - png and jpeg libs were NOT selected")
148 call mprintf(.true.,STDOUT," - during the build.")
149 call mprintf(.true.,STDOUT,"Stopping")
150 call mprintf(.true.,LOGFILE,"WARNING - Grib Edition 2 data detected, and")
151 call mprintf(.true.,LOGFILE," - png and jpeg libs were NOT selected")
152 call mprintf(.true.,LOGFILE," - during the build.")
153 call mprintf(.true.,LOGFILE,"Stopping")
154 call mprintf(.true.,ERROR,"NEED_GRIB2_LIBS")
159 call mprintf(.true.,INFORM,"Reading Grib Edition %i", i1=grib_version)
162 ! Read the "Vtable" file, and put the information contained therein into
163 ! the module "table".
165 call parse_table(debug_level,vtable_columns)
167 call mprintf(.true.,DEBUG,"Parsed the vtable.")
170 ! Initialize the input filename to GRIBFILE.AA{character just before A}
171 ! That way, when we update the filename below for the first time, it will
172 ! have the correct value of GRIBFILE.AAA.
174 gribflnm(12:12)=char(ichar(gribflnm(12:12))-1)
177 ! LOOP2 cycles through the list of files named GRIBFILE.???, until it finds
178 ! a non-existent file. Then we exit
182 ! At the beginning of LOOP2 update the input filename.
183 if (gribflnm(12:12).eq.'Z') then
184 if (gribflnm(11:11).eq.'Z') then
185 gribflnm(10:10) = char(ichar(gribflnm(10:10))+1)
186 gribflnm(11:11) = 'A'
188 gribflnm(11:11) = char(ichar(gribflnm(11:11))+1)
190 gribflnm(12:12) = 'A'
192 gribflnm(12:12) = char(ichar(gribflnm(12:12))+1)
195 ! Set READIT to .TRUE., meaning that we have not read any records yet
196 ! from the file GRIBFLNM.
198 call mprintf(.true.,DEBUG,"Reading from gribflnm %s ",s1=gribflnm)
200 readit = .TRUE. ! i.e., "Yes, we want to read a record."
203 ! LOOP1 reads through the file GRIBFLNM, exiting under two conditions:
204 ! 1) We have hit the end-of-file
205 ! 2) We have read past the ending date HEND.
207 ! Condition 2 assumes that the data in file GRIBFLNM are ordered in time.
210 ! At the beginning of LOOP1, we are at a new time period.
211 ! Clear the storage arrays and associated level information.
216 ! LOOP0 reads through the file GRIBFLNM, looking for data of the current
217 ! date. It exits under the following conditions.
218 ! 1) We have hit the end-of-file
219 ! 2) The GRIBFLNM variable has been updated to a nonexistent file.
220 ! 3) We start reading a new date and the data are assumed to be
222 ! 4) We have a valid record and the data are not assumed to be
227 ! If we need to read a new grib record, then read one.
230 if (grib_version.ne.2) then
231 call mprintf(.true.,DEBUG, &
232 "Calling rd_grib1 with iunit %i", i1=nunit1)
233 call mprintf(.true.,DEBUG, &
234 "flnm = %s",s1=gribflnm)
235 ! Read one record at a time from GRIB1 (and older Editions)
236 call rd_grib1(nunit1, gribflnm, level, field, &
237 hdate, ierr, iuarr, debug_level, ec_rec_len, pmin)
240 ! Read one file of records from GRIB2.
241 call mprintf(.true.,DEBUG,"Calling rd_grib2")
242 call rd_grib2(nunit1, gribflnm, hdate, &
243 grib_version, ierr, debug_level, pmin)
248 call mprintf(.true.,DEBUG,"ierr = %i ",i1=ierr)
250 ! We have hit the end of a file. Exit LOOP0 so we can
251 ! write output for date HDATE, and then exit LOOP1
252 ! to update the GRIBFLNM
258 ! We have hit the end of all the files. We can exit LOOP2
259 ! because there are no more files to read.
263 call mprintf(.true.,DEBUG, &
264 "Read a record %s with date %s", s1=field,s2=hdate(1:13))
268 call mprintf(.true.,DEBUG, &
269 "hdate = %s , hsave = %s ",s1=hdate(1:13), s2=hsave(1:13) )
271 ! if (hdate < hstart) then
272 ! ! The data read has a date HDATE earlier than the starting
273 ! ! date HSTART. So cycle LOOP0 to read the the next GRIB record.
278 if (FIELD.EQ.'NULL') then
279 ! The data read does not match any fields requested
280 ! in the Vtable. So cycle LOOP0 to read the next GRIB record.
285 if (ordered_by_date .and. (hdate > hsave)) then
287 ! Exit LOOP0, because we started to read data from another
290 call mprintf(.true.,DEBUG, &
291 "hdate %s > hsave %s so exit LOOP0",s1=hdate,s2=hsave)
293 ! We set READIT to FALSE because we have not yet processed
294 ! the data from this record, and we will want to process this
295 ! data on the next pass of LOOP1 (referring to the next time
296 ! period of interest.
304 ! When we have reached this point, we have a data array ARRAY which has
305 ! some data we want to save, with field name FIELD at pressure level
306 ! LEVEL (Pa). Dimensions of this data are map%nx and map%ny. Put
307 ! this data into storage.
309 if (((field == "SST").or.(field == "SKINTEMP")) .and. &
310 (level /= 200100.)) level = 200100.
312 call mprintf((.not.allocated(rdatarray)),ERROR, &
313 "GRIB data slab not allocated in ungrib.F before call to put_storage.")
314 call put_storage(iplvl,field, &
315 reshape(rdatarray(1:map%nx*map%ny),(/map%nx, map%ny/)),&
317 deallocate(rdatarray)
319 ! Since we processed the record we just read, we set
320 ! READIT to .TRUE. so that LOOP0 will read the next record.
323 if (.not. ordered_by_date) then
324 if (hdate >= hstart) then
332 ! When we have reached this point, we have either hit the end of file, or
333 ! hit the end of the current date. Either way, we want to output
334 ! the data found for this date. This current date is in HSAVE.
335 ! However, if (HSAVE == 0000-00-00_00:00:00), no output is necessary,
336 ! because that 0000 date is the flag for the very opening of a file.
338 if ((hsave(1:4).ne.'0000').and.(hsave.le.hend)) then
339 if (debug_level .gt. 100) then
340 print*, 'Calling output: '//hsave(1:13)
341 call mprintf(.true.,DEBUG,"Calling output: %s ",s1=hsave(1:13))
343 call output(hsave, nlvl, maxlvl, plvl, interval, 1, out_format, prefix, debug_level)
346 ! If the next record we process has a date later than HEND,
347 ! then time to exit LOOP1.
348 if ((ordered_by_date) .and. (hdate.gt.hend)) exit LOOP1
354 ! If we hit the end-of-file, its time to exit LOOP1 so we can
355 ! increment the GRIBFLNM to read the next file.
356 if (ierr.eq.1) exit LOOP1
360 ! When we have reached this point, we read all the data we want to from
361 ! file GRIBFLNM (either because we reached the end-of-file, or we
362 ! read past the date HEND). So we close the file and cycle LOOP2 to read
365 if (grib_version.ne.2) then
366 call c_close(iuarr(nunit1), debug_level, ierr)
369 hsave = '0000-00-00_00:00:00'
373 ! Now Reread, process, and reoutput.
375 call mprintf(.true.,INFORM,"First pass done, doing a reprocess")
377 call rrpr(hstart, ntimes, interval, nlvl, maxlvl, plvl, &
378 add_lvls, new_plvl, interp_type, &
379 debug_level, out_format, prefix)
381 ! Make sure the filedates are in order, with an inefficient sort:
385 ! Interpolate temporally to fill in missing times:
387 call datint(filedates, nfiles, hstart, ntimes, interval, out_format, prefix)
389 ! Now delete the temporary files:
391 call file_delete(filedates, nfiles, trim(get_path(prefix))//'PFILE:', interval)
393 ! And Now we are done:
395 call mprintf(.true.,STDOUT,'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
396 call mprintf(.true.,STDOUT,'! Successful completion of ungrib. !')
397 ! call mprintf(.true.,STDOUT,"! We're hauling gear at Bandimere. !")
398 call mprintf(.true.,STDOUT,'!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!')
400 call mprintf(.true.,LOGFILE,' *** Successful completion of program ungrib.exe *** ')
405 subroutine sort_filedates
412 do while ( .not. done)
415 if (filedates(n) > filedates(n+1)) then
416 filedates(size(filedates)) = filedates(n)
417 filedates(n) = filedates(n+1)
418 filedates(n+1) = filedates(size(filedates))
419 filedates(size(filedates)) = '0000-00-00 00:00:00.0000'
425 end subroutine sort_filedates