Merge remote-tracking branch 'origin/release-v4.6.1'
[WRF.git] / var / obsproc / kmabufr_to_littler / kma_bufr_src / decode_bufr.F
blobc636e479ba28e153f522158d17f35d13366b716b
1       PROGRAM BUFR
3 C**** *BUFR*
6 C     PURPOSE.
7 C     --------
8 C         EXAMPLE OF USING BUFR UNPACKING/PACKING SOFTWARE.
11 C**   INTERFACE.
12 C     ----------
14 C          NONE.
16 C     METHOD.
17 C     -------
19 C          NONE.
22 C     EXTERNALS.
23 C     ----------
25 C         CALL BUSEL
26 C         CALL BUFREX
27 C         CALL BUFREN
28 C         CALL BUPRS0
29 C         CALL BUPRS1
30 C         CALL BUPRS2
31 C         CALL BUPRS3
32 C         CALL BUPRT
33 C         CALL BUUKEY
35 C     REFERENCE.
36 C     ----------
38 C          NONE.
40 C     AUTHOR.
41 C     -------
43 C          M. DRAGOSAVAC    *ECMWF*       15/09/87.
46 C     MODIFICATIONS.
47 C     --------------
49 C          NONE.
52       IMPLICIT LOGICAL(L,O,G), CHARACTER*8(C,H,Y)
54       PARAMETER(JSUP =   9,JSEC0=   3,JSEC1= 40,JSEC2= 64 ,JSEC3=    4,
55      1        JSEC4=   2,JELEM=80000,JSUBS=400,JCVAL=150 ,JBUFL=512000,
56 #ifdef JBPW_64
57      2        JBPW =  64,JTAB =1000,JCTAB=120,JCTST=1800,JCTEXT=1200,
58 #else
59      2        JBPW =  32,JTAB =1000,JCTAB=120,JCTST=1800,JCTEXT=1200,
60 #endif
61      3        JWORK=4096000,JKEY=46,JBYTE=2048000)
63       PARAMETER (KELEM=40000)
64       PARAMETER (KVALS=4096000)
65
66       DIMENSION KBUFF(JBUFL)
67       DIMENSION KBUFR(JBUFL)
68       DIMENSION KSUP(JSUP)  ,KSEC0(JSEC0),KSEC1(JSEC1)
69       DIMENSION KSEC2(JSEC2),KSEC3(JSEC3),KSEC4(JSEC4)
70       DIMENSION KEY  (JKEY),KREQ(2)
71       DIMENSION NREQUEST(2)
73       REAL*8 VALUES(KVALS),VALUE(KVALS)
74       REAL*8 VALS(KVALS)
75       REAL*8 RQV(KELEM)
76       REAL*8 RVIND,EPS
78       DIMENSION KTDLST(JELEM),KTDEXP(JELEM),KRQ(KELEM)
79       DIMENSION KDATA(200),KBOXR(JELEM*4)
82       CHARACTER*256 CFIN,COUT,CARG(4)
83       CHARACTER*64 CNAMES(KELEM),CBOXN(JELEM*4)
84       CHARACTER*24 CUNITS(KELEM),CBOXU(JELEM*4)
85       CHARACTER*80 CVALS(kelem)
86       CHARACTER*80 CVAL(kelem)
87       CHARACTER*80 YENC
89 C     ------------------------------------------------------------------
90 C*          1. INITIALIZE CONSTANTS AND VARIABLES.
91 C              -----------------------------------
92  100  CONTINUE
94 C     MISSING VALUE INDICATOR
95
96       RVIND=1.7E38
97       NVIND=2147483647
99       NBYTPW=JBPW/8
100       IOBS=0
101       EPS=1.E-8
102       NPACK=0
103       N=0
104       OO=.FALSE.
105       KKK=0
107 C     GET INPUT AND OUTPUT FILE NAME.
109       NARG=COMMAND_ARGUMENT_COUNT()
112       DO 104 J=1,NARG
113       CALL GET_COMMAND_ARGUMENT(number=J, value=CARG(J))
114  104  CONTINUE
116       II=0
117       IO=0
118       DO 105 J=1,NARG
119       IF(CARG(J).EQ.'-i') THEN
120          IN=J
121       ELSEIF(CARG(J).EQ.'-o') THEN
122          IO=J
123       END IF
124  105  CONTINUE
125       IF(IN.EQ.0) THEN
126          PRINT*,'USAGE -- decode_bufr -i infile'
127          STOP
128       END IF
129       IF(IO.EQ.0.and.IN.EQ.0) THEN
130          PRINT*,'USAGE -- decode_bufr -i infile -o outfile'
131          STOP
132       END IF
135       IF(IO.NE.0)  COUT=CARG(IO+1)
137       IF(IO.LT.IN) THEN
138          IST=IN+1
139          IEND=NARG
140       ELSE
141          IST=IN+1
142          IEND=IO-1
143       END IF
146       IF(IO.NE.0) THEN
147          JJ=INDEX(COUT,' ')
148          JJ=JJ-1
149          CALL PBOPEN(IUNIT1,COUT(1:JJ),'W',IRET)
150          IF(IRET.EQ.-1) STOP 'OPEN FAILED ON BUFR.DAT'
151          IF(IRET.EQ.-2) STOP 'INVALID FILE NAME'
152          IF(IRET.EQ.-3) STOP 'INVALID OPEN MODE SPECIFIED'
153       END IF
155       DO 101 II=IST,IEND
157       CFIN=CARG(II)
158       ILN=INDEX(CFIN,' ')
159       ILN=ILN-1
161 C     SET REQUEST FOR PARTIAL EXPANSION
163       KRQL=0
164       NR=0
165       KREQ(1)=0
166       KREQ(2)=0
167       DO 103 I=1,KELEM
168       RQV(I)=RVIND
169       KRQ(I)=NVIND
170  103  CONTINUE
172 C*          1.2 OPEN FILE CONTAINING BUFR DATA.
173 C               -------------------------------
174  120  CONTINUE
176       IRET=0 
177       CALL PBOPEN(IUNIT,CFIN(1:ILN),'R',IRET)
178       IF(IRET.EQ.-1) STOP 'OPEN FAILED'
179       IF(IRET.EQ.-2) STOP 'INVALID FILE NAME'
180       IF(IRET.EQ.-3) STOP 'INVALID OPEN MODE SPECIFIED'
185 C     ----------------------------------------------------------------- 
186 C*          2. SET REQUEST FOR EXPANSION.
187 C              --------------------------
188  200  CONTINUE
190       OPRT=.FALSE.
191       OENC=.FALSE.
192       WRITE(*,'(A,$)') ' DO YOU WANT TO PRINT( Y/N ) : '
193       READ (*,'(A)') YENC
194       IF(YENC(1:1).EQ.'Y'.OR.YENC(1:1).EQ.'y') THEN
195          OPRT=.TRUE.
196       END IF
197       ICODE=0
198       WRITE(*,'(A,$)') ' CODE TABLES TO BE PRINTED ( Y/N ) : '
199       READ (*,'(A)') YCODC
200       IF(YCODC(1:1).EQ.'Y'.OR.YCODC(1:1).EQ.'y') THEN
201          ICODE=1
202       END IF
203       WRITE(*,'(A,$)') ' DO YOU WANT ENCODING( Y/N ) : '
204       READ (*,'(A)') YENC
205       IF(YENC(1:1).EQ.'Y'.OR.YENC(1:1).EQ.'y') THEN
206           OENC=.TRUE.
207          WRITE(*,'(A,$)') ' NUMBER OF SUBSETS TO PACK : '
208          READ(*,'(BN,I4)')   NCOM
209          OCOMP=.FALSE.
210          WRITE(*,'(A,$)') ' DO YOU WANT COMPRESSION( Y/N ) : '
211          READ (*,'(A)') YCOMP
212          IF(YCOMP(1:1).EQ.'Y'.OR.YCOMP(1:1).EQ.'y') OCOMP=.TRUE.
213       END IF
214       WRITE(*,'(A,$)') ' RECORD NUMBER TO START FROM : '
215       READ(*,'(BN,I6)')   NR
217  201  CONTINUE
219       WRITE(*,'(A,$)') ' REQUESTED ELEMENT : ' 
220       READ(*,'(BN,I6)')   IEL 
221       WRITE(*,'(A,$)') ' REQUESTED VALUE   : '
222       READ(*,'(BN,F12.2)')   VAL
223       IF(IEL.EQ.0) THEN
224          KRQL=J
225       ELSE
226          J=J+1
227          KRQ(J)=IEL
228          RQV(J)=VAL
229          IF(VAL.EQ.0.) RQV(J)=RVIND
230          GO TO 201
231       END IF
233       WRITE(*,'(A,$)') ' REQUESTED FLAG 1  : '
234       READ(*,'(BN,I6)')  KREQ(1)
236       WRITE(*,'(A,$)') ' REQUESTED FLAG 2  : '
237       READ(*,'(BN,I6)')  KREQ(2)
239       WRITE(*,'(A,$)') ' DO YOU WANT TO PRINT SECTION 0-3( Y/N ) : '
240       READ (*,'(A,$)') YENC
241       OSEC3=.FALSE.
242       IF(YENC(1:1).EQ.'Y'.OR.YENC(1:1).EQ.'y') OSEC3=.TRUE.
244 C*          2.1 SET REQUEST FOR PARTIAL EXPANSION.
245 C               ----------------------------------
246  210  CONTINUE
248 c     KERR=0
249       CALL BUSRQ(KREQ,KRQL,KRQ,RQV,KERR)
251 C     SET VARIABLE TO PACK BIG VALUES AS MISSING VALUE INDICATOR
253       KPMISS=1
254       KPRUS=0
255       KOKEY=0
256       CALL BUPRQ(KPMISS,KPRUS,KOKEY)
258 C     -----------------------------------------------------------------
259 C*          3.  READ BUFR MESSAGE.
260 C               ------------------
261  300  CONTINUE
263       IERR=0
264       KBUFL=0
266       IRET=0
267       CALL PBBUFR(IUNIT,KBUFF,JBYTE,KBUFL,IRET) 
268       IF(IRET.EQ.-1) THEN
269          IF(IO.NE.0) THEN
270             IF(NPACK.NE.0) GO TO 600
271          END IF
272          PRINT*,'NUMBER OF SUBSETS     ',IOBS
273          PRINT*,'NUMBER OF MESSAGES    ',N
274          CALL PBCLOSE(IUNIT,IRET)
275          GO TO 101
276       END IF
277       IF(IRET.EQ.-2) STOP 'FILE HANDLING PROBLEM' 
278       IF(IRET.EQ.-3) STOP 'ARRAY TOO SMALL FOR PRODUCT'
280       N=N+1
281       PRINT*,'----------------------------------',N,' ',KBUFL
282       KBUFL=KBUFL/NBYTPW+1
283       IF(N.LT.NR) GO TO 300
285 C     -----------------------------------------------------------------
286 C*          4. EXPAND BUFR MESSAGE.
287 C              --------------------
288  400  CONTINUE
290       CALL BUS012(KBUFL,KBUFF,KSUP,KSEC0,KSEC1,KSEC2,KERR)
291       IF(KERR.NE.0) THEN
292          PRINT*,'ERROR IN BUS012: ',KERR
293          PRINT*,' BUFR MESSAGE NUMBER ',N,' CORRUPTED.'
294          KERR=0
295          GO TO 300
296       END IF
298       KEL=KVALS/KSUP(6)
299       IF(KEL.GT.JELEM) KEL=JELEM
301          CALL BUFREX(KBUFL,KBUFF,KSUP,KSEC0 ,KSEC1,KSEC2 ,KSEC3 ,KSEC4,
302      1            KEL,CNAMES,CUNITS,KVALS,VALUES,CVALS,IERR)
304       IF(IERR.NE.0) THEN
305          IF(IERR.EQ.39) GO TO 300
306          CALL EXIT(2)
307       END IF
310       IOBS=IOBS+KSEC3(3)
312       NPACK=NPACK+1 
314       CALL BUSEL(KTDLEN,KTDLST,KTDEXL,KTDEXP,KERR)
315       IF(KERR.NE.0) CALL EXIT(2)
318 c      DO 401 IK=1,KSEC3(3)
320 c      CALL BUBOX(IK,KSUP,KEL,KTDEXP,CNAMES,CUNITS,KVALS,VALUES,
321 c    1            KBOX,KAPP,KLEN,KBOXR,VALS,CBOXN,CBOXU,IERR)
323 c 401  CONTINUE
325 c      IF(IERR.NE.0) THEN
326 c        PRINT*,'bubox error----------------------------------',N
327 c      END IF
329 C*          4.1 PRINT CONTENT OF EXPANDED DATA.
330 C               -------------------------------
331  410  CONTINUE
333       IF(.NOT.OPRT) GO TO 500
334       IF(.NOT.OSEC3) GO TO 450
336 C*          4.2 PRINT SECTION ZERO OF BUFR MESSAGE.
337 C               -----------------------------------
338  420  CONTINUE
341       CALL BUPRS0(KSEC0)
343 C*          4.3 PRINT SECTION ONE OF BUFR MESSAGE.
344 C               -----------------------------------
345  430  CONTINUE
347       CALL BUPRS1(KSEC1)
350 C*          4.4 PRINT SECTION TWO OF BUFR MESSAGE.
351 C               -----------------------------------
352  440  CONTINUE
354 C              AT ECMWF SECTION 2 CONTAINS RDB KEY.
355 C              SO UNPACK KEY
357       CALL BUUKEY(KSEC1,KSEC2,KEY,KSUP,KERR)
359 C              PRINT KEY
361       CALL BUPRS2(KSUP ,KEY)
363 C*          4.5 PRINT SECTION 3 OF BUFR MESSAGE.
364 C               -----------------------------------
365  450  CONTINUE
367 C               FIRST GET DATA DESCRIPTORS
369       CALL BUSEL(KTDLEN,KTDLST,KTDEXL,KTDEXP,KERR)
370 C     IF(KERR.NE.0) CALL EXIT(2)
372 C               PRINT  CONTENT
374       IF(OSEC3) THEN
375          CALL BUPRS3(KSEC3,KTDLEN,KTDLST,KTDEXL,KTDEXP,KEL,CNAMES)
376       END IF
378 C*         4.6 PRINT SECTION 4 (DATA).
379 C              -----------------------
380  460  CONTINUE
382 C          IN THE CASE OF MANY SUBSETS DEFINE RANGE OF SUBSETS
384       IF(.NOT.OO) THEN
385       WRITE(*,'(A,$)') ' STARTING SUBSET TO BE PRINTED : '
386       READ(*,'(BN,I6)')   IST
387       WRITE(*,'(A,$)') ' ENDING SUBSET TO BE PRINTED : '
388       READ(*,'(BN,I6)')   IEND
389       OO=.FALSE.
390       END IF
392 C              PRINT DATA
394       ICODE=0
396 C     IF(KSEC1(6).EQ.11) THEN
398          CALL BUPRT(ICODE,IST,IEND,KEL,CNAMES,CUNITS,CVALS,
399      1              KVALS,VALUES,KSUP,KSEC1,IERR)
400 C     ELSE
402 C              RESOLVE BIT MAPS 
404 C        IF(IEND.GT.KSEC3(3)) IEND=KSEC3(3)
406 C        DO 461 IK=IST,IEND
408 C        CALL BUBOX(IK,KSUP,KEL,KTDEXP,CNAMES,CUNITS,KVALS,VALUES,
409 C    1              KBOX,KAPP,KLEN,KBOXR,VALS,CBOXN,CBOXU,IERR)
410 C        IF(IERR.NE.0) CALL EXIT(2)
412 C        CALL BUPRTBOX(KBOX,KAPP,KLEN,KBOXR,VALS,CBOXN,CBOXU)
414 C461     CONTINUE
415 C     END IF
417 C     -----------------------------------------------------------------
418 C*          5. COLLECT DATA FOR REPACKING.
419 C              ---------------------------
420  500  CONTINUE
421 C      
423       IF(.NOT.OENC) GO TO 300
425 C               FIRST GET DATA DESCRIPTORS
427       CALL BUSEL(KTDLEN,KTDLST,KTDEXL,KTDEXP,KERR)
428       IF(KERR.NE.0) CALL EXIT(2)
430       DO 501 I=1,KSUP(5)
431          IN=I+(NPACK-1)*KSUP(5)
433          IF(CUNITS(I).EQ.'CCITTIA5') THEN
434             IPOS =VALUES(I)/1000.
435             ICH=NINT(VALUES(I)-IPOS*1000)
436             KKK=KKK+1
437             VALUE(IN)=KKK*1000+ICH
438             CVAL(KKK)=CVALS(IPOS)
439          ELSE
440             VALUE(IN)=VALUES(I)
441          END IF
442  501  CONTINUE
444       IF(NPACK.EQ.NCOM)    GO TO 600
446       GO TO 300
447 C     -----------------------------------------------------------------
448 C*          6. PACK BUFR MESSAGE BACK INTO BUFR.
449 C              ---------------------------------
450  600  CONTINUE
452     
453       KKK=0
454       KSEC1(5)=0
455       KSEC3(3)=NPACK
456       KSEC1(8)=1
457       KSEC1(15)=6
458       KSEC0(3)=4              ! EDITION 4 OF BUFR MESSAGE
459       KSEC3(4)=128            ! NO COMPRESSION
460       IF(OCOMP) KSEC3(4)=192  ! COMPRESSION  
461       KBUFL=JBUFL
463 C     GET REPLICATION FACTORS
465       KK=0
466       DO 601 K=1,KSUP(5)
467       IF(KTDEXP(K).EQ.31001.OR.KTDEXP(K).EQ.31002) THEN
468          KK=KK+1
469          KDATA(KK)=NINT(VALUE(K))
470       END IF
471  601  CONTINUE
473       KDLEN=2
474       IF(KK.NE.0) KDLEN=KK
475       IF(KSEC1(5).NE.0) THEN
476          CALL BUUKEY(KSEC1,KSEC2,KEY,KSUP,KERR)
477          IF(KERR.NE.0) THEN
478             PRINT*,'BUUKEY: ERROR ',KERR
479             CALL EXIT(2)
480          END IF
483 C        GET INFORMATION FOR RDB KEY
485          CALL BUCRKEY(KSUP(5),KTDEXP,KSUP,KSEC1,KSEC3,KEY,
486      1                 VALUE,CVAL,KERR)
487          IF(KERR.NE.0) THEN
488             PRINT*,'ERROR IN BUCREKEY.'
489             call exit(2)
490          END IF
493 C        PACK NEW RDB KEY
496          CALL BUPKEY(KEY,KSEC1,KSEC2,KERR)
497          IF(KERR.NE.0) CALL EXIT(2)
499       END IF
501       IF(KSUP(6).EQ.0) THEN
502          PRINT*,'ZERO SUBSETS'
503          CALL EXIT(2)
504       END IF
507 C*          6.2 ENCODE DATA INTO BUFR MESSAGE.
508 C               ------------------------------
509  620  CONTINUE
511       CALL BUFREN( KSEC0,KSEC1,KSEC2,KSEC3,KSEC4,
512      1             KTDLEN,KTDLST,KDLEN,KDATA,KSUP(5),    ! KEL
513      2             KVALS,VALUE,CVAL,KBUFL,KBUFR,KERR)
515       IF(KERR.NE.0) THEN
516          PRINT*,'ERROR IS ',KERR
517          PRINT*,'ERROR DURING ENCODING.'
518          CALL EXIT(2)
519       END IF
521 C           6.3 WRITE PACKED BUFR MESSAGE INTO FILE.
522 C               ------------------------------------
523  630  CONTINUE
525       ILEN=KBUFL*NBYTPW
526 C     
527       IERR=0
529        CALL PBWRITE(IUNIT1,KBUFR,ILEN,IERR)
530        IF(IERR.LT.0) THEN
531           PRINT*,'ERROR WRITING INTO TARGET FILE.'
532           CALL EXIT(2)
533        END IF
534        PRINT*,'RECORD WRITTEN INTO FILE-   ILEN=',ilen
536       NPACK=0
538       GO TO 300
539 C     -----------------------------------------------------------------
541  101  CONTINUE
543       IF(IO.NE.0) THEN
544       CALL PBCLOSE(IUNIT1,IRET)
545       END IF
547       END