NCEPLIBS-w3emc  2.11.0
w3fi65.f
Go to the documentation of this file.
1 C> @file
2 C> @brief NMC office note 29 report packer.
3 C> @author L. Marx @date 1990-01
4 
5 C> Packs an array of upper-air reports into the format
6 C> described by NMC office note 29, or packs an array of surface
7 C> reports into the format described by NMC office note 124. Input
8 C> integer, real or character type as specified in the category
9 C> tables in the write-up for w3fi64() (the office note 29 report
10 C> packer) are converted to character data. Missing character data
11 C> are specified as strings of 9's except for that converted from
12 C> input character type which are generally specified as blanks.
13 C> This library is similar to w3ai03() except w3ai03() was written in
14 C> assembler.
15 C>
16 C> Program history log:
17 C> - L. Marx 1990-01 Converted code from assembler
18 C> to vs fortran.
19 C> - Dennis Keyser 1991-08-23 Use same arguments as w3ai03() ;
20 C> Streamlined code; Docblocked and commented.
21 C> - Dennis Keyser 1992-06-29 Convert to cray cft77 fortran.
22 C> - Dennis Keyser 1992-07-09 Checks the number of characters
23 C> used by each variable prior to conversion from
24 C> integer to character format; If this number is
25 C> greater than the number of characters allocated for
26 C> the variable the variable is packed as "missing"
27 C> (i.e., stores as all 9's).
28 C> - Dennis Keyser 1993-06-28 Initializes number of words in
29 C> report to 42 in case "strange" report with no data
30 C> in any category encountered (used to be zero, but
31 C> such "strange" reports caused code to fail).
32 C> - Dennis Keyser 1993-12-22 Corrected error which resulted
33 C> in storage of 0's in place of actual data in a
34 C> category when that category was the only one with
35 C> data.
36 C> - Dennis Keyser 1998-08-07 Fortran 90-compliant - split an
37 C> if statement into 2-parts to prevent f90 floating
38 C> point exception error that can now occur in some
39 C> cases (did not occur in f77).
40 C>
41 C> @param[in] LOCRPT Integer array containing one unpacked report.
42 C> LOCRPT must begin on a fullword boundary. Format
43 C> is mixed, user must equivalence real and character
44 C> arrays to this array (see w3fi64 write-up for
45 C> content).
46 C> @param[out] COCBUF CHARACTER*10 Array containing a packed report in
47 C> NMC office note 29/124 format.
48 C>
49 C> @note After first creating and writing out the office note 85
50 C> (first) date record, the user's fortran program begins a packing
51 C> loop as follows.. Each iteration of the packing loop consists of
52 C> a call first to w3fi65() to pack the report into COCBUF, then a call
53 C> to w3fi66() with the current value of 'NFLAG' (set to zero for first
54 C> call) to block the packed report into a record (see w3fi66() write-
55 C> up). if 'NFLAG' is -1 upon returning from w3fi66(), the remaining
56 C> portion of the record is not large enough to hold the current
57 C> packed report. The user should write out the record, set 'NFLAG'
58 C> to zero, call w3fi66() to write the packed report to the beginning
59 C> of the next record, and repeat the packing loop. If 'NFLAG' is
60 C> positive, a packed report has been blocked into the record and
61 C> the user should continue the packing loop.
62 C> When all reports have been packed and blocked, the user
63 C> should write out this last record (which is not full but contains
64 C> fill information supplied by w3fi66()). One final record containing
65 C> the string 'endof file' (sic) followed by blank fill must be
66 C> written out to signal the end of the data set.
67 C>
68 C> @note 1: The packed report will have the categories ordered as
69 C> follows: 1, 2, 3, 4, 5, 6, 7, 51, 52, 8, 9.
70 C> @note 2: The input unpacked report must be in the format spec-
71 C> ified in the w3fi64() office note 29 report unpacker write-up.
72 C> @note 3: The unused porion of cocbuf is not cleared.
73 
74 C> @note Entry w3ai03() duplicates processing in w3fi65() since no
75 C> assembly language code in cray w3lib.
76 C>
77 C> @author L. Marx @date 1990-01
78  SUBROUTINE w3fi65(LOCRPT,COCBUF)
79 C
80  CHARACTER*12 HOLD
81  CHARACTER*10 COCBUF(*),FILL
82  CHARACTER*7 CNINES
83  CHARACTER*4 COCRPT(10000)
84  CHARACTER*2 KAT(11)
85 C
86  INTEGER LOCRPT(*),KATL(11),KATO(11),KATGC(20,11),KATGL(20,11),
87  $ MOCRPT(5000),KATLL(11)
88 C
89  REAL ROCRPT(5000)
90 C
91  equivalence(rocrpt,mocrpt,cocrpt)
92 C
93  SAVE
94 C
95  DATA katl/6,4,4,4,6,6,3,20,15,3,1/,kato/13,15,17,19,21,23,25,29,
96  $ 31,27,33/,imsg/99999/,fill/'XXXXXXXXXX'/,kat/'01','02','03','04',
97  $'05','06','07','51','52','08','09'/,cnines/'9999999'/,xmsg/99999./
98  DATA katgc/ 5*2,4,14*0, 3*2,4,16*0, 3*2,4,16*0, 3*2,4,16*0,
99  $ 5*2,4,14*0, 5*2,4,14*0, 2*2,4,17*0, 8*2,4,10*1,2, 15*1,5*0,
100  $ 2*2,4,17*0, 4,19*0/
101  DATA katgl/ 5,4,3*3,4,14*0, 5,4,2*3,16*0, 5,2*3,2,16*0,
102  $ 5,2*3,2,16*0, 5,4,3*3,4,14*0, 5,4,3*3,4,14*0, 5,3,2,17*0,
103  $ 2*5,2*3,4,3,2*4,5,2*3,7*2,1,3,
104  $ 4,3,4,1,5*2,4,2*2,1,2,7,5*0, 5,3,2,17*0, 12,19*0/
105  DATA katll/6,4,4,4,6,6,3,21,15,3,3/
106  DATA lwflag/0/
107 C
108  entry w3ai03(locrpt,cocbuf)
109 C
110  IF (lwflag.EQ.0) THEN
111 C FIRST TIME CALLED, DETERMINE MACHINE WORD LG IN BYTES (=8 FOR CRAY)
112 C DEPENDING ON WORD SIZE LW2*I-LW1 INDEXES THRU COCRPT
113 C EITHER AS 1,2,3...I FOR LW = 4 OR
114 C AS 1,3,5..2*I-1 FOR LW = 8 <------ HERE
115 C NECESSITATED BY LEFT JUSTIFICATION OF EQUIVALENCE
116  CALL w3fi01(lw)
117  lw2 = lw/4
118  lw1 = lw/8
119  lwflag = 1
120  END IF
121  mi = 43
122  kk = 0
123  lvls = 0
124 C DETERMINE THE TRUE NUMBER OF BYTES IN THE INPUT REPORT
125  DO 100 ncat = 1,11
126  m = kato(ncat)
127  IF(locrpt(m+1).GE.mi) kk = ncat
128  mi = max(mi,locrpt(m+1))
129  100 CONTINUE
130  IF(kk.GT.0) THEN
131  m = kato(kk)
132  lvls = locrpt(m)
133  END IF
134 cvvvvvy2k
135 cdak MBYTES = LW * ((MI - 1) + (LVLS * KATLL(KK)))
136  mwords = (mi - 1) + (lvls * katll(kk))
137 C TRANSFER LOCRPT TO MOCRPT IN ORDER TO EQUIVALENCE TO REAL AND CHAR.
138 cdak CALL XMOVEX(MOCRPT,LOCRPT,MBYTES)
139  mocrpt(1:mwords) = locrpt(1:mwords)
140 caaaaay2k
141 C INITIALIZE REPORT ID AS MISSING OR NOT APPLICABLE
142  cocbuf(1) = '9999999999'
143  cocbuf(2)(7:10) = '9999'
144  cocbuf(3)(8:10) = '999'
145  cocbuf(4)(1:7) = '9999999'
146 C READ IN LATITUDE FROM WORD 1 (REAL)
147 C WRITE OUT IN FIRST 5 CHARACTERS OF WORD 1 (C*5)
148  m = 1
149  n = 1
150  IF(rocrpt(m).LT.xmsg) THEN
151  IF(int(rocrpt(m)).GE.0) WRITE(cocbuf(n)(1:5),50)int(rocrpt(m))
152  IF(int(rocrpt(m)).LT.0) WRITE(cocbuf(n)(1:5),55)int(rocrpt(m))
153  END IF
154 C READ IN LONGITUDE FROM WORD 2 (REAL)
155 C WRITE OUT IN LAST 5 CHARACTERS OF WORD 1 (C*5)
156  m = 2
157  IF(rocrpt(m).LT.xmsg) THEN
158  IF(int(rocrpt(m)).GE.0) WRITE(cocbuf(n)(6:10),50)int(rocrpt(m))
159  IF(int(rocrpt(m)).LT.0) WRITE(cocbuf(n)(6:10),55)int(rocrpt(m))
160  END IF
161 C READ IN STATION ID FROM WORDS 11 AND 12 (C*8)
162 C (CHAR. 1-4 OF ID IN WORD 11, CHAR. 5-6 OF ID IN WORD 12, LEFT-JUSTIF.)
163 C WRITE OUT IN FIRST 6 CHARACTERS OF WORD 2 (C*6)
164  m = 11
165  n = n + 1
166  cocbuf(n)(1:6) = cocrpt(lw2*m-lw1)(1:4)//
167  $ cocrpt(lw2*(m+1)-lw1)(1:2)
168 C READ IN OBSERVATION TIME FROM WORD 4 (REAL)
169 C WRITE OUT IN LAST 4 CHARACTERS OF WORD 2 (C*4)
170  m = 4
171  IF(rocrpt(m).LT.xmsg) WRITE(cocbuf(n)(7:10),40) int(rocrpt(m))
172 C READ IN RESERVED CHARACTERS FROM WORDS 5 AND 6 (C*8)
173 C (4 CHAR., LEFT-JUSTIF.)
174 C WRITE OUT IN FIRST 7 CHARACTERS OF WORD 3 (C*7)
175  m = 5
176  n = n + 1
177  cocbuf(n)(1:7) =cocrpt(lw2*(m+1)-lw1)(1:2)//
178  $ cocrpt(lw2*m-lw1)(1:4)//cocrpt(lw2*(m+1)-lw1)(3:3)
179 C READ IN OFFICE NOTE 29 REPORT TYPE FROM WORD 9 (INTEGER)
180 C WRITE OUT IN LAST 3 CHARACTERS OF WORD 3 (C*3)
181  m = 9
182  IF(mocrpt(m).LT.imsg) WRITE(cocbuf(n)(8:10),30) mocrpt(m)
183 C READ IN STATION ELEVATION FROM WORD 7 (REAL)
184 C WRITE OUT IN FIRST 5 CHARACTERS OF WORD 4 (C*4)
185  m = 7
186  n = n + 1
187  IF(rocrpt(m).LT.xmsg) THEN
188  IF(int(rocrpt(m)).GE.0) WRITE(cocbuf(n)(1:5),50)int(rocrpt(m))
189  IF(int(rocrpt(m)).LT.0) WRITE(cocbuf(n)(1:5),55)int(rocrpt(m))
190  END IF
191 C READ IN INSTRUMENT TYPE FROM WORD 8 (INTEGER)
192 C WRITE OUT IN NEXT 2 CHARACTERS OF WORD 4 (C*2)
193  m = 8
194  IF(mocrpt(m).LT.99) WRITE(cocbuf(n)(6:7),20) mocrpt(m)
195  no = n
196  n = n + 1
197 CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
198 C LOOP THROUGH ALL THE CATEGORIES WHICH HAVE VALID DATA
199 CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
200  DO 3000 ncat = 1,11
201 C 'M' IS THE WORD IN MOCRPT WHERE THE NO. OF LEVELS IS READ FROM
202  m = kato(ncat)
203  lvls = mocrpt(m)
204 C 'MI' IS THE STARTING LOCATION IN MOCRPT FOR READING DATA FROM THIS CAT
205  mi = mocrpt(m+1)
206  IF(lvls.EQ.0.OR.mi.EQ.0) GO TO 3000
207 C CATEGORY WITH VALID CATEGORY ENCOUNTERED - WRITE OUT IN FIRST 2
208 C CHARACTERS OF CATEGORY/COUNTER GROUP FOR THIS CATEGORY (C*2)
209  cocbuf(n)(1:2) = kat(ncat)
210 C NUMBER OF LEVELS WRITTEN OUT TO CHAR. 6 & 7 OF CAT/CNTR GROUP (C*2)
211  WRITE(cocbuf(n)(6:7),20) lvls
212  nc = n
213  n = n + 1
214 C NWDSC COUNTS THE NUMBER OF 10-CHAR. WORDS IN THIS CATEGORY
215  nwdsc = 1
216  i = 1
217 C***********************************************************************
218 C LOOP THROUGH ALL THE LEVELS IN THE CURRENT CATEGORY
219 C***********************************************************************
220  DO 2000 l = 1,lvls
221 C NDG IS NO. OF INPUT PARAMETERS PER LEVEL IN THIS CATEGORY
222  ndg = katl(ncat)
223 C-----------------------------------------------------------------------
224 C LOOP THROUGH ALL THE PARAMETERS IN THE CURRENT LEVEL
225 C-----------------------------------------------------------------------
226  DO 1800 k = 1,ndg
227 C 'LL' IS THE NUMBER OF OUTPUT CHARACTERS PER PARAMETER FOR THIS CAT.
228  ll = katgl(k,ncat)
229 C KATGC IS AN INDICATOR FOR THE INPUT FORMAT OF EACH OUTPUT PARAMETER
230 C (=2 - REAL, =1 - INTEGER, =4 - CHARACTER*8)
231  IF(katgc(k,ncat).EQ.4) GO TO 1500
232 C OUTPUT PARAMETER IS MISSING OR NOT APPLICABLE (BASED ON MISSING INPUT)
233  IF(katgc(k,ncat).EQ.1) THEN
234  IF(mocrpt(mi).GE.imsg) THEN
235  hold(1:ll) = cnines(1:ll)
236 C SPECIAL CASE FOR INPUT PARAMETER 15, CAT. 52 -- MISSING IS '0099999'
237  IF(k.EQ.15.AND.ncat.EQ.9) hold(1:7) = '0099999'
238  GO TO 1750
239  END IF
240  ELSE IF(katgc(k,ncat).EQ.2) THEN
241  IF(rocrpt(mi).GE.xmsg) THEN
242  hold(1:ll) = cnines(1:ll)
243 C SPECIAL CASE FOR INPUT PARAMETER 15, CAT. 52 -- MISSING IS '0099999'
244  IF(k.EQ.15.AND.ncat.EQ.9) hold(1:7) = '0099999'
245  GO TO 1750
246  END IF
247  END IF
248  ivalue = mocrpt(mi)
249  IF(katgc(k,ncat).EQ.2) ivalue = int(rocrpt(mi))
250 C INITIALIZE ALL OUTPUT PARAMETERS HERE AS MISSING
251 C (WILL REMAIN MISSING IF "IVALUE" SOMEHOW WOULD FILL-UP TOO
252 C MANY CHARACTERS)
253  hold(1:ll) = cnines(1:ll)
254  IF(ll.EQ.1) THEN
255 C OUTPUT PARAMETER CONSISTS OF ONE CHARACTER
256  IF(ivalue.LE.9.AND.ivalue.GE.0)
257  $ WRITE(hold(1:ll),10) ivalue
258  ELSE IF(ll.EQ.2) THEN
259 C OUTPUT PARAMETER CONSISTS OF TWO CHARACTERS
260  IF(ivalue.LE.99.AND.ivalue.GE.-9) THEN
261  IF(ivalue.GE.0) WRITE(hold(1:ll),20) ivalue
262  IF(ivalue.LT.0) WRITE(hold(1:ll),25) ivalue
263  END IF
264  ELSE IF(ll.EQ.3) THEN
265 C OUTPUT PARAMETER CONSISTS OF THREE CHARACTERS
266  IF(ivalue.LE.999.AND.ivalue.GE.-99) THEN
267  IF(ivalue.GE.0) WRITE(hold(1:ll),30) ivalue
268  IF(ivalue.LT.0) WRITE(hold(1:ll),35) ivalue
269  END IF
270  ELSE IF(ll.EQ.4) THEN
271 C OUTPUT PARAMETER CONSISTS OF FOUR CHARACTERS
272  IF(ivalue.LE.9999.AND.ivalue.GE.-999) THEN
273  IF(ivalue.GE.0) WRITE(hold(1:ll),40) ivalue
274  IF(ivalue.LT.0) WRITE(hold(1:ll),45) ivalue
275  END IF
276  ELSE IF(ll.EQ.5) THEN
277 C OUTPUT PARAMETER CONSISTS OF FIVE CHARACTERS
278  IF(ivalue.LE.99999.AND.ivalue.GE.-9999) THEN
279  IF(ivalue.GE.0) WRITE(hold(1:ll),50) ivalue
280  IF(ivalue.LT.0) WRITE(hold(1:ll),55) ivalue
281  END IF
282  ELSE IF(ll.EQ.6) THEN
283 C OUTPUT PARAMETER CONSISTS OF SIX CHARACTERS
284  IF(ivalue.LE.999999.AND.ivalue.GE.-99999) THEN
285  IF(ivalue.GE.0) WRITE(hold(1:ll),60) ivalue
286  IF(ivalue.LT.0) WRITE(hold(1:ll),65) ivalue
287  END IF
288  ELSE IF(ll.EQ.7) THEN
289 C OUTPUT PARAMETER CONSISTS OF SEVEN CHARACTERS
290  IF(ivalue.LE.9999999.AND.ivalue.GE.-999999) THEN
291  IF(ivalue.GE.0) WRITE(hold(1:ll),70) ivalue
292  IF(ivalue.LT.0) WRITE(hold(1:ll),75) ivalue
293  END IF
294  END IF
295  GO TO 1750
296  1500 CONTINUE
297 C.......................................................................
298 C INPUT CHARACTER (MARKER) PROCESSING COMES HERE
299  IF(ll.LE.4) THEN
300 C THERE ARE BETWEEN ONE AND FOUR MARKERS IN OUTPUT PARAMETER
301  hold(1:ll) = cocrpt(lw2*mi-lw1)(1:ll)
302  ELSE
303 C THERE ARE MORE THAN FOUR MARKERS IN OUTPUT PARAMETER
304  ip = 1
305  1610 CONTINUE
306  jp = ip + 3
307  IF(jp.LT.ll) THEN
308 C GET FIRST FOUR MARKERS FROM INPUT WORD
309  hold(ip:jp) = cocrpt(lw2*mi-lw1)(1:4)
310  mi = mi + 1
311  ip = jp + 1
312  GO TO 1610
313  ELSE IF(jp.EQ.ll) THEN
314 C GET FOUR REMAINING MARKERS FROM NEXT INPUT WORD
315  hold(ip:jp) = cocrpt(lw2*mi-lw1)(1:4)
316  ELSE
317 C GET ONE, TWO, OR THREE REMAINING MARKERS FROM NEXT INPUT WORD
318  hold(ip:ll) = cocrpt(lw2*mi-lw1)(1:ll-jp+4)
319  END IF
320  END IF
321 C.......................................................................
322  1750 CONTINUE
323 C 'I' IS POINTER FOR BEGINNING BYTE IN C*10 WORD FOR OUTPUT PARAMETER
324 C 'J' IS POINTER FOR ENDING BYTE IN C*10 WORD FOR OUTPUT PARAMETER
325  j = i + ll - 1
326  IF(j.GT.10) THEN
327 C COME HERE IF OUTPUT PARAMETER SPANS ACROSS TWO C*10 WORDS
328  cocbuf(n)(i:10) = hold(1:11-i)
329  cocbuf(n+1)(1:j-10) = hold(12-i:ll)
330  n = n + 1
331  nwdsc = nwdsc + 1
332  i = j - 9
333  ELSE
334  cocbuf(n)(i:j) = hold(1:ll)
335  i = j + 1
336  IF(i.GE.11) THEN
337  n = n + 1
338  nwdsc = nwdsc + 1
339  i = 1
340  END IF
341  END IF
342 C GO ON TO NEXT INPUT WORD IN THIS LEVEL
343  mi = mi + 1
344  1800 CONTINUE
345 C-----------------------------------------------------------------------
346  2000 CONTINUE
347 C***********************************************************************
348 C FILL REMAINING PART OF LAST OUTPUT WORD IN THIS CATEGORY WITH X'S
349  IF(i.GT.1) cocbuf(n)(i:10) = fill(i:10)
350 C TOTAL NO. CHARACTERS IN CATEGORY (EXCL. FILLS) (NCHAR) WRITTEN OUT TO
351 C LAST 3 CHARACTERS OF CATEGORY/COUNTER GROUP (C*3)
352  nchar = ((nwdsc - 1) * 10) + i - 1
353  WRITE(cocbuf(nc)(8:10),30) nchar
354  IF(i.GT.1) n = n + 1
355 C RELATIVE POSITION IN REPORT OF NEXT CAT/CNTR GROUP (N) WRITTEN OUT TO
356 C CHAR. 3 - 5 OF CURRENT CATEGORY/COUNTER GROUP (C*3)
357  WRITE(cocbuf(nc)(3:5),30) n
358 C GO ON TO THE NEXT CATEGORY
359  3000 CONTINUE
360 CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
361 C WRITE OUT THE TOTAL LENGTH OF THE REPORT -- NO. OF 10-CHARACTER WORDS
362 C -- (N) IN LAST THREE CHARACTERS OF WORD 4 (C*3)
363  WRITE(cocbuf(no)(8:10),30) n
364 C WRITE OUT 'END REPORT' TO LOCATE THE END OF THIS REPORT IN THE BLOCK
365  cocbuf(n) = 'END REPORT'
366  RETURN
367  10 FORMAT(i1.1)
368  15 FORMAT(i1.0)
369  20 FORMAT(i2.2)
370  25 FORMAT(i2.1)
371  30 FORMAT(i3.3)
372  35 FORMAT(i3.2)
373  40 FORMAT(i4.4)
374  45 FORMAT(i4.3)
375  50 FORMAT(i5.5)
376  55 FORMAT(i5.4)
377  60 FORMAT(i6.6)
378  65 FORMAT(i6.5)
379  70 FORMAT(i7.7)
380  75 FORMAT(i7.6)
381  END
subroutine w3fi01(LW)
Determines the number of bytes in a full word for the particular machine (IBM or cray).
Definition: w3fi01.f:19
subroutine w3fi65(LOCRPT, COCBUF)
Packs an array of upper-air reports into the format described by NMC office note 29,...
Definition: w3fi65.f:79