1 | program iowrf |
---|
2 | ! Program to read/write wrf output. |
---|
3 | ! OPTION -thin : It will thin data to the ratio given |
---|
4 | ! OPTION -thina : It will average the fields over a user-specified grid area. |
---|
5 | ! OPTION -A : De-stagger data |
---|
6 | ! OPTION -box : Will get data from a user defined box |
---|
7 | ! Updated: January 8, 2008 |
---|
8 | ! Add de-staggering option |
---|
9 | ! Updated: Jun 19, 2007 |
---|
10 | ! Change time to unlimted on output |
---|
11 | ! Origincal code: |
---|
12 | ! Cindy Bruyere - March 2006 |
---|
13 | ! Some code borrowed from Jim Bresch |
---|
14 | !=================================Run Program================================ |
---|
15 | ! To extract a box from your input file |
---|
16 | ! iowrf wrfout_file -box x 10 50 y 10 60 [-debug] |
---|
17 | ! |
---|
18 | ! To thin your input file down (by picking up corresponding points) |
---|
19 | ! iowrf wrfout_file -thin 3 [-debug] |
---|
20 | ! |
---|
21 | ! To thin your input file down (by averaging) |
---|
22 | ! iowrf wrfout_file -thina 3 [-debug] |
---|
23 | ! |
---|
24 | ! To de-stagger the data |
---|
25 | ! iowrf wrfout_file -A |
---|
26 | ! |
---|
27 | ! To CREATE large 64bit data files |
---|
28 | ! -64bit |
---|
29 | ! |
---|
30 | ! To see more options |
---|
31 | ! iowrf -help |
---|
32 | ! |
---|
33 | ! The output will be written to a file with original file name + -box/-thin/-thina/-A |
---|
34 | ! |
---|
35 | !=================================Make Executable============================ |
---|
36 | ! Make executable: |
---|
37 | ! DEC Alpha |
---|
38 | ! f90 iowrf.f -L/usr/local/netcdf/lib -lnetcdf -lm \ |
---|
39 | ! -I/usr/local/netcdf/include -free -o iowrf |
---|
40 | ! |
---|
41 | ! linux flags |
---|
42 | ! pgf90 iowrf.f -L/usr/local/netcdf/lib -lnetcdf -lm \ |
---|
43 | ! -I/usr/local/netcdf/include -Mfree -o iowrf |
---|
44 | ! |
---|
45 | ! Sun flags |
---|
46 | ! f90 iowrf.f -L/usr/local/netcdf/lib -lnetcdf -lm \ |
---|
47 | ! -I/usr/local/netcdf/include -free -o iowrf |
---|
48 | ! |
---|
49 | ! SGI flags |
---|
50 | ! f90 iowrf.f -L/usr/local/netcdf/lib -lnetcdf -lm \ |
---|
51 | ! -I/usr/local/netcdf/include -freeform -o iowrf |
---|
52 | ! |
---|
53 | ! IBM flags (NCAR bluesky - 32bit) |
---|
54 | ! xlf iowrf.f -L/usr/local/lib32/r4i4 -lnetcdf -lm \ |
---|
55 | ! -I/usr/local/include -qfree=f90 -o iowrf |
---|
56 | ! |
---|
57 | ! IBM flags (NCAR bluesky - 64bit) |
---|
58 | ! xlf iowrf.f -L/usr/local/lib64/r4i4 -lnetcdf -lm \ |
---|
59 | ! -I/usr/local/include -qfree=f90 -o iowrf |
---|
60 | ! |
---|
61 | ! IBM flags (NCAR bluevista) |
---|
62 | ! xlf iowrf.f -L/usr/local/netcdf/lib -lnetcdf -lm \ |
---|
63 | ! -I/usr/local/netcdf/include -qfree=f90 -o iowrf |
---|
64 | ! |
---|
65 | ! Mac flags (with xlf compiler) |
---|
66 | ! xlf iowrf.f -L/usr/local/netcdf-xlf/lib -lnetcdf -lm \ |
---|
67 | ! -I/usr/local/netcdf-xlf/include -qfree=f90 -o iowrf |
---|
68 | ! |
---|
69 | ! Mac flags (with g95 compiler) |
---|
70 | ! g95 iowrf.f -L/usr/local/netcdf/lib -lnetcdf -lm \ |
---|
71 | ! -I/usr/local/netcdf/include -ffree-form -o iowrf |
---|
72 | ! |
---|
73 | !============================================================================ |
---|
74 | |
---|
75 | implicit none |
---|
76 | INCLUDE 'netcdf.inc' |
---|
77 | integer :: jdim |
---|
78 | parameter (jdim=6) |
---|
79 | integer ncid, status |
---|
80 | integer ishape(jdim) |
---|
81 | integer ishape2(jdim) |
---|
82 | character cval*50 |
---|
83 | character name*31 |
---|
84 | character (len=31),allocatable, dimension(:) :: dname |
---|
85 | integer, allocatable, dimension(:) :: dval, dval2 |
---|
86 | real, allocatable, dimension(:,:,:,:) :: data, data2 |
---|
87 | double precision, allocatable, dimension(:,:,:,:) :: ddata, ddata2 |
---|
88 | integer, allocatable, dimension(:,:,:,:) :: idata, idata2 |
---|
89 | character, allocatable, dimension(:,:,:,:) :: text |
---|
90 | character omit(10)*80 |
---|
91 | integer :: start_dims(4) |
---|
92 | integer :: dims_in(4), dims_out(4), box_start(3), box_end(3) |
---|
93 | integer :: firstS,firstE, secondS,secondE, thirdS,thirdE |
---|
94 | integer :: idm, ndims, nvars, natt, ngatts, nunlimdimid, iratio |
---|
95 | integer :: i, ii, j, iweg, jweg, isng, jsng, ibtg, jbtg, ix, iy |
---|
96 | integer :: i_shape_we, i_shape_sn, i_shape_bt |
---|
97 | integer :: i_shape_we_stag, i_shape_sn_stag, i_shape_bt_stag |
---|
98 | integer :: ilen, itype, ival, na |
---|
99 | integer :: mcid |
---|
100 | real :: dx, rval |
---|
101 | real :: new_cen |
---|
102 | real :: okm |
---|
103 | character (len=80) :: input_file, output_file |
---|
104 | character (len=10) :: option |
---|
105 | logical :: debug=.FALSE. |
---|
106 | logical :: x_ave=.FALSE. |
---|
107 | logical :: y_ave=.FALSE. |
---|
108 | logical :: bit64 |
---|
109 | |
---|
110 | call read_args(input_file,option,iratio,box_start,box_end,bit64,debug) |
---|
111 | output_file = trim(input_file)//option |
---|
112 | |
---|
113 | write(6,*) |
---|
114 | write(6,*) "#########################################" |
---|
115 | write(6,*) "Running IOWRF " |
---|
116 | write(6,*) |
---|
117 | write(6,*) "INPUT FILE: ",trim(input_file) |
---|
118 | write(6,*) "OUTPUT FILE: ",trim(output_file) |
---|
119 | write(6,*) "OPTION: ",option |
---|
120 | |
---|
121 | IF (debug) THEN |
---|
122 | if ( option(1:5) == '-thin' ) then ! used for -thina and -thin |
---|
123 | write(6,*) "RATIO: ",iratio |
---|
124 | elseif ( option == '-box' )then |
---|
125 | write(6,*) "BOX START (x y z): ",box_start |
---|
126 | write(6,*) "BOX END (x y z): ",box_end |
---|
127 | endif |
---|
128 | ENDIF |
---|
129 | |
---|
130 | |
---|
131 | ! OPEN INPUT AND OUTPUT FILE |
---|
132 | ! output_file is input_file_new |
---|
133 | status = nf_open(input_file, 0, ncid) |
---|
134 | if (status .ne. nf_noerr) call handle_err(status) |
---|
135 | if (bit64) then |
---|
136 | status = nf_create(output_file, NF_64BIT_OFFSET, mcid) |
---|
137 | else |
---|
138 | status = nf_create(output_file, 0, mcid) |
---|
139 | endif |
---|
140 | if (status .ne. nf_noerr) call handle_err(status) |
---|
141 | |
---|
142 | ! GET BASIC INFORMTION ABOUT THE FILE |
---|
143 | ! most important |
---|
144 | ! ndims: number of dimensions |
---|
145 | ! nvars: number of variables |
---|
146 | ! ngatts: number of global attributes |
---|
147 | status = nf_inq(ncid, ndims, nvars, ngatts, nunlimdimid) |
---|
148 | if (status .ne. nf_noerr) call handle_err(status) |
---|
149 | IF (debug) THEN |
---|
150 | write(6,*) |
---|
151 | write(6,'(4(A,i4))') ' ndims = ',ndims,' nvars = ',nvars,' ngatts = ',ngatts, & |
---|
152 | ' nunlimdimid =',nunlimdimid |
---|
153 | write(6,*) |
---|
154 | ENDIF |
---|
155 | |
---|
156 | ! ALLOCATE SOME VARIABLES |
---|
157 | allocate (dval(ndims)) |
---|
158 | allocate(dval2(ndims)) |
---|
159 | allocate(dname(ndims)) |
---|
160 | |
---|
161 | ! GET SOME BASIC DIMS FROM INPUT_FILE |
---|
162 | dx = -99. |
---|
163 | status = nf_get_att_real (ncid, nf_global, 'DX', dx) |
---|
164 | status = nf_get_att_int (ncid, nf_global, 'WEST-EAST_GRID_DIMENSION', iweg) |
---|
165 | status = nf_get_att_int (ncid, nf_global, 'SOUTH-NORTH_GRID_DIMENSION', isng) |
---|
166 | status = nf_get_att_int (ncid, nf_global, 'BOTTOM-TOP_GRID_DIMENSION', ibtg) |
---|
167 | IF (debug) THEN |
---|
168 | write(6,*) "BASICS from input file:" |
---|
169 | write(6,*) " DX= ", dx |
---|
170 | write(6,*) " X= ", iweg |
---|
171 | write(6,*) " Y= ", isng |
---|
172 | write(6,*) " Z= ", ibtg |
---|
173 | ENDIF |
---|
174 | if (dx .lt. 0.) stop 'dx is bad' |
---|
175 | |
---|
176 | ! CALCULATE DIMS FOR OUTPUT FILE |
---|
177 | IF ( option(1:5) == '-thin' ) THEN ! used for -thina and -thin |
---|
178 | okm = dx*iratio |
---|
179 | jweg = int((iweg-1)/iratio) + 1 |
---|
180 | jsng = int((isng-1)/iratio) + 1 |
---|
181 | jbtg = ibtg |
---|
182 | ELSEIF ( option == '-box' ) THEN |
---|
183 | okm = dx |
---|
184 | jweg = iweg |
---|
185 | jsng = isng |
---|
186 | jbtg = ibtg |
---|
187 | if ( box_end(1) .ne. 0 ) jweg = int(box_end(1) - box_start(1)) + 1 |
---|
188 | if ( box_end(2) .ne. 0 ) jsng = int(box_end(2) - box_start(2)) + 1 |
---|
189 | if ( box_end(3) .ne. 0 ) jbtg = int(box_end(3) - box_start(3)) + 1 |
---|
190 | ELSE |
---|
191 | okm = dx |
---|
192 | jweg = iweg |
---|
193 | jsng = isng |
---|
194 | jbtg = ibtg |
---|
195 | ENDIF |
---|
196 | IF (debug) THEN |
---|
197 | write(6,*) "BASICS for output file:" |
---|
198 | write(6,*) " DX= ", okm |
---|
199 | write(6,*) " X= ", jweg |
---|
200 | write(6,*) " Y= ", jsng |
---|
201 | write(6,*) " Z= ", jbtg |
---|
202 | ENDIF |
---|
203 | !! We also need to fix the CEN_LAT and CEN_LON later, so get |
---|
204 | !! the middle of the new domain |
---|
205 | ix = int((jweg-1)/2.) |
---|
206 | iy = int((jsng-1)/2.) |
---|
207 | if ( ix .eq. int(jweg/2.) ) x_ave = .TRUE. |
---|
208 | if ( iy .eq. int(jsng/2.) ) y_ave = .TRUE. |
---|
209 | ix = int(jweg/2.) |
---|
210 | iy = int(jsng/2.) |
---|
211 | |
---|
212 | ! READ ALL DIMS FROM INPUT FILE AND CREATE DIMS FOR OUTPUT FILE |
---|
213 | IF (debug) THEN |
---|
214 | write(6,*) |
---|
215 | write(6,*) "FILE dimensions:" |
---|
216 | ENDIF |
---|
217 | i_shape_we = 0 |
---|
218 | i_shape_sn = 0 |
---|
219 | i_shape_bt = 0 |
---|
220 | i_shape_we_stag = 0 |
---|
221 | i_shape_sn_stag = 0 |
---|
222 | i_shape_bt_stag = 0 |
---|
223 | |
---|
224 | do i = 1, ndims |
---|
225 | status = nf_inq_dim(ncid, i, dname(i), dval(i)) |
---|
226 | dval2(i) = dval(i) |
---|
227 | ! CAUTION -- this stuff is hard-wired |
---|
228 | if (dname(i) .eq. 'west_east_stag') then |
---|
229 | dval2(i) = jweg |
---|
230 | i_shape_we_stag = i |
---|
231 | else if (dname(i) .eq. 'west_east') then |
---|
232 | dval2(i) = jweg-1 |
---|
233 | i_shape_we = i |
---|
234 | else if (dname(i) .eq. 'south_north_stag') then |
---|
235 | dval2(i) = jsng |
---|
236 | i_shape_sn_stag = i |
---|
237 | else if (dname(i) .eq. 'south_north') then |
---|
238 | dval2(i) = jsng-1 |
---|
239 | i_shape_sn = i |
---|
240 | else if (dname(i) .eq. 'bottom_top_stag') then |
---|
241 | dval2(i) = jbtg |
---|
242 | i_shape_bt_stag = i |
---|
243 | else if (dname(i) .eq. 'bottom_top') then |
---|
244 | dval2(i) = jbtg-1 |
---|
245 | i_shape_bt = i |
---|
246 | endif |
---|
247 | if ( dname(i) == "Time" ) then |
---|
248 | status = nf_def_dim(mcid, dname(i), NF_UNLIMITED, i) |
---|
249 | else |
---|
250 | status = nf_def_dim(mcid, dname(i), dval2(i), i) |
---|
251 | end if |
---|
252 | IF (debug) THEN |
---|
253 | write(6,'(i4," : ",A," in = ",i4," (out = ",i4,")")') & |
---|
254 | i,dname(i),dval(i),dval2(i) |
---|
255 | ENDIF |
---|
256 | enddo |
---|
257 | IF (.not. debug) THEN |
---|
258 | write(6,*) |
---|
259 | write(6,*) "Set up file DIMENSIONS" |
---|
260 | ENDIF |
---|
261 | |
---|
262 | ! DEALING WITH THE GLOBAL ATTRIBUTES |
---|
263 | IF (debug) THEN |
---|
264 | write(6,*) |
---|
265 | write(6,*) "FILE attributes:" |
---|
266 | ENDIF |
---|
267 | do i = 1, ngatts |
---|
268 | status = nf_inq_attname(ncid, nf_global, i, name) |
---|
269 | status = nf_inq_atttype(ncid, nf_global, name, itype) |
---|
270 | status = nf_inq_attlen(ncid, nf_global, name, ilen) |
---|
271 | |
---|
272 | if ( itype .eq. 2 ) then ! characters |
---|
273 | status = nf_get_att_text (ncid, nf_global, name, cval) |
---|
274 | IF (debug) THEN |
---|
275 | write(6,'(i4," : ",A," in = ",A," (out = ",$)') & |
---|
276 | i,name,cval(1:ilen) |
---|
277 | ENDIF |
---|
278 | if(name(1:5) .eq. 'TITLE') then |
---|
279 | cval = cval(1:ilen)//" : iowrf"//option |
---|
280 | ilen = len_trim(cval) |
---|
281 | endif |
---|
282 | IF (debug) write(6,'(A,")")') cval(1:ilen) |
---|
283 | status = nf_put_att_text(mcid, nf_global, name, ilen,& |
---|
284 | cval(1:ilen)) |
---|
285 | |
---|
286 | elseif ( itype .eq. 4 ) then ! integers |
---|
287 | status = nf_get_att_int (ncid, nf_global, name, ival) |
---|
288 | IF (debug) THEN |
---|
289 | write(6,'(i4," : ",A," in = ",i7," (out = ",$)') & |
---|
290 | i,name,ival |
---|
291 | ENDIF |
---|
292 | if(name .eq. 'WEST-EAST_GRID_DIMENSION') ival = jweg |
---|
293 | if(name .eq. 'SOUTH-NORTH_GRID_DIMENSION') ival = jsng |
---|
294 | if(name .eq. 'BOTTOM-TOP_GRID_DIMENSION') ival = jbtg |
---|
295 | IF (debug) write(6,'(i7,")")') ival |
---|
296 | status = nf_put_att_int(mcid, nf_global, name, itype,& |
---|
297 | ilen, ival) |
---|
298 | |
---|
299 | elseif ( itype .eq. 5 ) then ! real |
---|
300 | status = nf_get_att_real (ncid, nf_global, name, rval) |
---|
301 | IF (debug) THEN |
---|
302 | write(6,'(i4," : ",A," in = ",G18.10E2," (out = ",$)') & |
---|
303 | i,name,rval |
---|
304 | ENDIF |
---|
305 | if(name(1:2) .eq. 'DX' .or. name(1:2) .eq. 'DY') rval = okm |
---|
306 | IF (debug) write(6,'(G18.10E2,")")') rval |
---|
307 | status = nf_put_att_real(mcid, nf_global, name, itype,& |
---|
308 | ilen, rval) |
---|
309 | endif |
---|
310 | enddo |
---|
311 | IF ( .not. debug ) THEN |
---|
312 | write(6,*) "Write file ATTRIBUTES" |
---|
313 | write(6,*) |
---|
314 | ENDIF |
---|
315 | |
---|
316 | |
---|
317 | ! TRAIN FILE |
---|
318 | do i = 1, nvars |
---|
319 | status = nf_inq_var(ncid, i, cval, itype, idm, ishape, natt) |
---|
320 | ishape2 = ishape |
---|
321 | if ( idm .ge. 4 ) then |
---|
322 | do ii=1,idm |
---|
323 | IF ( option == "-A" .AND. ishape2(ii) == i_shape_bt_stag ) THEN |
---|
324 | ishape2(ii) = i_shape_bt |
---|
325 | ELSEIF ( option == "-A" .AND. ishape2(ii) == i_shape_we_stag ) THEN |
---|
326 | ishape2(ii) = i_shape_we |
---|
327 | ELSEIF ( option == "-A" .AND. ishape2(ii) == i_shape_sn_stag ) THEN |
---|
328 | ishape2(ii) = i_shape_sn |
---|
329 | END IF |
---|
330 | enddo |
---|
331 | end if |
---|
332 | |
---|
333 | status = nf_def_var(mcid, cval, itype, idm, ishape2, i) |
---|
334 | do na = 1, natt |
---|
335 | status = nf_inq_attname(ncid, i, na, name) |
---|
336 | status = nf_copy_att(ncid, i, name, mcid, i) |
---|
337 | enddo |
---|
338 | enddo |
---|
339 | status = nf_enddef(mcid) |
---|
340 | |
---|
341 | ! ########## LOOP THROUGH THE DATA |
---|
342 | IF (debug) THEN |
---|
343 | write(6,*) |
---|
344 | write(6,*) |
---|
345 | ENDIF |
---|
346 | write(6,*) "Write file VARIABLES:" |
---|
347 | start_dims = 1 |
---|
348 | do i = 1, nvars |
---|
349 | status = nf_inq_var(ncid, i, cval, itype, idm, ishape, natt) |
---|
350 | ishape2 = ishape |
---|
351 | if ( idm .ge. 4 ) then |
---|
352 | do ii=1,idm |
---|
353 | IF ( option == "-A" .AND. ishape2(ii) == i_shape_bt_stag ) THEN |
---|
354 | ishape2(ii) = i_shape_bt |
---|
355 | ELSEIF ( option == "-A" .AND. ishape2(ii) == i_shape_we_stag ) THEN |
---|
356 | ishape2(ii) = i_shape_we |
---|
357 | ELSEIF ( option == "-A" .AND. ishape2(ii) == i_shape_sn_stag ) THEN |
---|
358 | ishape2(ii) = i_shape_sn |
---|
359 | END IF |
---|
360 | enddo |
---|
361 | end if |
---|
362 | IF (debug) THEN |
---|
363 | write(6,*) |
---|
364 | ENDIF |
---|
365 | write(6,*) 'VARIABLE: ',trim(cval) |
---|
366 | |
---|
367 | ! GET THE DIMS FOR INPUT AND OUTPUT FROM THE SHAPE |
---|
368 | dims_in = 1 |
---|
369 | dims_out = 1 |
---|
370 | do ii = 1,idm |
---|
371 | dims_in(ii) = dval(ishape(ii)) |
---|
372 | dims_out(ii) = dval2(ishape2(ii)) |
---|
373 | enddo |
---|
374 | IF (debug) THEN |
---|
375 | write(6,*) ' DIMS IN: ',dims_in |
---|
376 | write(6,*) ' DIMS OUT: ',dims_out |
---|
377 | ENDIF |
---|
378 | |
---|
379 | IF ( option == '-box' ) THEN |
---|
380 | !! Get the start and end dimensions of the box in the input file |
---|
381 | firstS = 1 |
---|
382 | firstE = dims_out(1) |
---|
383 | secondS = 1 |
---|
384 | secondE = dims_out(2) |
---|
385 | thirdS = 1 |
---|
386 | thirdE = dims_out(3) |
---|
387 | |
---|
388 | if (idm.eq.2 .and. dims_out(1).ge.jbtg-1 .and. box_end(3).ne.0) then |
---|
389 | firstS = box_start(3) |
---|
390 | firstE = box_end(3) |
---|
391 | if (dims_out(3) .eq. jbtg-1) firstE = firstE-1 |
---|
392 | endif |
---|
393 | if (idm .ge. 3) then |
---|
394 | if (box_end(1) .ne. 0) then |
---|
395 | firstS = box_start(1) |
---|
396 | firstE = box_end(1) |
---|
397 | if (dims_out(1) .eq. jweg-1) firstE = firstE-1 |
---|
398 | endif |
---|
399 | if (box_end(2) .ne. 0) then |
---|
400 | secondS = box_start(2) |
---|
401 | secondE = box_end(2) |
---|
402 | if (dims_out(2) .eq. jsng-1) secondE = secondE-1 |
---|
403 | endif |
---|
404 | if (idm == 4 .and. box_end(3).ne.0) then |
---|
405 | thirdS = box_start(3) |
---|
406 | thirdE = box_end(3) |
---|
407 | if (dims_out(3) .eq. jbtg-1) thirdE = thirdE-1 |
---|
408 | endif |
---|
409 | endif |
---|
410 | ENDIF |
---|
411 | |
---|
412 | ! ALLOCATE THE INPUT AND OUTPUT ARRAYS |
---|
413 | ! READ THE DATA FROM INPUT FILE |
---|
414 | ! THIN THE GRID IF NEEDED, OR GET THE CORRECT BOX |
---|
415 | |
---|
416 | IF (itype .eq. 2) THEN ! character |
---|
417 | allocate (text(dims_in(1), dims_in(2), dims_in(3), & |
---|
418 | dims_in(4))) |
---|
419 | status = nf_get_var_text(ncid, i, text) |
---|
420 | IF (debug) write(6,*) ' SAMPLE VALUE = ',text(:,1,1,1) |
---|
421 | status = nf_put_vara_text (mcid, i, start_dims, dims_in, text) |
---|
422 | deallocate (text) |
---|
423 | |
---|
424 | ELSEIF (itype .eq. 4) THEN ! integer |
---|
425 | allocate (idata(dims_in(1), dims_in(2), dims_in(3), & |
---|
426 | dims_in(4))) |
---|
427 | allocate(idata2(dims_out(1),dims_out(2),dims_out(3),& |
---|
428 | dims_out(4))) |
---|
429 | status = nf_get_var_int(ncid, i, idata) |
---|
430 | IF (debug) write(6,*) ' SAMPLE VALUE = ',idata(1,1,1,1) |
---|
431 | IF ( option == '-thina' ) THEN |
---|
432 | if (idm .ge. 3) then |
---|
433 | IF (debug) write(6,*) ' Grid is thinned with a ratio of ',iratio |
---|
434 | allocate(data2(dims_out(1),dims_out(2),dims_out(3),& |
---|
435 | dims_out(4))) |
---|
436 | call thin_ave (real(idata),data2,dims_in(1),dims_in(2), & |
---|
437 | dims_in(3),dims_in(4),dims_out(1),dims_out(2), & |
---|
438 | dims_out(3),dims_out(4),iratio) |
---|
439 | idata2 = int(data2) |
---|
440 | deallocate(data2) |
---|
441 | else |
---|
442 | idata2 = idata |
---|
443 | endif |
---|
444 | ELSEIF ( option == '-thin' ) THEN |
---|
445 | if (idm .ge. 3) then |
---|
446 | IF (debug) write(6,*) ' Grid is thinned with a ratio of ',iratio |
---|
447 | idata2 = idata(1:dims_in(1):iratio,1:dims_in(2):iratio,:,:) |
---|
448 | else |
---|
449 | idata2 = idata |
---|
450 | endif |
---|
451 | ELSEIF ( option == '-A' ) THEN |
---|
452 | idata2 = idata |
---|
453 | ELSEIF ( option == '-box') THEN |
---|
454 | IF (debug) write(6,*) ' a BOX is extracted from the input domain ' |
---|
455 | idata2 = idata(firstS:firstE,secondS:secondE,thirdS:thirdE,:) |
---|
456 | ENDIF |
---|
457 | status = nf_put_vara_int (mcid, i, start_dims, dims_out, idata2) |
---|
458 | deallocate (idata) |
---|
459 | deallocate (idata2) |
---|
460 | |
---|
461 | ELSEIF (itype .eq. 5) THEN ! real |
---|
462 | allocate (data(dims_in(1), dims_in(2), dims_in(3), & |
---|
463 | dims_in(4))) |
---|
464 | allocate(data2(dims_out(1),dims_out(2),dims_out(3), & |
---|
465 | dims_out(4))) |
---|
466 | status = nf_get_var_real(ncid, i, data) |
---|
467 | IF (debug) write(6,*) ' SAMPLE VALUE = ',data(1,1,1,1) |
---|
468 | IF ( option == '-thina' ) THEN |
---|
469 | if (idm .ge. 3) then |
---|
470 | IF (debug) write(6,*) ' Grid is thinned with a ratio of ',iratio |
---|
471 | call thin_ave (data,data2,dims_in(1),dims_in(2), & |
---|
472 | dims_in(3),dims_in(4),dims_out(1),dims_out(2), & |
---|
473 | dims_out(3),dims_out(4),iratio) |
---|
474 | else |
---|
475 | data2 = data |
---|
476 | endif |
---|
477 | ELSEIF ( option == '-thin' ) THEN |
---|
478 | if (idm .ge. 3) then |
---|
479 | IF (debug) write(6,*) ' Grid is thinned with a ratio of ',iratio |
---|
480 | data2 = data(1:dims_in(1):iratio,1:dims_in(2):iratio,:,:) |
---|
481 | else |
---|
482 | data2 = data |
---|
483 | endif |
---|
484 | ELSEIF ( option == '-A' ) THEN |
---|
485 | if (idm .eq. 4 .AND. (dims_in(1) > dims_out(1)) ) then |
---|
486 | IF (debug) write(6,*) ' de-staggering in the X direction' |
---|
487 | data2 = (data(1:dims_in(1)-1,:,:,:)+data(2:dims_in(1),:,:,:))*.5 |
---|
488 | elseif (idm .eq. 4 .AND. (dims_in(2) > dims_out(2)) ) then |
---|
489 | IF (debug) write(6,*) ' de-staggering in the Y direction' |
---|
490 | data2 = (data(:,1:dims_in(2)-1,:,:)+data(:,2:dims_in(2),:,:))*.5 |
---|
491 | elseif (idm .eq. 4 .AND. (dims_in(3) > dims_out(3)) ) then |
---|
492 | IF (debug) write(6,*) ' de-staggering in the Y direction' |
---|
493 | data2 = (data(:,:,1:dims_in(3)-1,:)+data(:,:,3:dims_in(2),:))*.5 |
---|
494 | else |
---|
495 | data2 = data |
---|
496 | endif |
---|
497 | ELSEIF ( option == '-box') THEN |
---|
498 | IF (debug) write(6,*) ' a BOX is extracted from the input domain ' |
---|
499 | data2 = data(firstS:firstE,secondS:secondE,thirdS:thirdE,:) |
---|
500 | ENDIF |
---|
501 | status = nf_put_vara_real (mcid, i, start_dims, dims_out, data2) |
---|
502 | IF ( cval == 'XLAT' .or. cval == 'XLONG' ) THEN |
---|
503 | ! We need fix the box's center long and lat |
---|
504 | new_cen = data2(ix,iy,1,1) |
---|
505 | if ( x_ave .and. y_ave ) then |
---|
506 | new_cen = (data2(ix, iy,1,1)+data2(ix ,iy+1,1,1)+ & |
---|
507 | data2(ix+1,iy,1,1)+data2(ix+1,iy+1,1,1))/4. |
---|
508 | elseif ( x_ave .and. .not. y_ave ) then |
---|
509 | new_cen = (data2(ix, iy,1,1)+data2(ix+1,iy ,1,1))/2. |
---|
510 | elseif ( .not. x_ave .and. y_ave ) then |
---|
511 | new_cen = (data2(ix, iy,1,1)+data2(ix ,iy+1,1,1))/2. |
---|
512 | endif |
---|
513 | ENDIF |
---|
514 | IF ( cval == 'XLAT' ) THEN |
---|
515 | IF (debug) write(6,*) ' Fix global attribute CEN_LAT: now = ', new_cen |
---|
516 | status = nf_inq_atttype(ncid, nf_global, 'CEN_LAT', itype) |
---|
517 | status = nf_inq_attlen(ncid, nf_global, 'CEN_LAT', ilen) |
---|
518 | status = nf_put_att_real(mcid, nf_global, 'CEN_LAT', itype,& |
---|
519 | ilen, new_cen) |
---|
520 | ELSEIF ( cval == 'XLONG' ) THEN |
---|
521 | IF (debug) write(6,*) ' Fix global attribute CEN_LON: now = ', new_cen |
---|
522 | status = nf_inq_atttype(ncid, nf_global, 'CEN_LON', itype) |
---|
523 | status = nf_inq_attlen(ncid, nf_global, 'CEN_LON', ilen) |
---|
524 | status = nf_put_att_real(mcid, nf_global, 'CEN_LON', itype,& |
---|
525 | ilen, new_cen) |
---|
526 | ENDIF |
---|
527 | deallocate (data) |
---|
528 | deallocate (data2) |
---|
529 | |
---|
530 | ELSEIF (itype .eq. 6) THEN ! double |
---|
531 | allocate (ddata(dims_in(1), dims_in(2), dims_in(3), & |
---|
532 | dims_in(4))) |
---|
533 | allocate(ddata2(dims_out(1),dims_out(2),dims_out(3),& |
---|
534 | dims_out(4))) |
---|
535 | status = nf_get_var_double(ncid, i, ddata) |
---|
536 | IF (debug) write(6,*) ' SAMPLE VALUE = ',ddata(1,1,1,1) |
---|
537 | IF ( option == '-thina' ) THEN |
---|
538 | if (idm .ge. 3) then |
---|
539 | IF (debug) write(6,*) ' Grid is thinned with a ratio of ',iratio |
---|
540 | allocate(data2(dims_out(1),dims_out(2),dims_out(3),& |
---|
541 | dims_out(4))) |
---|
542 | call thin_ave (real(ddata),data2,dims_in(1),dims_in(2), & |
---|
543 | dims_in(3),dims_in(4),dims_out(1),dims_out(2), & |
---|
544 | dims_out(3),dims_out(4),iratio) |
---|
545 | ddata2 = data2 |
---|
546 | deallocate (data2) |
---|
547 | else |
---|
548 | ddata2 = ddata |
---|
549 | endif |
---|
550 | ELSEIF ( option == '-thin' ) THEN |
---|
551 | if (idm .ge. 3) then |
---|
552 | IF (debug) write(6,*) ' Grid is thinned with a ratio of ',iratio |
---|
553 | ddata2 = ddata(1:dims_in(1):iratio,1:dims_in(2):iratio,:,:) |
---|
554 | else |
---|
555 | ddata2 = ddata |
---|
556 | endif |
---|
557 | ELSEIF ( option == '-A' ) THEN |
---|
558 | if (idm .eq. 4 .AND. (dims_in(1) > dims_out(1)) ) then |
---|
559 | IF (debug) write(6,*) ' de-staggering in the X direction' |
---|
560 | ddata2 = (ddata(1:dims_in(1)-1,:,:,:)+ddata(2:dims_in(1),:,:,:))*.5 |
---|
561 | elseif (idm .eq. 4 .AND. (dims_in(2) > dims_out(2)) ) then |
---|
562 | IF (debug) write(6,*) ' de-staggering in the Y direction' |
---|
563 | ddata2 = (ddata(:,1:dims_in(2)-1,:,:)+ddata(:,2:dims_in(2),:,:))*.5 |
---|
564 | elseif (idm .eq. 4 .AND. (dims_in(3) > dims_out(3)) ) then |
---|
565 | IF (debug) write(6,*) ' de-staggering in the Z direction' |
---|
566 | ddata2 = (ddata(:,:,1:dims_in(3)-1,:)+ddata(:,:,3:dims_in(2),:))*.5 |
---|
567 | else |
---|
568 | ddata2 = ddata |
---|
569 | endif |
---|
570 | ELSEIF ( option == '-box') THEN |
---|
571 | IF (debug) write(6,*) ' a BOX is extracted from the input domain ' |
---|
572 | ddata2 = ddata(firstS:firstE,secondS:secondE,thirdS:thirdE,:) |
---|
573 | ENDIF |
---|
574 | status = nf_put_vara_double (mcid, i, start_dims, dims_out, ddata2) |
---|
575 | deallocate (ddata) |
---|
576 | deallocate (ddata2) |
---|
577 | ELSE |
---|
578 | stop 'trouble - do not know the variable type' |
---|
579 | ENDIF |
---|
580 | |
---|
581 | ENDDO ! END OF VARIABLE LOOP |
---|
582 | status = nf_close(mcid) |
---|
583 | |
---|
584 | write(6,*) |
---|
585 | write(6,*) "SUCCESS - we are out of here" |
---|
586 | write(6,*) "#########################################" |
---|
587 | |
---|
588 | end program iowrf |
---|
589 | !--------------------------------------------------------------------- |
---|
590 | subroutine handle_err(status) |
---|
591 | integer status |
---|
592 | write(6,*) 'Error number ',status |
---|
593 | stop |
---|
594 | end subroutine |
---|
595 | !--------------------------------------------------------------------- |
---|
596 | subroutine thin_ave (ain, aou, a1, a2, a3, a4, b1, b2, b3, b4, & |
---|
597 | iratio) |
---|
598 | ! average one array into another in x,y. |
---|
599 | integer a1, a2, a3, a4, b1, b2, b3, b4,iratio |
---|
600 | real ain(a1,a2,a3,a4), aou(b1,b2,b3,b4) |
---|
601 | !write(6,*) 'begin thin_ave, ratio = ',iratio |
---|
602 | !write(6,*) 'a1 = ',a1,' a2 = ',a2,' a3 = ',a3,' a4 = ',a4 |
---|
603 | !write(6,*) 'b1 = ',b1,' b2 = ',b2,' b3 = ',b3,' b4 = ',b4 |
---|
604 | do k4 = 1, b4 |
---|
605 | do k3 = 1, b3 |
---|
606 | do j = 1, b2 |
---|
607 | ymx = (((j-1) * iratio) + 1 ) + iratio/2. |
---|
608 | ymn = (((j-1) * iratio) + 1 ) - iratio/2. |
---|
609 | ymx = amin1(float(a2),ymx) |
---|
610 | ymn = amax1(1.,ymn) |
---|
611 | !write(6,*) 'ymn = ',ymn,' ymx = ',ymx |
---|
612 | do i = 1, b1 |
---|
613 | !write(6,*) 'i = ',i,' j = ',j |
---|
614 | xmx = (((i-1) * iratio) + 1 ) + iratio/2. |
---|
615 | xmn = (((i-1) * iratio) + 1 ) - iratio/2. |
---|
616 | xmx = amin1(float(a1),xmx) |
---|
617 | xmn = amax1(1.,xmn) |
---|
618 | !write(6,*) 'xmn = ',xmn,' xmx = ',xmx |
---|
619 | nc = 0 |
---|
620 | sum = 0. |
---|
621 | nn1 = int(ymn+.5) |
---|
622 | nn2 = int(ymx) |
---|
623 | do n = nn1, nn2 |
---|
624 | mm1 = int(xmn+.5) |
---|
625 | mm2 = int(xmx) |
---|
626 | !write(6,*) 'nn1 = ',nn1,' nn2 = ',nn2 |
---|
627 | !write(6,*) 'mm1 = ',mm1,' mm2 = ',mm2 |
---|
628 | do m = mm1, mm2 |
---|
629 | sum = ain(m,n,k3,k4) + sum |
---|
630 | !write(6,*) 'm = ',m,' n = ',n,' ain = ',ain(m,n,k3,k4),& |
---|
631 | ! ' sum = ',sum |
---|
632 | nc = nc + 1 |
---|
633 | enddo |
---|
634 | enddo |
---|
635 | aou(i,j,k3,k4) = sum/float(nc) |
---|
636 | !write(6,*) 'i = ',i,' value = ',aou(i,j,k3,k4) |
---|
637 | enddo |
---|
638 | enddo |
---|
639 | enddo |
---|
640 | enddo |
---|
641 | |
---|
642 | end subroutine thin_ave |
---|
643 | !-------------------------------------------------------- |
---|
644 | |
---|
645 | subroutine read_args(input_file,option,iratio,box_start,box_end,bit64,debug) |
---|
646 | |
---|
647 | implicit none |
---|
648 | character (len=80) :: input_file |
---|
649 | character (len=10) :: option |
---|
650 | |
---|
651 | integer :: iratio |
---|
652 | integer :: box_start(3), box_end(3) |
---|
653 | logical :: bit64, debug |
---|
654 | |
---|
655 | integer :: numarg, i, idummy, idummy1, idummy2 |
---|
656 | real :: rdummy |
---|
657 | integer, external :: iargc |
---|
658 | character (len=80) :: dummy, dir |
---|
659 | |
---|
660 | ! set up some defaults first |
---|
661 | input_file = " " |
---|
662 | option = " " |
---|
663 | idummy1 = 0 |
---|
664 | idummy2 = 0 |
---|
665 | box_start = 0 |
---|
666 | box_end = 0 |
---|
667 | bit64 = .FALSE. |
---|
668 | numarg = iargc() |
---|
669 | i = 1 |
---|
670 | |
---|
671 | if (numarg .lt. 1) call help_info |
---|
672 | |
---|
673 | do while (i <= numarg) |
---|
674 | call getarg(i,dummy) |
---|
675 | |
---|
676 | if (dummy(1:1) == "-") then ! We have an option, else it is the filename |
---|
677 | |
---|
678 | SELECTCASE (trim(dummy)) |
---|
679 | CASE ("-help") |
---|
680 | call help_info |
---|
681 | CASE ("-h") |
---|
682 | call help_info |
---|
683 | CASE ("-debug") |
---|
684 | debug = .TRUE. |
---|
685 | CASE ("-thina") |
---|
686 | option = dummy |
---|
687 | i = i+1 |
---|
688 | call getarg(i,dummy) |
---|
689 | read(dummy,'(i3)')idummy |
---|
690 | iratio = idummy |
---|
691 | if ( iratio .lt. 2 ) STOP ' Must supply a ratio of 2 or more ' |
---|
692 | CASE ("-thin") |
---|
693 | option = dummy |
---|
694 | i = i+1 |
---|
695 | call getarg(i,dummy) |
---|
696 | read(dummy,'(i3)')idummy |
---|
697 | iratio = idummy |
---|
698 | if ( iratio .lt. 2 ) STOP ' Must supply a ratio of 2 or more ' |
---|
699 | CASE ("-A") |
---|
700 | option = dummy |
---|
701 | CASE ("-box") |
---|
702 | option = dummy |
---|
703 | DO |
---|
704 | i = i+1 |
---|
705 | call getarg(i,dir) |
---|
706 | if (dir(1:1) == '-') then |
---|
707 | i=i-1 |
---|
708 | exit |
---|
709 | endif |
---|
710 | if (dir.ne.'x') then |
---|
711 | if (dir.ne.'y') then |
---|
712 | if (dir.ne.'z') then |
---|
713 | i=i-1 |
---|
714 | exit |
---|
715 | endif |
---|
716 | endif |
---|
717 | endif |
---|
718 | i = i+1 |
---|
719 | call getarg(i,dummy) |
---|
720 | read(dummy,'(i3)')idummy1 |
---|
721 | i = i+1 |
---|
722 | call getarg(i,dummy) |
---|
723 | read(dummy,'(i3)')idummy2 |
---|
724 | if (dir.eq.' '.or.idummy1.eq.0.or.idummy2.eq.0) exit |
---|
725 | if ( dir == 'x' ) then |
---|
726 | box_start(1) = idummy1 |
---|
727 | box_end(1) = idummy2 |
---|
728 | endif |
---|
729 | if ( dir == 'y' ) then |
---|
730 | box_start(2) = idummy1 |
---|
731 | box_end(2) = idummy2 |
---|
732 | endif |
---|
733 | if ( dir == 'z' ) then |
---|
734 | box_start(3) = idummy1 |
---|
735 | box_end(3) = idummy2 |
---|
736 | endif |
---|
737 | idummy1 = 0 |
---|
738 | idummy2 = 0 |
---|
739 | ENDDO |
---|
740 | CASE ("-64bit") |
---|
741 | bit64 = .TRUE. |
---|
742 | CASE DEFAULT |
---|
743 | call help_info |
---|
744 | END SELECT |
---|
745 | else |
---|
746 | input_file = dummy |
---|
747 | endif |
---|
748 | |
---|
749 | i = i+1 |
---|
750 | |
---|
751 | enddo |
---|
752 | |
---|
753 | if (input_file == " ") call help_info |
---|
754 | |
---|
755 | end subroutine read_args |
---|
756 | !------------------------------------------------------------------------------ |
---|
757 | |
---|
758 | subroutine help_info |
---|
759 | |
---|
760 | print*," " |
---|
761 | print*," iowrf wrf_data_file_name [-options] " |
---|
762 | print*," " |
---|
763 | print*," Current options available are:" |
---|
764 | print*," -help : Print this information" |
---|
765 | print*," -h : Print this information" |
---|
766 | print*," " |
---|
767 | print*," -thina x : Thin the input grid, with a ratio of x" |
---|
768 | print*," Example:" |
---|
769 | print*," -thina 3 " |
---|
770 | print*," Will thin the grid with a ratio of 3, i.e., " |
---|
771 | print*," a 12km grid will be upscaled to a 36km grid" |
---|
772 | print*," The new grid point will be an average of the surrounding points" |
---|
773 | print*," " |
---|
774 | print*," -thin x : Thin the input grid, with a ratio of x" |
---|
775 | print*," Example:" |
---|
776 | print*," -thin 3 " |
---|
777 | print*," Will thin the grid with a ratio of 3, i.e., " |
---|
778 | print*," a 12km grid will be upscaled to a 36km grid" |
---|
779 | print*," The new grid point will be the feedback value from the input domain" |
---|
780 | print*," " |
---|
781 | print*," -box [ ] : Will extract a box out of the input grid" |
---|
782 | print*," The box can have values for x/y/z " |
---|
783 | print*," Examples:" |
---|
784 | print*," -box x 10 30 y 20 40 z 5 15" |
---|
785 | print*," -box x 10 30 y 20 40 " |
---|
786 | print*," -box x 10 30 " |
---|
787 | print*," -box y 20 40 " |
---|
788 | print*," " |
---|
789 | print*," -A : De-stagger output" |
---|
790 | print*," " |
---|
791 | print*," -64bit : To create large 64bit data files" |
---|
792 | print*," " |
---|
793 | end subroutine help_info |
---|
794 | |
---|
795 | !------------------------------------------------------------------------------ |
---|
796 | |
---|