NCEPLIBS-w3emc 2.12.0
Loading...
Searching...
No Matches
w3fi65.f
Go to the documentation of this file.
1C> @file
2C> @brief NMC office note 29 report packer.
3C> @author L. Marx @date 1990-01
4
5C> Packs an array of upper-air reports into the format
6C> described by NMC office note 29, or packs an array of surface
7C> reports into the format described by NMC office note 124. Input
8C> integer, real or character type as specified in the category
9C> tables in the write-up for w3fi64() (the office note 29 report
10C> packer) are converted to character data. Missing character data
11C> are specified as strings of 9's except for that converted from
12C> input character type which are generally specified as blanks.
13C> This library is similar to w3ai03() except w3ai03() was written in
14C> assembler.
15C>
16C> Program history log:
17C> - L. Marx 1990-01 Converted code from assembler
18C> to vs fortran.
19C> - Dennis Keyser 1991-08-23 Use same arguments as w3ai03() ;
20C> Streamlined code; Docblocked and commented.
21C> - Dennis Keyser 1992-06-29 Convert to cray cft77 fortran.
22C> - Dennis Keyser 1992-07-09 Checks the number of characters
23C> used by each variable prior to conversion from
24C> integer to character format; If this number is
25C> greater than the number of characters allocated for
26C> the variable the variable is packed as "missing"
27C> (i.e., stores as all 9's).
28C> - Dennis Keyser 1993-06-28 Initializes number of words in
29C> report to 42 in case "strange" report with no data
30C> in any category encountered (used to be zero, but
31C> such "strange" reports caused code to fail).
32C> - Dennis Keyser 1993-12-22 Corrected error which resulted
33C> in storage of 0's in place of actual data in a
34C> category when that category was the only one with
35C> data.
36C> - Dennis Keyser 1998-08-07 Fortran 90-compliant - split an
37C> if statement into 2-parts to prevent f90 floating
38C> point exception error that can now occur in some
39C> cases (did not occur in f77).
40C>
41C> @param[in] LOCRPT Integer array containing one unpacked report.
42C> LOCRPT must begin on a fullword boundary. Format
43C> is mixed, user must equivalence real and character
44C> arrays to this array (see w3fi64 write-up for
45C> content).
46C> @param[out] COCBUF CHARACTER*10 Array containing a packed report in
47C> NMC office note 29/124 format.
48C>
49C> @note After first creating and writing out the office note 85
50C> (first) date record, the user's fortran program begins a packing
51C> loop as follows.. Each iteration of the packing loop consists of
52C> a call first to w3fi65() to pack the report into COCBUF, then a call
53C> to w3fi66() with the current value of 'NFLAG' (set to zero for first
54C> call) to block the packed report into a record (see w3fi66() write-
55C> up). if 'NFLAG' is -1 upon returning from w3fi66(), the remaining
56C> portion of the record is not large enough to hold the current
57C> packed report. The user should write out the record, set 'NFLAG'
58C> to zero, call w3fi66() to write the packed report to the beginning
59C> of the next record, and repeat the packing loop. If 'NFLAG' is
60C> positive, a packed report has been blocked into the record and
61C> the user should continue the packing loop.
62C> When all reports have been packed and blocked, the user
63C> should write out this last record (which is not full but contains
64C> fill information supplied by w3fi66()). One final record containing
65C> the string 'endof file' (sic) followed by blank fill must be
66C> written out to signal the end of the data set.
67C>
68C> @note 1: The packed report will have the categories ordered as
69C> follows: 1, 2, 3, 4, 5, 6, 7, 51, 52, 8, 9.
70C> @note 2: The input unpacked report must be in the format spec-
71C> ified in the w3fi64() office note 29 report unpacker write-up.
72C> @note 3: The unused porion of cocbuf is not cleared.
73
74C> @note Entry w3ai03() duplicates processing in w3fi65() since no
75C> assembly language code in cray w3lib.
76C>
77C> @author L. Marx @date 1990-01
78 SUBROUTINE w3fi65(LOCRPT,COCBUF)
79C
80 CHARACTER*12 HOLD
81 CHARACTER*10 COCBUF(*),FILL
82 CHARACTER*7 CNINES
83 CHARACTER*4 COCRPT(10000)
84 CHARACTER*2 KAT(11)
85C
86 INTEGER LOCRPT(*),KATL(11),KATO(11),KATGC(20,11),KATGL(20,11),
87 $ MOCRPT(5000),KATLL(11)
88C
89 REAL ROCRPT(5000)
90C
91 equivalence(rocrpt,mocrpt,cocrpt)
92C
93 SAVE
94C
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/
107C
108 entry w3ai03(locrpt,cocbuf)
109C
110 IF (lwflag.EQ.0) THEN
111C FIRST TIME CALLED, DETERMINE MACHINE WORD LG IN BYTES (=8 FOR CRAY)
112C DEPENDING ON WORD SIZE LW2*I-LW1 INDEXES THRU COCRPT
113C EITHER AS 1,2,3...I FOR LW = 4 OR
114C AS 1,3,5..2*I-1 FOR LW = 8 <------ HERE
115C 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
124C 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
134cvvvvvy2k
135cdak MBYTES = LW * ((MI - 1) + (LVLS * KATLL(KK)))
136 mwords = (mi - 1) + (lvls * katll(kk))
137C TRANSFER LOCRPT TO MOCRPT IN ORDER TO EQUIVALENCE TO REAL AND CHAR.
138cdak CALL XMOVEX(MOCRPT,LOCRPT,MBYTES)
139 mocrpt(1:mwords) = locrpt(1:mwords)
140caaaaay2k
141C 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'
146C READ IN LATITUDE FROM WORD 1 (REAL)
147C 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
154C READ IN LONGITUDE FROM WORD 2 (REAL)
155C 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
161C READ IN STATION ID FROM WORDS 11 AND 12 (C*8)
162C (CHAR. 1-4 OF ID IN WORD 11, CHAR. 5-6 OF ID IN WORD 12, LEFT-JUSTIF.)
163C 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)
168C READ IN OBSERVATION TIME FROM WORD 4 (REAL)
169C 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))
172C READ IN RESERVED CHARACTERS FROM WORDS 5 AND 6 (C*8)
173C (4 CHAR., LEFT-JUSTIF.)
174C 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)
179C READ IN OFFICE NOTE 29 REPORT TYPE FROM WORD 9 (INTEGER)
180C 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)
183C READ IN STATION ELEVATION FROM WORD 7 (REAL)
184C 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
191C READ IN INSTRUMENT TYPE FROM WORD 8 (INTEGER)
192C 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
197CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
198C LOOP THROUGH ALL THE CATEGORIES WHICH HAVE VALID DATA
199CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
200 DO 3000 ncat = 1,11
201C 'M' IS THE WORD IN MOCRPT WHERE THE NO. OF LEVELS IS READ FROM
202 m = kato(ncat)
203 lvls = mocrpt(m)
204C '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
207C CATEGORY WITH VALID CATEGORY ENCOUNTERED - WRITE OUT IN FIRST 2
208C CHARACTERS OF CATEGORY/COUNTER GROUP FOR THIS CATEGORY (C*2)
209 cocbuf(n)(1:2) = kat(ncat)
210C 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
214C NWDSC COUNTS THE NUMBER OF 10-CHAR. WORDS IN THIS CATEGORY
215 nwdsc = 1
216 i = 1
217C***********************************************************************
218C LOOP THROUGH ALL THE LEVELS IN THE CURRENT CATEGORY
219C***********************************************************************
220 DO 2000 l = 1,lvls
221C NDG IS NO. OF INPUT PARAMETERS PER LEVEL IN THIS CATEGORY
222 ndg = katl(ncat)
223C-----------------------------------------------------------------------
224C LOOP THROUGH ALL THE PARAMETERS IN THE CURRENT LEVEL
225C-----------------------------------------------------------------------
226 DO 1800 k = 1,ndg
227C 'LL' IS THE NUMBER OF OUTPUT CHARACTERS PER PARAMETER FOR THIS CAT.
228 ll = katgl(k,ncat)
229C KATGC IS AN INDICATOR FOR THE INPUT FORMAT OF EACH OUTPUT PARAMETER
230C (=2 - REAL, =1 - INTEGER, =4 - CHARACTER*8)
231 IF(katgc(k,ncat).EQ.4) GO TO 1500
232C 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)
236C 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)
243C 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))
250C INITIALIZE ALL OUTPUT PARAMETERS HERE AS MISSING
251C (WILL REMAIN MISSING IF "IVALUE" SOMEHOW WOULD FILL-UP TOO
252C MANY CHARACTERS)
253 hold(1:ll) = cnines(1:ll)
254 IF(ll.EQ.1) THEN
255C 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
259C 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
265C 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
271C 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
277C 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
283C 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
289C 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
297C.......................................................................
298C INPUT CHARACTER (MARKER) PROCESSING COMES HERE
299 IF(ll.LE.4) THEN
300C THERE ARE BETWEEN ONE AND FOUR MARKERS IN OUTPUT PARAMETER
301 hold(1:ll) = cocrpt(lw2*mi-lw1)(1:ll)
302 ELSE
303C 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
308C 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
314C GET FOUR REMAINING MARKERS FROM NEXT INPUT WORD
315 hold(ip:jp) = cocrpt(lw2*mi-lw1)(1:4)
316 ELSE
317C 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
321C.......................................................................
322 1750 CONTINUE
323C 'I' IS POINTER FOR BEGINNING BYTE IN C*10 WORD FOR OUTPUT PARAMETER
324C 'J' IS POINTER FOR ENDING BYTE IN C*10 WORD FOR OUTPUT PARAMETER
325 j = i + ll - 1
326 IF(j.GT.10) THEN
327C 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
342C GO ON TO NEXT INPUT WORD IN THIS LEVEL
343 mi = mi + 1
344 1800 CONTINUE
345C-----------------------------------------------------------------------
346 2000 CONTINUE
347C***********************************************************************
348C 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)
350C TOTAL NO. CHARACTERS IN CATEGORY (EXCL. FILLS) (NCHAR) WRITTEN OUT TO
351C 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
355C RELATIVE POSITION IN REPORT OF NEXT CAT/CNTR GROUP (N) WRITTEN OUT TO
356C CHAR. 3 - 5 OF CURRENT CATEGORY/COUNTER GROUP (C*3)
357 WRITE(cocbuf(nc)(3:5),30) n
358C GO ON TO THE NEXT CATEGORY
359 3000 CONTINUE
360CXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
361C WRITE OUT THE TOTAL LENGTH OF THE REPORT -- NO. OF 10-CHARACTER WORDS
362C -- (N) IN LAST THREE CHARACTERS OF WORD 4 (C*3)
363 WRITE(cocbuf(no)(8:10),30) n
364C 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