File: C:\NOAA\NEMS_11731\src\chem\gocart\src\GMAO_Shared\GMAO_gfio\gfio.f
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105 subroutine GFIO_Create ( fname, title, source, contact, amiss,
106 & im, jm, km, lon, lat, levs, levunits,
107 & yyyymmdd_beg, hhmmss_beg, timinc,
108 & nvars, vname, vtitle, vunits, kmvar,
109 & valid_range, packing_range, prec,
110 & fid, rc )
111
112
113
114 Implicit NONE
115 include "netcdf.inc"
116 include "gfio.h"
117
118
119
120
121 character*(*) fname
122 character*(*) title
123 character*(*) source
124 character*(*) contact
125
126 real amiss
127
128
129 integer im
130 integer jm
131 integer km
132
133 real lon(im)
134
135
136 real lat(jm)
137
138 real levs(km)
139
140 character*(*) levunits
141
142 integer yyyymmdd_beg
143 integer hhmmss_beg
144 integer timinc
145
146
147 integer nvars
148 character*(*) vname(nvars)
149 integer vmode
150 character*(*) vtitle(nvars)
151
152 character*(*) vunits(nvars)
153 integer kmvar(nvars)
154
155
156 real valid_range(2,nvars)
157
158
159
160
161
162 real packing_range(2,nvars)
163
164
165
166
167
168
169
170
171 integer prec
172
173
174
175
176
177
178
179
180
181
182
183 integer fid
184 integer rc
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225 real*4 amiss_32
226 real*4 lon_32(im), lat_32(jm), levs_32(km)
227 real*8 lon_64(im), lat_64(jm), levs_64(km)
228 real*4 scale_32, offset_32
229 real*4 high_32,low_32
230 integer vid(nvars)
231 integer i, j
232 integer timeid, latid, lonid, levid
233 integer timedim, latdim, londim, levdim
234 integer dims3D(4), dims2D(3)
235 integer corner(4), edges(4)
236 character*80 timeUnits
237 logical surfaceOnly
238 character*8 strBuf
239 character*14 dateString
240 integer year,mon,day,hour,min,sec
241 integer err
242
243
244
245 integer*2 amiss_16
246 real*4 pRange_32(2,nvars),vRange_32(2,nvars)
247 logical packflag
248
249
250
251
252 character (len=50) :: lonName = "longitude"
253 character (len=50) :: lonUnits = "degrees_east"
254 character (len=50) :: latName = "latitude"
255 character (len=50) :: latUnits = "degrees_north"
256 character (len=50) :: levName = "vertical level"
257
258 character (len=50) :: timeName = "time"
259
260 character (len=50) :: conventions = "COARDS"
261 character (len=50) :: history = "File written by GFIO v1.0.8"
262
263 amiss_16 = PACK_FILL
264
265
266
267
268 = .TRUE.
269
270
271
272 if (timinc .eq. 0) then
273 rc=-1
274 return
275 endif
276
277
278
279 do i=1,nvars
280 if (kmvar(i) .NE. 0) then
281 surfaceOnly = .FALSE.
282 exit
283 endif
284 enddo
285
286
287
288 do i=1,im
289 lon_64(i) = lon(i)
290 enddo
291 do i=1,jm
292 lat_64(i) = lat(i)
293 enddo
294 do i=1,km
295 levs_64(i) = levs(i)
296 enddo
297 do j=1,nvars
298 do i=1,2
299 vRange_32(i,j) = valid_range(i,j)
300 pRange_32(i,j) = packing_range(i,j)
301 enddo
302 enddo
303
304 amiss_32 = amiss
305
306
307
308 call ncpopt(NCVERBOS)
309
310
311
312 #if defined(HAS_NETCDF4)
313 rc = nf_create (fname, IOR(NF_CLOBBER,NF_NETCDF4), fid)
314 #else
315 fid = nccre (fname, NCCLOB, rc)
316 #endif
317 if (err("Create: can't create file",rc,-30) .LT. 0) return
318
319
320
321 = ncddef (fid, 'lon', im, rc)
322 if (err("Create: error defining lon",rc,-31) .LT. 0) return
323 latdim = ncddef (fid, 'lat', jm, rc)
324 if (err("Create: error defining lat",rc,-31) .LT. 0) return
325 if (.NOT. surfaceOnly) then
326 levdim = ncddef (fid, 'lev', km, rc)
327 if (err("Create: error defining lev",rc,-31) .LT. 0) return
328 endif
329 timedim = ncddef(fid, 'time', NCUNLIM, rc)
330 if (err("Create: error defining time",rc,-31) .LT. 0) return
331
332
333
334 = ncvdef (fid, 'lon', NCDOUBLE, 1, londim, rc)
335 if (err("Create: error creating lon",rc,-32) .LT. 0) return
336 latid = ncvdef (fid, 'lat', NCDOUBLE, 1, latdim, rc)
337 if (err("Create: error creating lat",rc,-32) .LT. 0) return
338 if (.NOT. surfaceOnly) then
339 levid = ncvdef (fid, 'lev', NCDOUBLE, 1, levdim, rc)
340 if (err("Create: error creating lev",rc,-32) .LT. 0) return
341 endif
342 timeid = ncvdef (fid, 'time', NCLONG, 1, timedim, rc)
343 if (err("Create: error creating time",rc,-32) .LT. 0) return
344
345
346
347 call ncaptc (fid,lonid,'long_name',NCCHAR,LEN_TRIM(lonName),
348 . lonName,rc)
349 if (err("Create: error creating lon attribute",rc,-33) .LT. 0)
350 . return
351 call ncaptc (fid,lonid,'units',NCCHAR,LEN_TRIM(lonUnits),
352 . lonUnits,rc)
353 if (err("Create: error creating lon attribute",rc,-33) .LT. 0)
354 . return
355
356 call ncaptc (fid,latid,'long_name',NCCHAR,LEN_TRIM(latName),
357 . latName,rc)
358 if (err("Create: error creating lat attribute",rc,-33) .LT. 0)
359 . return
360 call ncaptc (fid,latid,'units',NCCHAR,LEN_TRIM(latUnits),
361 . latUnits,rc)
362 if (err("Create: error creating lat attribute",rc,-33) .LT. 0)
363 . return
364
365 if (.NOT. surfaceOnly) then
366 call ncaptc (fid,levid,'long_name',NCCHAR,LEN_TRIM(levName),
367 . levName,rc)
368 if (err("Create: error creating lev attribute",rc,-33) .LT. 0)
369 . return
370 call ncaptc (fid,levid,'units',NCCHAR,LEN_TRIM(levunits),
371 . levunits,rc)
372 if (err("Create: error creating lev attribute",rc,-33) .LT. 0)
373 . return
374 call ncaptc (fid,levid,'positive',NCCHAR,LEN_TRIM('down'),
375 . 'down',rc)
376 if (err("Create: error creating lev attribute",rc,-33) .LT. 0)
377 . return
378 endif
379
380 call ncaptc (fid, timeid, 'long_name', NCCHAR, LEN_TRIM(timeName),
381 . timeName, rc)
382 if (err("Create: error creating time attribute",rc,-33) .LT. 0)
383 . return
384
385
386
387
388
389
390 call GFIO_parseIntTime ( yyyymmdd_beg, year, mon, day )
391 call GFIO_parseIntTime ( hhmmss_beg, hour, min, sec )
392
393 write (timeUnits,202) year,mon,day,hour,min,sec
394 202 format ('minutes since ',I4.4,'-',I2.2,'-',I2.2,' ',I2.2,':',
395 . I2.2,':',I2.2)
396 call ncaptc (fid, timeid, 'units', NCCHAR, LEN_TRIM(timeUnits),
397 . timeUnits, rc)
398 if (err("Create: error creating time attribute",rc,-33) .LT. 0)
399 . return
400
401
402
403
404
405
406 call GFIO_parseIntTime ( timinc, hour, min, sec )
407
408 if ( sec .NE. 0) then
409 print *, 'GFIO_Create: Time increments not on minute',
410 . ' boundaries are not currently allowed.'
411 rc = -18
412 return
413 endif
414 call ncapt (fid, timeid, 'time_increment', NCLONG, 1, timInc, rc)
415 if (err("Create: error creating time attribute",rc,-33) .LT. 0)
416 . return
417 call ncapt (fid,timeid,'begin_date',NCLONG,1,yyyymmdd_beg,rc)
418 if (err("Create: error creating time attribute",rc,-33) .LT. 0)
419 . return
420 call ncapt (fid,timeid,'begin_time',NCLONG,1,hhmmss_beg,rc)
421 if (err("Create: error creating time attribute",rc,-33) .LT. 0)
422 . return
423
424 dims3D(4) = timedim
425 dims3D(3) = levdim
426 dims3D(2) = latdim
427 dims3D(1) = londim
428
429 dims2D(3) = timedim
430 dims2D(2) = latdim
431 dims2D(1) = londim
432
433 scale_32 = 1.0
434 = 0.0
435
436
437
438
439 do i=1,nvars
440 scale_32 = 1.0
441 = 0.0
442 if (pRange_32(1,i) .NE. amiss_32 .OR. pRange_32(2,i) .NE.
443 . amiss_32) then
444 if (pRange_32(1,i) .GT. pRange_32(2,i)) then
445 high_32 = pRange_32(1,i)
446 low_32 = pRange_32(2,i)
447 else
448 high_32 = pRange_32(2,i)
449 low_32 = pRange_32(1,i)
450 endif
451 scale_32 = (high_32 - low_32)/PACK_BITS*2
452 offset_32 = high_32 - scale_32*PACK_BITS
453 if (scale_32 .EQ. 0.0) then
454 = 1.0
455 = 0.0
456 packflag = .FALSE.
457 else
458 packflag = .TRUE.
459 endif
460 else
461 packflag = .FALSE.
462 endif
463 if ( kmvar(i) .eq. 0 ) then
464 if (packflag) then
465 vid(i) = ncvdef (fid, vname(i), NCSHORT, 3, dims2D, rc)
466 vmode=NCSHORT;
467 else if (prec .EQ. 1) then
468 vid(i) = ncvdef (fid, vname(i), NCDOUBLE, 3, dims2D, rc)
469 vmode=NCDOUBLE;
470 else
471 vid(i) = ncvdef (fid, vname(i), NCFLOAT, 3, dims2D, rc)
472 vmode=NCFLOAT;
473 endif
474 else
475 if (packflag) then
476 vid(i) = ncvdef (fid, vname(i), NCSHORT, 4, dims3D, rc)
477 vmode=NCSHORT;
478 else if (prec .EQ. 1) then
479 vid(i) = ncvdef (fid, vname(i), NCDOUBLE, 4, dims3D, rc)
480 vmode=NCDOUBLE;
481 else
482 vid(i) = ncvdef (fid, vname(i), NCFLOAT, 4, dims3D, rc)
483 vmode=NCFLOAT;
484 endif
485 endif
486 if (err("Create: error defining variable",rc,-34) .LT. 0)
487 . return
488
489 call ncaptc (fid, vid(i), 'long_name', NCCHAR,
490 . LEN_TRIM(vtitle(i)),vtitle(i), rc)
491 if (err("Create: error defining variable attribute",rc,-35)
492 . .LT. 0) return
493 call ncaptc (fid, vid(i), 'units', NCCHAR,
494 . LEN_TRIM(vunits(i)),vunits(i), rc)
495 if (err("Create: error defining variable attribute",rc,-35)
496 . .LT. 0) return
497
498 if (packflag) then
499 if (vmode .EQ. NCSHORT) then
500 call ncapt (fid,vid(i),'_FillValue',vmode,1,amiss_16,rc)
501 end if
502 if (vmode .EQ. NCFLOAT) then
503 call ncapt (fid,vid(i),'_FillValue',vmode,1,amiss_32,rc)
504 end if
505 if (vmode .EQ. NCDOUBLE) then
506 call ncapt (fid,vid(i),'_FillValue',vmode,1,amiss,rc)
507 end if
508 if (err("Create: error defining variable attribute",rc,-35)
509 . .LT. 0) return
510 if ( scale_32 .ne. 1.0 .or. offset_32 .ne. 0.0 ) then
511 call ncapt (fid,vid(i),'scale_factor',NCFLOAT,1,scale_32,rc)
512 if (err("Create: error defining variable attribute",rc,-35)
513 . .LT. 0) return
514 call ncapt (fid,vid(i),'add_offset',NCFLOAT,1,offset_32,rc)
515 if (err("Create: error defining variable attribute",rc,-35)
516 . .LT. 0) return
517 call ncapt (fid,vid(i),'packmin',NCFLOAT,1,low_32,rc)
518 if (err("Create: error defining variable attribute",rc,-35)
519 . .LT. 0) return
520 call ncapt (fid,vid(i),'packmax',NCFLOAT,1,high_32,rc)
521 if (err("Create: error defining variable attribute",rc,-35)
522 . .LT. 0) return
523 end if
524 call ncapt (fid,vid(i),'missing_value',NCSHORT,1,amiss_16,rc)
525 if (err("Create: error defining variable attribute",rc,-35)
526 . .LT. 0) return
527 call ncapt (fid,vid(i),'fmissing_value',NCFLOAT,1,amiss_32,rc)
528 if (err("Create: error defining variable attribute",rc,-35)
529 . .LT. 0) return
530 else
531 if (vmode .EQ. NCSHORT) then
532 call ncapt (fid,vid(i),'_FillValue',vmode,1,amiss_16,rc)
533 end if
534 if (vmode .EQ. NCFLOAT) then
535 call ncapt (fid,vid(i),'_FillValue',vmode,1,amiss_32,rc)
536 end if
537 if (vmode .EQ. NCDOUBLE) then
538 call ncapt (fid,vid(i),'_FillValue',vmode,1,amiss,rc)
539 end if
540 if (err("Create: error defining variable attribute",rc,-35)
541 . .LT. 0) return
542 if ( scale_32 .ne. 1.0 .or. offset_32 .ne. 0.0 ) then
543 call ncapt (fid,vid(i),'scale_factor',NCFLOAT,1,scale_32,rc)
544 if (err("Create: error defining variable attribute",rc,-35)
545 . .LT. 0) return
546 call ncapt (fid,vid(i),'add_offset',NCFLOAT,1,offset_32,rc)
547 if (err("Create: error defining variable attribute",rc,-35)
548 . .LT. 0) return
549 end if
550 call ncapt (fid,vid(i),'missing_value',NCFLOAT,1,amiss_32,rc)
551 if (err("Create: error defining variable attribute",rc,-35)
552 . .LT. 0) return
553 call ncapt (fid,vid(i),'fmissing_value',NCFLOAT,1,amiss_32,rc)
554 if (err("Create: error defining variable attribute",rc,-35)
555 . .LT. 0) return
556 endif
557
558 if (vRange_32(1,i) .NE. amiss_32 .OR. vRange_32(2,i) .NE.
559 . amiss_32) then
560 if (vRange_32(1,i) .GT. vRange_32(2,i)) then
561 high_32 = vRange_32(1,i)
562 low_32 = vRange_32(2,i)
563 else
564 high_32 = vRange_32(2,i)
565 low_32 = vRange_32(1,i)
566 endif
567 call ncapt (fid,vid(i),'vmin',NCFLOAT,1,low_32,rc)
568 if (err("Create: error defining variable attribute",rc,-35)
569 . .LT. 0) return
570 call ncapt (fid,vid(i),'vmax',NCFLOAT,1,high_32,rc)
571 if (err("Create: error defining variable attribute",rc,-35)
572 . .LT. 0) return
573 else
574 call ncapt (fid,vid(i),'vmin',NCFLOAT,1,amiss_32,rc)
575 if (err("Create: error defining variable attribute",rc,-35)
576 . .LT. 0) return
577 call ncapt (fid,vid(i),'vmax',NCFLOAT,1,amiss_32,rc)
578 if (err("Create: error defining variable attribute",rc,-35)
579 . .LT. 0) return
580
581 endif
582 enddo
583
584
585
586 call ncaptc (fid,NCGLOBAL,'Conventions',NCCHAR,
587 . LEN_TRIM(conventions),conventions,rc)
588 if (err("Create: error defining Conventions",rc,-36).LT. 0)
589 . return
590 call ncaptc (fid,NCGLOBAL,'Source',NCCHAR,LEN_TRIM(source),
591 . source,rc)
592 if (err("Create: error defining Source",rc,-36).LT. 0) return
593 call ncaptc (fid,NCGLOBAL,'Title',NCCHAR,LEN_TRIM(title),title,
594 . rc)
595 if (err("Create: error defining Title",rc,-36).LT. 0) return
596 call ncaptc (fid,NCGLOBAL,'Contact',NCCHAR,LEN_TRIM(contact),
597 . contact,rc)
598 if (err("Create: error defining Contact",rc,-36).LT. 0) return
599 call ncaptc (fid,NCGLOBAL,'History',NCCHAR,LEN_TRIM(history),
600 . history,rc)
601 if (err("Create: error defining History",rc,-36).LT. 0) return
602
603
604
605 call ncendf (fid, rc)
606 if (err("Create: error exiting define mode",rc,-37) .LT. 0)
607 . return
608
609
610
611 (1) = 1
612 edges(1) = im
613 call ncvpt (fid, lonid, corner, edges, lon_64, rc)
614 if (err("Create: error writing lons",rc,-38) .LT. 0) return
615
616 corner(1) = 1
617 edges(1) = jm
618 call ncvpt (fid, latid, corner, edges, lat_64, rc)
619 if (err("Create: error writing lats",rc,-38) .LT. 0) return
620
621 if (.NOT. surfaceOnly) then
622 corner(1) = 1
623 edges(1) = km
624 call ncvpt (fid, levid, corner, edges, levs_64, rc)
625 if (err("Create: error writing levs",rc,-38) .LT. 0) return
626 endif
627
628 corner(1) = 1
629 edges(1) = 1
630 call ncvpt (fid, timeid, corner, edges, 0, rc)
631 if (err("Create: error writing times",rc,-38) .LT. 0) return
632
633 rc=0
634 return
635 end
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655 subroutine GFIO_Open ( fname, fmode, fid, rc )
656
657
658
659
660
661 Implicit NONE
662 include "netcdf.inc"
663 include "gfio.h"
664
665
666
667
668
669 character*(*) fname
670 integer fmode
671
672
673
674
675
676
677
678 integer fid
679 integer rc
680
681
682
683
684
685
686
687
688
689
690 integer err
691
692 if ( fmode .EQ. 0) then
693 fid = ncopn(fname, NCRDWR, rc)
694 else
695 fid = ncopn(fname, NCNOWRIT, rc)
696 endif
697 if (fid .LT. 0) then
698 = fid
699 endif
700
701 if (err("Open: error opening file",rc,-39) .NE. 0) return
702
703 rc = 0
704 return
705 end
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724 subroutine GFIO_PutVar ( fid, vname, yyyymmdd, hhmmss,
725 & im, jm, kbeg, kount, grid,
726 & rc )
727
728
729
730 Implicit NONE
731 include "netcdf.inc"
732 include "gfio.h"
733
734
735
736 integer fid
737 character*(*) vname
738 integer yyyymmdd
739 integer hhmmss
740
741 integer im
742 integer jm
743 integer kbeg
744
745 integer kount
746 real grid(im,jm,kount)
747
748
749
750
751 integer rc
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796 integer timeid, dimSize, dimId, timeType
797 character*(MAXCHR) dimName
798 integer corner(4), edges(4)
799 integer vid
800 integer seconds, DiffDate, timeIndex
801 integer minutes
802 integer idx, i, j, k
803 integer begDate, begTime, timInc
804 integer err
805 character*8 strBuf
806 integer hour,min,sec,incSecs
807 integer, allocatable :: allTimes(:)
808 integer fillTime
809
810
811
812 real*4, allocatable :: grid_32(:,:,:)
813 real*8, allocatable :: grid_64(:,:,:)
814 real*4 dummy32
815 real*8 dummy64
816 real dummy
817
818
819
820 character*(MAXCHR) varName
821 integer type, nvDims, vdims(MAXVDIMS), nvAtts
822
823
824
825 integer*2, allocatable :: grid_16(:,:,:)
826 real*4, allocatable :: fminutes_32(:)
827 real*4 high_32, low_32, amiss_32
828 real*4 scale_32, offset_32
829 logical outRange
830 logical outPRange
831
832
833
834 = .FALSE.
835 outPRange = .FALSE.
836
837
838
839 call ncpopt(NCVERBOS)
840
841
842
843
844
845 if (MAXCHR .LT. MAXNCNAM) then
846 print *, 'GFIO_PutVar warning: MAXNCNAM is larger than ',
847 . 'dimName array size.'
848 endif
849
850
851
852 = ncvid (fid, vname, rc)
853 if (err("PutVar: variable not defined",rc,-40) .NE. 0) return
854
855
856 = ncdid (fid, 'lon', rc)
857 if (err("PutVar: can't get ID for lon",rc,-41) .NE. 0) return
858 call ncdinq (fid, dimId, dimName, dimSize, rc)
859 if (err("PutVar: can't get info for lon",rc,-41) .NE. 0) return
860 if (dimSize .ne. im) then
861 rc = -4
862 return
863 endif
864
865 dimId = ncdid (fid, 'lat', rc)
866 if (err("PutVar: can't get ID for lat",rc,-41) .NE. 0) return
867 call ncdinq (fid, dimId, dimName, dimSize, rc)
868 if (err("PutVar: can't get info for lat",rc,-41) .NE. 0) return
869 if (dimSize .ne. jm) then
870 rc = -5
871 return
872 endif
873
874 if (kbeg .NE. 0) then
875 dimId = ncdid (fid, 'lev', rc)
876 if (err("PutVar: can't get ID for lev",rc,-42) .NE. 0) return
877 call ncdinq (fid, dimId, dimName, dimSize, rc)
878 if (err("PutVar: can't get info for lev",rc,-42) .NE. 0) return
879 if (kbeg-1 + kount .gt. dimSize) then
880 rc = -3
881 return
882 endif
883 endif
884
885
886
887 = ncvid (fid, 'time', rc)
888 if (err("PutVar: time not defined",rc,-43) .NE. 0) return
889 call ncagt (fid, timeId, 'begin_date', begDate, rc)
890 if (err("PutVar: missing begin_date",rc,-44) .NE. 0) return
891 call ncagt (fid, timeId, 'begin_time', begTime, rc)
892 if (err("PutVar: missing begin_time",rc,-44) .NE. 0) return
893
894 seconds = DiffDate (begDate, begTime, yyyymmdd, hhmmss)
895
896 if (seconds .lt. 0) then
897 print *, 'GFIO_PutVar: Error code from diffdate. Problem with',
898 . ' date/time.'
899 rc = -7
900 return
901 endif
902 if ( MOD (seconds,60) .eq. 0 ) then
903 minutes = seconds / 60
904 else
905 print *, 'GFIO_PutVar: Currently, times must fall on minute ',
906 . 'boundaries.'
907 rc = -6
908 return
909 endif
910
911
912
913
914 call ncagt (fid, timeId, 'time_increment', timInc, rc)
915 if (err("PutVar: missing time increment",rc,-44) .NE. 0) return
916
917
918
919
920
921
922
923
924 call GFIO_parseIntTime ( timinc, hour, min, sec )
925
926 incSecs = hour*3600 + min*60 + sec
927
928 if ( MOD (seconds, incSecs) .ne. 0 ) then
929 print *, 'GFIO_putvar: Absolute time of ',seconds,' not ',
930 . 'possible with an interval of ',incSecs
931 rc = -2
932 return
933 else
934 timeIndex = seconds/incSecs + 1
935 endif
936
937
938
939 if ( kbeg .eq. 0 ) then
940 corner(1)=1
941 corner(2)=1
942 corner(3)=timeIndex
943 edges(1)=im
944 edges(2)=jm
945 edges(3)=1
946 else
947 corner(1)=1
948 corner(2)=1
949 corner(3)=kbeg
950 corner(4)=timeIndex
951 edges(1)=im
952 edges(2)=jm
953 edges(3)=kount
954 edges(4)=1
955 endif
956
957
958
959 call ncagt (fid, vid, 'vmin', low_32, rc)
960 if (err("PutVar: can't get vmin",rc,-53) .NE. 0) return
961 call ncagt (fid, vid, 'vmax', high_32, rc)
962 if (err("PutVar: can't get vmax",rc,-53) .NE. 0) return
963 call ncagt (fid, vid, 'fmissing_value', amiss_32, rc)
964 if (err("PutVar: can't get fmissing_value",rc,-53) .NE. 0) return
965 if (low_32 .NE. amiss_32 .OR. high_32 .NE. amiss_32) then
966 do k=1,kount
967 do j=1,jm
968 do i=1,im
969 if (grid(i,j,k) .GT. high_32 .OR. grid(i,j,k) .LT.
970 . low_32) then
971 outRange = .TRUE.
972 goto 100
973 endif
974 enddo
975 enddo
976 enddo
977 100 continue
978 endif
979
980
981
982 call ncvinq (fid, vid, varName, type, nvDims, vDims, nvAtts, rc)
983 if (err("PutVar: error in variable inquire",rc,-52) .NE. 0) return
984
985
986
987 if (HUGE(dummy) .EQ. HUGE(dummy32)) then
988 if (type .EQ. NCFLOAT) then
989 call ncvpt (fid, vid, corner, edges, grid, rc)
990 else if (type .EQ. NCDOUBLE) then
991 allocate (grid_64(im,jm,kount))
992 do k=1,kount
993 do j=1,jm
994 do i=1,im
995 grid_64(i,j,k) = grid(i,j,k)
996 enddo
997 enddo
998 enddo
999 call ncvpt (fid, vid, corner, edges, grid_64, rc)
1000 deallocate (grid_64)
1001 else if (type .EQ. NCSHORT) then
1002 call ncagt (fid, vid, 'packmax', high_32, rc)
1003 if (err("PutVar: error getting packmax",rc,-53) .NE. 0) return
1004 call ncagt (fid, vid, 'packmin', low_32, rc)
1005 if (err("PutVar: error getting packmin",rc,-53) .NE. 0) return
1006 call ncagt (fid, vid, 'scale_factor', scale_32, rc)
1007 if (err("PutVar: error getting scale",rc,-53) .NE. 0) return
1008 call ncagt (fid, vid, 'add_offset', offset_32, rc)
1009 if (err("PutVar: error getting offset",rc,-53) .NE. 0) return
1010 allocate (grid_16(im,jm,kount))
1011 do k=1,kount
1012 do j=1,jm
1013 do i=1,im
1014 if ( grid(i,j,k) .LT. low_32 .OR. grid(i,j,k) .GT.
1015 . high_32) then
1016 grid_16(i,j,k) = PACK_FILL
1017 outPRange = .TRUE.
1018 else
1019 grid_16(i,j,k) = (grid(i,j,k) - offset_32)/scale_32
1020 endif
1021 enddo
1022 enddo
1023 enddo
1024 call ncvpt (fid, vid, corner, edges, grid_16, rc)
1025 deallocate (grid_16)
1026 else
1027 rc = -13
1028 return
1029 endif
1030 else if (HUGE(dummy) .EQ. HUGE(dummy64)) then
1031 if (type .EQ. NCFLOAT) then
1032 allocate (grid_32(im,jm,kount))
1033 do k=1,kount
1034 do j=1,jm
1035 do i=1,im
1036 grid_32(i,j,k) = grid(i,j,k)
1037 enddo
1038 enddo
1039 enddo
1040 call ncvpt (fid, vid, corner, edges, grid_32, rc)
1041 deallocate (grid_32)
1042 else if (type .EQ. NCDOUBLE) then
1043 call ncvpt (fid, vid, corner, edges, grid, rc)
1044 else if (type .EQ. NCSHORT) then
1045 call ncagt (fid, vid, 'packmax', high_32, rc)
1046 if (err("PutVar: error getting packmax",rc,-53) .NE. 0) return
1047 call ncagt (fid, vid, 'packmin', low_32, rc)
1048 if (err("PutVar: error getting packmin",rc,-53) .NE. 0) return
1049 call ncagt (fid, vid, 'scale_factor', scale_32, rc)
1050 if (err("PutVar: error getting scale",rc,-53) .NE. 0) return
1051 call ncagt (fid, vid, 'add_offset', offset_32, rc)
1052 if (err("PutVar: error getting offset",rc,-53) .NE. 0) return
1053 allocate (grid_16(im,jm,kount))
1054 do k=1,kount
1055 do j=1,jm
1056 do i=1,im
1057 if ( grid(i,j,k) .LT. low_32 .OR. grid(i,j,k) .GT.
1058 . high_32) then
1059 grid_16(i,j,k) = PACK_FILL
1060 outPRange = .TRUE.
1061 else
1062 grid_16(i,j,k) = (grid(i,j,k) - offset_32)/scale_32
1063 endif
1064 enddo
1065 enddo
1066 enddo
1067 call ncvpt (fid, vid, corner, edges, grid_16, rc)
1068 deallocate (grid_16)
1069 else
1070 rc = -13
1071 return
1072 endif
1073 else
1074 rc = -12
1075 return
1076 endif
1077 if (err("PutVar: error writing variable",rc,-45) .NE. 0) return
1078
1079
1080
1081
1082 call ncdinq (fid, timeId, dimName, dimSize, rc)
1083 dimSize = dimSize - 1
1084
1085 allocate ( allTimes (MAX(timeIndex,dimSize)) )
1086 allocate ( fminutes_32 (MAX(timeIndex,dimSize)) )
1087 call ncvinq (fid,timeId,dimName,timeType,nvDims,vDims,nvAtts,rc)
1088
1089 if (dimSize .GT. 0) then
1090
1091
1092
1093 (1)=1
1094 edges(1)=dimSize
1095
1096 if (timeType .EQ. NCFLOAT) then
1097 call ncvgt (fid,timeId,corner,edges,fminutes_32,rc)
1098 do i=1,dimSize
1099 allTimes(i) = INT(fminutes_32(i))
1100 enddo
1101 else if (timeType .EQ. NCLONG) then
1102 call ncvgt (fid,timeId,corner,edges,allTimes,rc)
1103 endif
1104 if (err("PutVar: error reading times from file",rc,-46) .NE. 0)
1105 . return
1106 endif
1107
1108
1109
1110
1111
1112 do i=1,timeIndex-1
1113 fillTime = (i-1) * incSecs/60
1114 allTimes(i) = fillTime
1115 enddo
1116 allTimes(timeIndex) = minutes
1117
1118
1119
1120 (1)=1
1121 edges(1)=timeIndex
1122
1123 if (timeType .EQ. NCFLOAT) then
1124 do i=1,timeIndex
1125 fminutes_32(i) = INT(allTimes(i))
1126 enddo
1127 call ncvpt (fid,timeId,corner,edges,fminutes_32,rc)
1128 else if (timeType .EQ. NCLONG) then
1129 call ncvpt (fid,timeId,corner,edges,allTimes,rc)
1130 endif
1131 if (err("PutVar: error writing time",rc,-38) .NE. 0) return
1132
1133 if (outRange .AND. outPRange) then
1134 rc = -17
1135 else if (outPRange) then
1136 rc = -16
1137 else if (outRange) then
1138 rc = -15
1139 else
1140 rc = 0
1141 endif
1142
1143 deallocate ( allTimes )
1144 deallocate ( fminutes_32 )
1145
1146 return
1147 end
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169 subroutine GFIO_GetVarT ( fid, vname, yyyymmdd, hhmmss,
1170 & im, jm, kbeg, kount, grid, rc,
1171 & fid2)
1172
1173
1174
1175
1176
1177 integer fid
1178 integer fid3
1179 integer fid2
1180 character*(*) vname
1181 integer yyyymmdd
1182 integer hhmmss
1183 integer im
1184 integer jm
1185 integer kbeg
1186
1187 integer kount
1188
1189 logical cyclic
1190
1191
1192
1193 real grid(im,jm,kount)
1194 integer rc
1195
1196
1197
1198
1199
1200
1201
1202
1203 = .false.
1204 call GFIO_GetVarT1 ( fid, vname, yyyymmdd, hhmmss,
1205 & im, jm, kbeg, kount, grid, rc,
1206 & cyclic, fid2 )
1207 return
1208 end
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228 subroutine GFIO_GetVarT1 ( fid, vname, yyyymmdd, hhmmss,
1229 & im, jm, kbeg, kount, grid, rc,
1230 & cyclic,fid2 )
1231
1232
1233
1234 Implicit NONE
1235 include "netcdf.inc"
1236 include "gfio.h"
1237
1238
1239
1240 integer fid,fid2
1241 character*(*) vname
1242 integer yyyymmdd
1243 integer hhmmss
1244 integer im
1245 integer jm
1246 integer kbeg
1247
1248 integer kount
1249
1250 logical cyclic
1251
1252
1253
1254 real grid(im,jm,kount)
1255 integer rc
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269 integer begDate, begTime, incSecs, timeIndex1, timeIndex2
1270 integer secs, secs1, secs2, nymd1, nymd2, nhms1, nhms2
1271 integer err, diffdate, i, j, k
1272
1273 real grid2(im,jm,kount)
1274 real alpha, amiss, gfio_getmissing
1275
1276 logical tcyclic
1277
1278
1279
1280
1281 = cyclic
1282
1283 rc = 0
1284
1285
1286
1287 call GetBegDateTime ( fid, begDate, begTime, incSecs, rc )
1288 if (err("GetVar: could not determine begin_date/begin_time",rc,-44)
1289 & .NE. 0) return
1290
1291 secs = DiffDate (begDate, begTime, yyyymmdd, hhmmss)
1292
1293 if ( .not. tcyclic ) then
1294 if (yyyymmdd .LT. begDate .OR. (begDate .EQ. yyyymmdd .AND.
1295 . hhmmss .LT. begTime) .or. secs .LT. 0) then
1296 print *, 'GFIO_GetVar: Requested time earlier than first time.'
1297 rc = -7
1298 return
1299 endif
1300 end if
1301
1302
1303
1304 if ( secs >= 0 ) then
1305 timeIndex1 = secs/incSecs + 1
1306 else
1307 timeIndex1 = secs/incSecs
1308 end if
1309 timeIndex2 = timeIndex1 + 1
1310 secs1 = (timeIndex1-1) * incSecs
1311 secs2 = (timeIndex2-1) * incSecs
1312 call GetDate ( begDate, begTime, secs1, nymd1, nhms1, rc )
1313 call GetDate ( begDate, begTime, secs2, nymd2, nhms2, rc )
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325 call GFIO_GetVar1 ( fid, vname, nymd1, nhms1,
1326 & im, jm, kbeg, kount, grid, tcyclic, rc )
1327 if ( rc .ne. 0 ) return
1328
1329 if ( secs1 .eq. secs ) return
1330
1331
1332
1333
1334 call GFIO_GetVar1 ( fid, vname, nymd2, nhms2,
1335 & im, jm, kbeg, kount, grid2, tcyclic, rc)
1336 if ( rc .ne. 0 ) then
1337 if ( fid /= fid2 )
1338 & call GFIO_GetVar1 ( fid2, vname, nymd2, nhms2,
1339 & im, jm, kbeg, kount, grid2, tcyclic, rc )
1340
1341 if ( rc .ne. 0 ) return
1342 end if
1343
1344
1345
1346 = GFIO_GetMissing ( fid, rc )
1347 if ( rc .ne. 0 ) return
1348
1349
1350
1351 = float(secs - secs1)/float(secs2 - secs1)
1352
1353 do k = 1, kount
1354 do j = 1, jm
1355 do i = 1, im
1356 if ( grid(i,j,k) .ne. amiss .and. grid2(i,j,k) .ne. amiss ) then
1357 grid(i,j,k) = grid(i,j,k)
1358 & + alpha * (grid2(i,j,k) - grid(i,j,k))
1359 else
1360 grid(i,j,k) = amiss
1361 end if
1362 end do
1363 end do
1364 end do
1365
1366
1367
1368 = 0
1369
1370 return
1371 end
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389 subroutine GFIO_GetVar ( fid, vname, yyyymmdd, hhmmss,
1390 & im, jm, kbeg, kount, grid, rc)
1391
1392 Implicit NONE
1393
1394
1395
1396 integer fid
1397 character*(*) vname
1398 integer yyyymmdd
1399 integer hhmmss
1400 integer im
1401 integer jm
1402 integer kbeg
1403
1404 integer kount
1405 logical cyclic
1406 real grid(im,jm,kount)
1407 integer rc
1408
1409
1410
1411 = .false.
1412 call GFIO_GetVar1 ( fid, vname, yyyymmdd, hhmmss,
1413 & im, jm, kbeg, kount, grid,
1414 & cyclic,rc )
1415
1416 return
1417 end
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434 subroutine GFIO_GetVar1 ( fid, vname, yyyymmdd, hhmmss,
1435 & im, jm, kbeg, kount, grid,
1436 & cyclic,rc)
1437
1438
1439
1440 Implicit NONE
1441 include "netcdf.inc"
1442 include "gfio.h"
1443
1444
1445
1446 integer fid
1447 character*(*) vname
1448 integer yyyymmdd
1449 integer hhmmss
1450 integer im
1451 integer jm
1452 integer kbeg
1453
1454 integer kount
1455 logical cyclic
1456
1457
1458
1459
1460 real grid(im,jm,kount)
1461 integer rc
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503 integer timeId, begDate, begTime, seconds, minutes, timInc
1504 integer corner(4), edges(4), timeIndex, timeShift, lm
1505 integer vid
1506 integer DiffDate
1507 integer err
1508 integer i,j,k
1509 character*8 strBuf
1510 integer hour,min,sec,incSecs
1511
1512
1513
1514 character*(MAXCHR) dimName
1515 character*(MAXCHR) dimUnits
1516 character*(MAXCHR) varName
1517 integer dimSize, dimId
1518 integer nDims,nvars,ngatts
1519 integer varType, index, IdentifyDim
1520
1521
1522
1523 real*4, allocatable :: grid_32(:,:,:)
1524 real*8, allocatable :: grid_64(:,:,:)
1525 real*4 dummy32
1526 real*8 dummy64
1527 real dummy
1528
1529
1530
1531 integer type, nvDims, vdims(MAXVDIMS), nvAtts
1532
1533
1534
1535 integer*2, allocatable :: grid_16(:,:,:)
1536 integer*2 amiss_16
1537 real*4 amiss_32
1538 real*4 scale_32, offset_32
1539
1540 logical tcyclic
1541
1542
1543 call ncpopt(NCVERBOS)
1544
1545
1546
1547 = cyclic
1548
1549
1550
1551
1552
1553
1554
1555 if (MAXCHR .LT. MAXNCNAM) then
1556 print *, 'GFIO_GetVar warning: MAXNCNAM is larger than ',
1557 . 'dimName array size.'
1558 endif
1559
1560
1561
1562 call ncinq (fid, nDims, nvars, ngatts, dimId, rc)
1563 if (err("DimInqure: ncinq failed",rc,-48) .NE. 0)return
1564
1565
1566
1567
1568 do i=1,nvars
1569 call ncvinq (fid,i,varName,varType,nvDims,vDims,nvAtts,rc)
1570 if (err("GFIO_GetVar1: variable inquire error",rc,-52) .NE. 0)
1571 . return
1572 if (nvDims .EQ. 1) then
1573 nvars = nvars - 1
1574 dimId = ncdid (fid, varName, rc)
1575 if (err("GFIO_GetVar1: ncdid failed",rc,-41) .NE. 0) return
1576 call ncagtc (fid, i, 'units', dimUnits, MAXCHR, rc)
1577 if (err("DimInqure: could not get units for dimension",rc,-53)
1578 . .NE. 0) return
1579 call ncdinq (fid, dimId, dimName, dimSize, rc)
1580 if (err("DimInqure: can't get dim info",rc,-41) .NE. 0) return
1581 index = IdentifyDim (dimName, dimUnits)
1582 if ( index .EQ. 0 ) then
1583 if (dimSize .ne. im) then
1584 rc = -4
1585 im = dimSize
1586 return
1587 endif
1588 else if ( index .EQ. 1 ) then
1589 if (dimSize .ne. jm) then
1590 rc = -5
1591 jm = dimSize
1592 return
1593 endif
1594 else if ( index .EQ. 2 ) then
1595 if (kount .gt. dimSize) then
1596 rc = -3
1597 return
1598 endif
1599 else if ( index .EQ. 3 ) then
1600 timeId = dimId
1601 lm = dimSize
1602 else
1603 print *, 'GFIO_GetVar: Coordinate variable ',
1604 . TRIM(dimName),' with units of ',TRIM(dimUnits),
1605 . ' is not understood.'
1606 rc = -19
1607 return
1608 endif
1609 endif
1610 enddo
1611
1612
1613
1614 = ncvid (fid, vname, rc)
1615 if (err("GetVar: variable not defined",rc,-40) .NE. 0) return
1616
1617
1618
1619
1620
1621
1622
1623
1624 call GetBegDateTime ( fid, begDate, begTime, incSecs, rc )
1625 if (err("GetVar: could not determine begin_date/begin_time",rc,-44)
1626 & .NE. 0) return
1627
1628 seconds = DiffDate (begDate, begTime, yyyymmdd, hhmmss)
1629
1630
1631
1632
1633
1634
1635 if ( .not. tcyclic ) then
1636 if (seconds .LT. 0) then
1637 print *, 'GFIO_GetVar: Error code from diffdate. Problem with',
1638 . ' date/time.'
1639 rc = -7
1640 return
1641 endif
1642 if (yyyymmdd .LT. begDate .OR. (begDate .EQ. yyyymmdd .AND.
1643 . hhmmss .LT. begTime) ) then
1644 print *, 'GFIO_GetVar: Requested time earlier than first time.'
1645 rc = -7
1646 return
1647 endif
1648
1649 end if
1650
1651 if ( MOD (seconds,60) .eq. 0 ) then
1652 minutes = seconds / 60
1653 else
1654 print *, 'GFIO_GetVar: Currently, times must fall on minute ',
1655 . 'boundaries.'
1656 rc = -6
1657 return
1658 endif
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673 if ( MOD (seconds, incSecs) .ne. 0 ) then
1674 print *, 'GFIO_getvar: Absolute time of ',seconds,' not ',
1675 . 'possible with an interval of ',incSecs
1676 rc = -2
1677 return
1678 else
1679 timeIndex = seconds/incSecs + 1
1680 endif
1681
1682
1683
1684
1685
1686 if ( tcyclic ) then
1687 timeShift = mod ( timeIndex, lm )
1688 if ( timeShift > 0 ) then
1689 timeIndex = timeShift
1690 else
1691 timeIndex = lm + timeShift
1692 end if
1693 end if
1694
1695
1696
1697
1698
1699 if ( kbeg .eq. 0 ) then
1700 corner(1)=1
1701 corner(2)=1
1702 corner(3)=timeIndex
1703 edges(1)=im
1704 edges(2)=jm
1705 edges(3)=1
1706 else
1707 corner(1)=1
1708 corner(2)=1
1709 corner(3)=kbeg
1710 corner(4)=timeIndex
1711 edges(1)=im
1712 edges(2)=jm
1713 edges(3)=kount
1714 edges(4)=1
1715 endif
1716
1717
1718
1719 call ncvinq (fid, vid, varName, type, nvDims, vDims, nvAtts, rc)
1720 if (err("GetVar: error in variable inquire",rc,-52) .NE. 0) return
1721
1722
1723
1724 if (HUGE(dummy) .EQ. HUGE(dummy32)) then
1725 if (type .EQ. NCFLOAT) then
1726 call ncvgt (fid, vid, corner, edges, grid, rc)
1727 else if (type .EQ. NCDOUBLE) then
1728 allocate (grid_64(im,jm,kount))
1729 call ncvgt (fid, vid, corner, edges, grid_64, rc)
1730 do k=1,kount
1731 do j=1,jm
1732 do i=1,im
1733 grid(i,j,k) = grid_64(i,j,k)
1734 enddo
1735 enddo
1736 enddo
1737 deallocate (grid_64)
1738 else if (type .EQ. NCSHORT) then
1739 call ncagt (fid, vid, 'scale_factor', scale_32, rc)
1740 if (err("GetVar: error getting scale",rc,-53) .NE. 0) return
1741 call ncagt (fid, vid, 'add_offset', offset_32, rc)
1742 if (err("GetVar: error getting offset",rc,-53) .NE. 0) return
1743 call ncagt (fid, vid, 'missing_value', amiss_16, rc)
1744 if (err("GetVar: error getting offset",rc,-53) .NE. 0) return
1745 call ncagt (fid, vid, 'fmissing_value', amiss_32, rc)
1746 if (err("GetVar: error getting offset",rc,-53) .NE. 0) return
1747 allocate (grid_16(im,jm,kount))
1748 call ncvgt (fid, vid, corner, edges, grid_16, rc)
1749 do k=1,kount
1750 do j=1,jm
1751 do i=1,im
1752 if ( grid_16(i,j,k) .EQ. amiss_16 ) then
1753 grid(i,j,k) = amiss_32
1754 else
1755 grid(i,j,k) = scale_32*grid_16(i,j,k) + offset_32
1756 endif
1757 enddo
1758 enddo
1759 enddo
1760 deallocate (grid_16)
1761 else
1762 rc = -13
1763 return
1764 endif
1765 else if (HUGE(dummy) .EQ. HUGE(dummy64)) then
1766 if (type .EQ. NCFLOAT) then
1767 allocate (grid_32(im,jm,kount))
1768 call ncvgt (fid, vid, corner, edges, grid_32, rc)
1769 do k=1,kount
1770 do j=1,jm
1771 do i=1,im
1772 grid(i,j,k) = grid_32(i,j,k)
1773 enddo
1774 enddo
1775 enddo
1776 deallocate (grid_32)
1777 elseif (type .EQ. NCDOUBLE) then
1778 call ncvgt (fid, vid, corner, edges, grid, rc)
1779 else if (type .EQ. NCSHORT) then
1780 call ncagt (fid, vid, 'scale_factor', scale_32, rc)
1781 if (err("GetVar: error getting scale",rc,-53) .NE. 0) return
1782 call ncagt (fid, vid, 'add_offset', offset_32, rc)
1783 if (err("GetVar: error getting offset",rc,-53) .NE. 0) return
1784 call ncagt (fid, vid, 'missing_value', amiss_16, rc)
1785 if (err("GetVar: error getting offset",rc,-53) .NE. 0) return
1786 call ncagt (fid, vid, 'fmissing_value', amiss_32, rc)
1787 if (err("GetVar: error getting offset",rc,-53) .NE. 0) return
1788 allocate (grid_16(im,jm,kount))
1789 call ncvgt (fid, vid, corner, edges, grid_16, rc)
1790 do k=1,kount
1791 do j=1,jm
1792 do i=1,im
1793 if ( grid_16(i,j,k) .EQ. amiss_16 ) then
1794 grid(i,j,k) = amiss_32
1795 else
1796 grid(i,j,k) = scale_32*grid_16(i,j,k) + offset_32
1797 endif
1798 enddo
1799 enddo
1800 enddo
1801 deallocate (grid_16)
1802 else
1803 rc = -13
1804 return
1805 endif
1806 else
1807 rc = -12
1808 return
1809 endif
1810 if (err("GetVar: error reading variable",rc,-46) .NE. 0) return
1811
1812 rc = 0
1813 return
1814 end
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831 subroutine GFIO_DimInquire (fid,im,jm,km,lm,nvars,ngatts,rc)
1832
1833
1834
1835 Implicit NONE
1836 include "netcdf.inc"
1837 include "gfio.h"
1838
1839
1840
1841 integer fid
1842
1843
1844
1845 integer im
1846 integer jm
1847 integer km
1848
1849 integer lm
1850 integer nvars
1851 integer ngatts
1852 integer rc
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882 integer timeid, dimId, i
1883 integer attType, attLen
1884 character*(MAXCHR) dimName
1885 character*(MAXCHR) dimUnits
1886 character*(MAXCHR) vname
1887 integer dimSize
1888 integer nDims
1889 integer err
1890 logical surfaceOnly
1891 integer IdentifyDim, index
1892 integer varType, nvDims, vDims(MAXVDIMS), nvAtts
1893
1894
1895
1896 = .FALSE.
1897
1898
1899
1900 call ncpopt(NCVERBOS)
1901
1902
1903
1904
1905
1906
1907
1908 if (MAXCHR .LT. MAXNCNAM) then
1909 print *, 'GFIO_DimInquire warning: MAXNCNAM is larger than ',
1910 . 'dimName array size.'
1911 endif
1912
1913
1914
1915
1916 call ncinq (fid, nDims, nvars, ngatts, dimId, rc)
1917 if (err("DimInquire: ncinq failed",rc,-48) .NE. 0)return
1918
1919 if (nDims .EQ. 3) then
1920 surfaceOnly = .TRUE.
1921 endif
1922
1923
1924
1925
1926 do i=1,nvars
1927 call ncvinq (fid,i,vname,varType,nvDims,vDims,nvAtts,rc)
1928 if (err("DimInquire: variable inquire error",rc,-52) .NE. 0)
1929 . return
1930 if (nvDims .EQ. 1) then
1931 nvars = nvars - 1
1932 dimId = ncdid (fid, vname, rc)
1933 if (err("DimInquire: ncdid failed",rc,-41) .NE. 0) return
1934 call ncdinq (fid, dimId, dimName, dimSize, rc)
1935 if (err("DimInqure: can't get dim info",rc,-41) .NE. 0) return
1936
1937 call ncagtc (fid, i, 'units', dimUnits, MAXCHR, rc)
1938 if (err("DimInquire: could not get units for dimension",rc,-53)
1939 . .NE. 0) return
1940 index = IdentifyDim (dimName, dimUnits)
1941 if ( index .EQ. 0 ) then
1942 im = dimSize
1943 else if ( index .EQ. 1 ) then
1944 jm = dimSize
1945 else if ( index .EQ. 2 ) then
1946 km = dimSize
1947 else if ( index .EQ. 3 ) then
1948 lm = dimSize
1949 else
1950 print *, 'GFIO_DimInquire: Coordinate variable ',
1951 . TRIM(dimName),' with units of ',TRIM(dimUnits),
1952 . ' is not understood.'
1953 rc = -19
1954 return
1955 endif
1956 endif
1957 enddo
1958
1959 if (surfaceOnly) then
1960 km=0
1961 endif
1962
1963 rc=0
1964 return
1965 end
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982 subroutine GFIO_Inquire ( fid, im, jm, km, lm, nvars,
1983 & title, source, contact, amiss,
1984 & lon, lat, levs, levunits,
1985 & yyyymmdd, hhmmss, timinc,
1986 & vname, vtitle, vunits, kmvar,
1987 & valid_range , packing_range, rc)
1988
1989
1990
1991 Implicit NONE
1992 include "netcdf.inc"
1993 include "gfio.h"
1994
1995
1996
1997
1998
1999
2000 integer fid
2001
2002
2003
2004
2005 integer im
2006 integer jm
2007 integer km
2008 integer lm
2009
2010
2011
2012
2013
2014
2015 integer nvars
2016
2017
2018
2019
2020 character*(*) title
2021 character*(*) source
2022 character*(*) contact
2023 real amiss
2024
2025
2026 real lon(im)
2027
2028
2029 real lat(jm)
2030
2031 real levs(km)
2032
2033 character*(*) levunits
2034
2035 integer yyyymmdd(lm)
2036 integer hhmmss(lm)
2037 integer timinc
2038
2039
2040 character*(*) vname(nvars)
2041 character*(*) vtitle(nvars)
2042
2043 character*(*) vunits(nvars)
2044 integer kmvar(nvars)
2045
2046 real valid_range(2,nvars)
2047
2048
2049
2050 real packing_range(2,nvars)
2051
2052
2053
2054
2055
2056 integer rc
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103 integer vid(nvars)
2104 integer timeType, dimType
2105 integer timeId, latId, lonId, levId, dimId, incSecs, incTime, varId
2106 integer nDims, recdim, ngatts, seconds
2107 integer varType, nvDims, vDims(MAXVDIMS), nvAtts
2108 integer yyyymmdd_beg, hhmmss_beg, hour, min, sec
2109 integer start1D, minutes(lm)
2110 character*8 strBuf
2111 character*(MAXCHR) dimName
2112 character*(MAXCHR) dimUnits
2113 character*(MAXCHR) vnameTemp
2114 integer IdentifyDim, index
2115 integer dimSize
2116 integer i
2117 logical surfaceOnly
2118 logical noTimeInfo
2119 integer attType, attLen
2120 integer fV
2121 integer allVars
2122
2123
2124
2125 real*4 fminutes_32(lm)
2126 real*8 fminutes_64(lm)
2127 real*4 lon_32(im), lat_32(jm), levs_32(km)
2128 real*8 lon_64(im), lat_64(jm), levs_64(km)
2129 real*4 amiss_32
2130 real*4 pRange_32(2,nvars),vRange_32(2,nvars)
2131 integer err
2132 logical is_gfio
2133
2134
2135
2136 = 0
2137 surfaceOnly = .FALSE.
2138 noTimeInfo = .FALSE.
2139 is_gfio = .true.
2140
2141
2142
2143 call ncpopt(2)
2144
2145
2146
2147 if (LEN(vname(1)) .lt. MAXNCNAM) then
2148 print *,'GFIO_Inquire: length of vname array must be at least ',
2149 . MAXNCNAM,' bytes.'
2150 rc = -20
2151 return
2152 endif
2153
2154
2155
2156
2157
2158 if (MAXCHR .LT. MAXNCNAM) then
2159 print *, 'GFIO_Inquire warning: MAXNCNAM is larger than ',
2160 . 'dimName array size.'
2161 endif
2162
2163
2164
2165 call ncinq (fid,nDims,allVars,ngatts,recdim,rc)
2166 if (err("Inqure: ncinq failed",rc,-48) .NE. 0) return
2167
2168 if (nDims .EQ. 3) then
2169 surfaceOnly = .TRUE.
2170 endif
2171
2172
2173
2174 do i=1,allVars
2175 call ncvinq (fid,i,vnameTemp,varType,nvDims,vDims,nvAtts,rc)
2176 if (err("GFIO_Inquire: variable inquire error",rc,-52) .NE. 0)
2177 . return
2178 if (nvDims .EQ. 1) then
2179 dimId = ncdid (fid, vnameTemp, rc)
2180 if (err("Inquire: ncdid failed",rc,-40) .NE. 0) return
2181 call ncdinq (fid, dimId, dimName, dimSize, rc)
2182 if (err("Inqure: can't get dim info",rc,-41) .NE. 0) return
2183
2184 call ncagtc (fid, i, 'units', dimUnits, MAXCHR, rc)
2185 if (err("Inqure: could not get units for dimension",rc,-53)
2186 . .NE. 0) return
2187 index = IdentifyDim (dimName, dimUnits)
2188 if ( index .EQ. 0 ) then
2189 if (dimSize .ne. im) then
2190 rc = -4
2191 im = dimSize
2192 return
2193 else
2194 lonId = dimId
2195 lonId = i
2196 endif
2197 else if ( index .EQ. 1 ) then
2198 if (dimSize .ne. jm) then
2199 rc = -5
2200 jm = dimSize
2201 return
2202 else
2203 latId = dimId
2204 latId = i
2205 endif
2206 else if ( index .EQ. 2 ) then
2207 if (km .ne. dimSize) then
2208 rc = -3
2209 km = dimSize
2210 return
2211 else
2212 levId = dimId
2213 levId = i
2214 endif
2215 else if ( index .EQ. 3 ) then
2216 if (lm .ne. dimSize) then
2217 rc = -8
2218 lm = dimSize
2219 return
2220 else
2221 timeId = dimId
2222 timeId = i
2223 endif
2224 else
2225 print *, 'GFIO_Inquire: Coordinate variable ',
2226 . TRIM(dimName),' with units of ',TRIM(dimUnits),
2227 . ' is not understood.'
2228 rc = -19
2229 return
2230 endif
2231 endif
2232 enddo
2233
2234
2235 start1D=1
2236
2237
2238
2239
2240
2241
2242 call ncvinq (fid,lonId,dimName,dimType,nvDims,vDims,nvAtts,rc)
2243 if ( dimType .eq. NCFLOAT ) then
2244 call ncvgt (fid,lonId,start1D,im,lon_32,rc)
2245 if (err("Inquire: error reading 32-bit lons",rc,-49) .LT. 0) return
2246 do i=1,im
2247 lon(i)=lon_32(i)
2248 enddo
2249 else if ( dimType .eq. NCDOUBLE ) then
2250 is_gfio = .false.
2251 call ncvgt (fid,lonId,start1D,im,lon_64,rc)
2252 if (err("Inquire: error reading 64-bit lons",rc,-49) .LT. 0) return
2253 do i=1,im
2254 lon(i)=lon_64(i)
2255 enddo
2256 else
2257 if (err("Inquire: unsupported lon type",-1,-49) .LT. 0) return
2258 endif
2259
2260 call ncvinq (fid,latId,dimName,dimType,nvDims,vDims,nvAtts,rc)
2261 if ( dimType .eq. NCFLOAT ) then
2262 call ncvgt (fid,latId,start1D,jm,lat_32,rc)
2263 if (err("Inquire: error reading 32-bit lats",rc,-49) .LT. 0) return
2264 do i=1,jm
2265 lat(i)=lat_32(i)
2266 enddo
2267 else if ( dimType .eq. NCDOUBLE ) then
2268 call ncvgt (fid,latId,start1D,jm,lat_64,rc)
2269 if (err("Inquire: error reading 32-bit lats",rc,-49) .LT. 0) return
2270 do i=1,jm
2271 lat(i)=lat_64(i)
2272 enddo
2273 else
2274 if (err("Inquire: unsupported lat type",-1,-49) .LT. 0) return
2275 endif
2276
2277
2278 if (.NOT. surfaceOnly) then
2279 call ncvinq (fid,levId,dimName,dimType,nvDims,vDims,nvAtts,rc)
2280 if ( dimType .eq. NCFLOAT ) then
2281 call ncvgt (fid,levId,start1D,km,levs_32,rc)
2282 if (err("Inquire: error reading 32-bit levs",rc,-49) .LT. 0) return
2283 do i=1,km
2284 levs(i)=levs_32(i)
2285 enddo
2286 else if ( dimType .eq. NCDOUBLE ) then
2287 call ncvgt (fid,levId,start1D,km,levs_64,rc)
2288 if (err("Inquire: error reading 32-bit levs",rc,-49) .LT. 0) return
2289 do i=1,km
2290 levs(i)=levs_64(i)
2291 enddo
2292 else
2293 if (err("Inquire: unsupported lev type",-1,-49) .LT. 0) return
2294 endif
2295 end if
2296
2297
2298
2299
2300
2301 call ncvinq (fid,timeId,dimName,timeType,nvDims,vDims,nvAtts,rc)
2302 if (timeType .EQ. NCFLOAT) then
2303 call ncvgt (fid,timeId,start1D,lm,fminutes_32,rc)
2304 do i=1,lm
2305 minutes(i) = INT (fminutes_32(i))
2306 enddo
2307 else if (timeType .EQ. NCDOUBLE) then
2308 call ncvgt (fid,timeId,start1D,lm,fminutes_64,rc)
2309 do i=1,lm
2310 minutes(i) = INT (fminutes_64(i))
2311 enddo
2312 else if (timeType .EQ. NCLONG) then
2313 call ncvgt (fid,timeId,start1D,lm,minutes,rc)
2314 endif
2315 if (err("Inquire: error reading times",rc,-49) .LT. 0) return
2316
2317
2318
2319
2320 if (.NOT. surfaceOnly) then
2321 call ncagtc (fid,levid,'units',levunits,LEN(levunits),rc)
2322 if (err("Inquire: error reading lev units",rc,-50) .LT. 0)
2323 . return
2324 endif
2325
2326
2327 noTimeInfo = .FALSE.
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347 call GetBegDateTime ( fid, yyyymmdd_beg, hhmmss_beg, incSecs, rc )
2348 if ( rc .ne. 0 ) noTimeInfo = .TRUE.
2349
2350
2351
2352
2353
2354
2355
2356 if (.NOT. noTimeInfo) then
2357 if ( lm .ge. 1 ) then
2358 = incSecs/3600
2359 if (hour == 0) hour=1
2360 min = mod(incSecs,3600*hour)/60
2361
2362 = incSecs/3600*10000 + mod(incSecs,3600)/60*100 + mod(incSecs,60)
2363 end if
2364
2365
2366
2367
2368 do i=1,lm
2369
2370
2371
2372 = incSecs * (i-1)
2373 call GetDate (yyyymmdd_beg,hhmmss_beg, seconds,
2374 . yyyymmdd(i),hhmmss(i),rc)
2375 if (rc .LT. 0) then
2376 print *, "GFIO_Inquire: error in getdate"
2377 rc = -14
2378 return
2379 endif
2380
2381
2382 enddo
2383 else
2384 timInc = 000100
2385 endif
2386
2387
2388
2389 if ( is_gfio ) then
2390
2391 call ncagtc (fid,NCGLOBAL,'Title',title,LEN(title),rc)
2392 if (rc .NE. 0) then
2393 print *, 'GFIO_Inquire: Warning. Global attribute Title ',
2394 . 'not found.'
2395 endif
2396 call ncagtc (fid,NCGLOBAL,'Source',source,LEN(source),rc)
2397 if (rc .NE. 0) then
2398 print *, 'GFIO_Inquire: Warning. Global attribute Title ',
2399 . 'not found.'
2400 endif
2401 call ncagtc (fid,NCGLOBAL,'Contact',contact,LEN(contact),rc)
2402 if (rc .NE. 0) then
2403 print *, 'GFIO_Inquire: Warning. Global attribute Title ',
2404 . 'not found.'
2405 endif
2406
2407 else
2408
2409 Title = 'Unknown'
2410 Source = 'Unknown'
2411 Contact = 'Unknown'
2412
2413 end if
2414
2415
2416
2417
2418
2419 do i= 1, allVars
2420 call ncvinq (fid,i,vnameTemp,varType,nvDims,vDims,nvAtts,rc)
2421 if (err("Inquire: variable inquire error",rc,-52) .NE. 0) return
2422 if (nvDims .EQ. 1) then
2423 cycle
2424 else
2425 if ( is_gfio ) then
2426 call ncagt (fid, i,'fmissing_value',amiss_32,rc)
2427 else
2428 rc = -1
2429 end if
2430 if (rc .NE. 0) then
2431 call ncainq (fid, i, 'missing_value', attType, attLen, rc)
2432 if (rc.eq.0 .and. attType .EQ. NCFLOAT) then
2433 call ncagt (fid, allVars, 'missing_value', amiss_32, rc)
2434 if (rc .ne. 0) call ncagt (fid, 1, 'missing_value', amiss_32, rc)
2435 if (err("Inquire: error getting missing value",rc,-53)
2436 . .NE. 0) return
2437 else
2438 print *,
2439 . 'GFIO_Inquire: Cannot find missing value, assuming 1E+15'
2440 amiss_32 = 1.0E+15
2441 end if
2442 endif
2443 exit
2444 endif
2445 end do
2446 amiss = amiss_32
2447
2448
2449
2450 do i=1,allVars
2451 call ncvinq (fid,i,vnameTemp,varType,nvDims,vDims,nvAtts,rc)
2452 if (err("Inquire: variable inquire error",rc,-52) .NE. 0) return
2453 if (nvDims .EQ. 1) then
2454 cycle
2455 else
2456 fV = fV + 1
2457 vname(fV) = vnameTemp
2458 endif
2459 if (nvDims .EQ. 3) then
2460 kmvar(fV)=0
2461 else
2462 kmvar(fV)=km
2463 endif
2464 call ncagtc (fid,i,'long_name',vtitle(fV),LEN(vtitle(fV)), rc)
2465 if (err("Inquire: variable attribute error",rc,-53) .NE. 0)
2466 . return
2467 call ncagtc (fid,i,'units',vunits(fV),LEN(vunits(fV)),rc)
2468 if (err("Inquire: variable attribute error",rc,-53) .NE. 0)
2469 . return
2470
2471
2472
2473
2474 call ncagt (fid, i, 'packmin', pRange_32(1,fV), rc)
2475 if (rc .NE. 0) then
2476 packing_range(1,fV) = amiss
2477 else
2478 packing_range(1,fV) = pRange_32(1,fV)
2479 endif
2480 call ncagt (fid, i, 'packmax', pRange_32(2,fV), rc)
2481 if (rc .NE. 0) then
2482 packing_range(2,fV) = amiss
2483 else
2484 packing_range(2,fV) = pRange_32(2,fV)
2485 endif
2486 call ncagt (fid, i, 'vmin', vRange_32(1,fV), rc)
2487 if (rc .NE. 0) then
2488 valid_range(1,fV) = amiss
2489 else
2490 valid_range(1,fV) = vRange_32(1,fV)
2491 endif
2492 call ncagt (fid, i, 'vmax', vRange_32(2,fV), rc)
2493 if (rc .NE. 0) then
2494 valid_range(2,fV) = amiss
2495 else
2496 valid_range(2,fV) = vRange_32(2,fV)
2497 endif
2498
2499 enddo
2500
2501 if (fV .NE. nvars) then
2502 rc = -9
2503 nvars = fV
2504 return
2505 endif
2506
2507 rc=0
2508 call ncpopt(NCVERBOS)
2509
2510 return
2511 end
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524 subroutine GFIO_Close ( fid, rc )
2525
2526
2527
2528 Implicit NONE
2529 include "netcdf.inc"
2530 include "gfio.h"
2531
2532
2533
2534 integer fid
2535
2536
2537
2538 integer rc
2539
2540
2541
2542
2543
2544
2545
2546
2547
2548
2549
2550
2551
2552
2553
2554 integer i
2555 integer err
2556
2557
2558
2559 call ncpopt(NCVERBOS)
2560
2561 call ncclos (fid, rc)
2562 if (err("Close: error closing file",rc,-54) .NE. 0) return
2563
2564 rc = 0
2565 return
2566 end
2567
2568
2569
2570
2571
2572
2573
2574
2575
2576
2577
2578
2579
2580 subroutine GFIO_PutIntAtt ( fid, name, count, buf, prec, rc )
2581
2582
2583
2584 Implicit NONE
2585 include "netcdf.inc"
2586 include "gfio.h"
2587
2588
2589
2590 integer fid
2591 character*(*) name
2592 integer count
2593 integer buf(count)
2594 integer prec
2595
2596
2597
2598
2599
2600 integer rc
2601
2602
2603
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614
2615
2616
2617
2618
2619
2620 integer*4 dummy32
2621 integer*8 dummy64
2622 integer i
2623
2624 integer*4, allocatable :: buf32(:)
2625 integer*8, allocatable :: buf64(:)
2626 integer err
2627
2628 call ncredf ( fid, rc )
2629 if (err("PutIntAtt: could not enter define mode",rc,-55) .NE. 0)
2630 . return
2631
2632 if ( HUGE(dummy32) .EQ. HUGE(i) .AND. prec .EQ. 0 ) then
2633 call ncapt ( fid, NCGLOBAL, name, NCLONG, count, buf, rc )
2634
2635 else if ( HUGE(dummy32) .EQ. HUGE(i) .AND. prec .EQ. 1 ) then
2636 allocate ( buf64(count) )
2637 do i=1,count
2638 buf64(i) = buf(i)
2639 enddo
2640 call ncapt ( fid, NCGLOBAL, name, NCDOUBLE, count, buf64, rc )
2641 deallocate (buf64)
2642
2643 else if (HUGE(dummy64) .EQ. HUGE(i) .AND. prec .EQ. 0 ) then
2644 allocate ( buf32(count) )
2645 do i=1,count
2646 buf32(i) = buf(i)
2647 enddo
2648 call ncapt ( fid, NCGLOBAL, name, NCLONG, count, buf32, rc )
2649 deallocate (buf32)
2650
2651 else if (HUGE(dummy64) .EQ. HUGE(i) .AND. prec .EQ. 1 ) then
2652 call ncapt ( fid, NCGLOBAL, name, NCDOUBLE, count, buf, rc )
2653
2654 else
2655 rc = -12
2656 return
2657 endif
2658 if (err("PutIntAtt: error writing attribute",rc,-36) .NE. 0)
2659 . return
2660
2661 call ncendf ( fid, rc )
2662 if (err("PutIntAtt: could not exit define mode",rc,-56) .NE. 0)
2663 . return
2664
2665 rc = 0
2666 return
2667 end
2668
2669
2670
2671
2672
2673
2674
2675
2676
2677
2678
2679
2680
2681 subroutine GFIO_PutRealAtt ( fid, name, count, buf, prec, rc )
2682
2683
2684
2685 Implicit NONE
2686 include "netcdf.inc"
2687 include "gfio.h"
2688
2689
2690
2691 integer fid
2692 character*(*) name
2693 integer count
2694 real buf(count)
2695 integer prec
2696
2697
2698
2699
2700
2701 integer rc
2702
2703
2704
2705
2706
2707
2708
2709
2710
2711
2712
2713
2714
2715
2716
2717
2718
2719
2720
2721 real*4 dummy32
2722 real*8 dummy64
2723 real r
2724 integer i
2725 real*4, allocatable :: buf32(:)
2726 real*8, allocatable :: buf64(:)
2727 integer err
2728
2729 call ncredf ( fid, rc )
2730 if (err("PutRealAtt: could not enter define mode",rc,-55) .NE. 0)
2731 . return
2732
2733 if (HUGE(dummy32) .EQ. HUGE(r) .AND. prec .EQ. 0) then
2734 call ncapt ( fid, NCGLOBAL, name, NCFLOAT, count, buf, rc )
2735
2736 else if (HUGE(dummy32) .EQ. HUGE(r) .AND. prec .EQ. 1) then
2737 allocate (buf64(count))
2738 do i=1,count
2739 buf64(i) = buf(i)
2740 enddo
2741 call ncapt ( fid, NCGLOBAL, name, NCDOUBLE, count, buf64, rc )
2742 deallocate (buf64)
2743
2744 else if (HUGE(dummy64) .EQ. huge(r) .AND. prec .EQ. 0) then
2745 allocate (buf32(count))
2746 do i=1,count
2747 buf32(i) = buf(i)
2748 enddo
2749 call ncapt ( fid, NCGLOBAL, name, NCFLOAT, count, buf32, rc )
2750 deallocate (buf32)
2751
2752 else if (HUGE(dummy64) .EQ. huge(r) .AND. prec .EQ. 1) then
2753 call ncapt ( fid, NCGLOBAL, name, NCDOUBLE, count, buf, rc )
2754
2755 else
2756 rc = -12
2757 return
2758 endif
2759 if (err("PutRealAtt: error writing attribute",rc,-36) .NE. 0)
2760 . return
2761
2762 call ncendf ( fid, rc )
2763 if (err("PutRealAtt: could not exit define mode",rc,-56) .NE. 0)
2764 . return
2765
2766 rc = 0
2767 return
2768 end
2769
2770
2771
2772
2773
2774
2775
2776
2777
2778
2779
2780
2781
2782
2783 subroutine GFIO_PutCharAtt ( fid, name, count, buf, rc )
2784
2785
2786
2787 Implicit NONE
2788 include "netcdf.inc"
2789 include "gfio.h"
2790
2791
2792
2793 integer fid
2794 character*(*) name
2795 integer count
2796 character buf(count)
2797
2798
2799
2800 integer rc
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817 integer err
2818
2819 call ncredf ( fid, rc )
2820 if (err("PutCharAtt: could not enter define mode",rc,-55) .NE. 0)
2821 . return
2822 call ncaptc ( fid, NCGLOBAL, name, NCCHAR, count, buf, rc )
2823 if (err("PutCharAtt: error writing attribute",rc,-36) .NE. 0)
2824 . return
2825 call ncendf ( fid, rc )
2826 if (err("PutCharAtt: could not exit define mode",rc,-56) .NE. 0)
2827 . return
2828
2829 rc = 0
2830 return
2831 end
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843
2844
2845 subroutine GFIO_GetAttNames ( fid, ngatts, aname, rc )
2846
2847
2848
2849 Implicit NONE
2850 include "netcdf.inc"
2851 include "gfio.h"
2852
2853
2854
2855 integer fid
2856
2857
2858
2859 integer ngatts
2860
2861
2862
2863
2864 character*(*) aname(ngatts)
2865 integer rc
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877
2878
2879
2880
2881
2882
2883
2884 integer ngattsFile, i
2885 integer nDims,dimSize,recDim
2886 integer err
2887
2888
2889
2890 call ncpopt(NCVERBOS)
2891
2892
2893
2894 call ncinq (fid,nDims,dimSize,ngattsFile,recdim,rc)
2895 if (err("GetAttNames: ncinq failed",rc,-48) .NE. 0) return
2896 if (ngattsFile .NE. ngatts) then
2897 rc = -10
2898 ngatts = ngattsFile
2899 return
2900 endif
2901
2902
2903
2904 if (LEN(aname(1)) .lt. MAXNCNAM) then
2905 print *,'GFIO_GetAttNames: length of aname array must be at ',
2906 . 'least ',MAXNCNAM,' bytes.'
2907 rc = -11
2908 return
2909 endif
2910
2911
2912
2913 do i=1,ngatts
2914 call ncanam (fid, NCGLOBAL, i, aname(i), rc)
2915 if (err("GetAttNames: error reading attribute name",rc,-57)
2916 . .NE. 0) return
2917 enddo
2918
2919 rc = 0
2920 return
2921 end
2922
2923
2924
2925
2926
2927
2928
2929
2930
2931
2932
2933
2934
2935
2936
2937 subroutine GFIO_AttInquire ( fid, name, type, count, rc )
2938
2939
2940
2941 Implicit NONE
2942 include "netcdf.inc"
2943 include "gfio.h"
2944
2945
2946
2947 integer fid
2948 character*(*) name
2949
2950
2951
2952 integer type
2953
2954
2955
2956
2957
2958
2959 integer count
2960 integer rc
2961
2962
2963
2964
2965
2966
2967
2968
2969
2970
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987 integer nctype
2988 integer err
2989
2990 call ncainq (fid, NCGLOBAL, name, nctype, count, rc)
2991 if (err("AttInquire: error reading attribute info",rc,-58)
2992 . .NE. 0) return
2993 if (nctype .EQ. NCLONG) then
2994 type = 0
2995 elseif (nctype .EQ. NCFLOAT) then
2996 type = 1
2997 elseif (nctype .EQ. NCCHAR) then
2998 type = 2
2999 elseif (nctype .EQ. NCDOUBLE) then
3000 type = 3
3001 else
3002 type = -1
3003 endif
3004
3005 rc = 0
3006 return
3007 end
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021 subroutine GFIO_GetIntAtt ( fid, name, count, buf, rc )
3022
3023
3024
3025 Implicit NONE
3026 include "netcdf.inc"
3027 include "gfio.h"
3028
3029
3030
3031 integer fid
3032 character*(*) name
3033
3034
3035
3036 integer count
3037
3038
3039
3040
3041
3042 integer buf(count)
3043 integer rc
3044
3045
3046
3047
3048
3049
3050
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063 integer length, type
3064 integer err, i
3065 integer*4 dummy32
3066 integer*8 dummy64
3067 integer*4, allocatable :: buf32(:)
3068 integer*8, allocatable :: buf64(:)
3069
3070 call ncainq (fid, NCGLOBAL, name, type, length, rc)
3071 if (err("GetIntAtt: error reading attribute info",rc,-58)
3072 . .NE. 0) return
3073
3074 if ( count .NE. length ) then
3075 rc = -1
3076 count = length
3077 return
3078 endif
3079
3080 if ( type .NE. NCLONG .AND. type .NE. NCDOUBLE) then
3081 rc = -2
3082 return
3083 endif
3084 if ( HUGE(dummy32) .EQ. HUGE(i)) then
3085 if ( type .EQ. NCLONG ) then
3086 call ncagt ( fid, NCGLOBAL, name, buf, rc )
3087 else
3088 allocate (buf64(count))
3089 call ncagt ( fid, NCGLOBAL, name, buf64, rc )
3090 do i=1,count
3091 buf(i) = buf64(i)
3092 enddo
3093 deallocate (buf64)
3094 endif
3095 else if (HUGE(dummy64) .EQ. HUGE(i)) then
3096 if ( type .EQ. NCLONG ) then
3097 allocate (buf32(count))
3098 call ncagt ( fid, NCGLOBAL, name, buf32, rc )
3099 do i=1,count
3100 buf(i) = buf32(i)
3101 enddo
3102 deallocate (buf32)
3103 else
3104 call ncagt ( fid, NCGLOBAL, name, buf, rc )
3105 endif
3106 else
3107 rc = -12
3108 return
3109 endif
3110 if (err("GetIntAtt: error reading attribute value",rc,-51)
3111 . .NE. 0) return
3112
3113 rc = 0
3114 return
3115 end
3116
3117
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129 subroutine GFIO_GetRealAtt ( fid, name, count, buf, rc )
3130
3131
3132
3133 Implicit NONE
3134 include "netcdf.inc"
3135 include "gfio.h"
3136
3137
3138
3139 integer fid
3140 character*(*) name
3141
3142
3143
3144 integer count
3145
3146
3147
3148
3149
3150 real buf(count)
3151 integer rc
3152
3153
3154
3155
3156
3157
3158
3159
3160
3161
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172 integer length, type
3173 integer err
3174 real r
3175 integer i
3176 real*4 dummy32
3177 real*8 dummy64
3178 real*4, allocatable :: buf32(:)
3179 real*8, allocatable :: buf64(:)
3180
3181 call ncainq (fid, NCGLOBAL, name, type, length, rc)
3182 if (err("GetRealAtt: error reading attribute info",rc,-58)
3183 . .NE. 0) return
3184
3185 if ( count .NE. length ) then
3186 rc = -1
3187 count = length
3188 return
3189 endif
3190 if ( type .NE. NCFLOAT .AND. type .NE. NCDOUBLE) then
3191 rc = -2
3192 return
3193 endif
3194
3195 if ( HUGE(dummy32) .EQ. HUGE(r)) then
3196 if ( type .EQ. NCFLOAT ) then
3197 call ncagt ( fid, NCGLOBAL, name, buf, rc )
3198 else
3199 allocate (buf64(count))
3200 call ncagt ( fid, NCGLOBAL, name, buf64, rc )
3201 do i=1,count
3202 buf(i) = buf64(i)
3203 enddo
3204 deallocate (buf64)
3205 endif
3206 else if (HUGE(dummy64) .EQ. HUGE(r)) then
3207 if ( type .EQ. NCFLOAT ) then
3208 allocate (buf32(count))
3209 call ncagt ( fid, NCGLOBAL, name, buf32, rc )
3210 do i=1,count
3211 buf(i) = buf32(i)
3212 enddo
3213 deallocate (buf32)
3214 else
3215 call ncagt ( fid, NCGLOBAL, name, buf, rc )
3216 endif
3217 else
3218 rc = -12
3219 return
3220 endif
3221 if (err("GetRealAtt: error reading attribute value",rc,-51)
3222 . .NE. 0) return
3223
3224 rc = 0
3225 return
3226 end
3227
3228
3229
3230
3231
3232
3233
3234
3235
3236
3237
3238
3239
3240 subroutine GFIO_GetCharAtt ( fid, name, count, buf, rc )
3241
3242
3243
3244 Implicit NONE
3245 include "netcdf.inc"
3246 include "gfio.h"
3247
3248
3249
3250 integer fid
3251 character*(*) name
3252
3253
3254
3255 integer count
3256
3257
3258
3259
3260
3261 character buf(count)
3262 integer rc
3263
3264
3265
3266
3267
3268
3269
3270
3271
3272
3273
3274
3275
3276
3277
3278
3279
3280 integer length, type
3281 integer err
3282
3283 call ncainq (fid, NCGLOBAL, name, type, length, rc)
3284 if (err("GetCharAtt: error reading attribute info",rc,-58)
3285 . .NE. 0) return
3286 if ( count .NE. length ) then
3287 rc = -1
3288 count = length
3289 return
3290 endif
3291 if ( type .NE. NCCHAR) then
3292 rc = -2
3293 return
3294 endif
3295
3296 call ncagtc ( fid, NCGLOBAL, name, buf, count, rc )
3297 if (err("GetCharAtt: error reading attribute value",rc,-51)
3298 . .NE. 0) return
3299
3300 rc = 0
3301 return
3302 end
3303