00001
00002
00003
00004
00005
00006
00007 Module psmile_io_utils
00008
00009 Interface psmile_io_fileunit
00010 module procedure psmile_io_fileunit
00011 End Interface
00012 Interface combine_with_date
00013 module procedure combine_with_date
00014 End Interface
00015 Interface extract_date
00016 module procedure extract_date
00017 End Interface
00018 Interface psmile_io_get_initial_date
00019 module procedure psmile_io_get_initial_date
00020 End Interface
00021 Interface psmile_io_get_jobstart_date
00022 module procedure psmile_io_get_jobstart_date
00023 End Interface
00024 Interface psmile_io_get_jobend_date
00025 module procedure psmile_io_get_jobend_date
00026 End Interface
00027 Interface psmile_io_check_basename
00028 module procedure psmile_io_check_basename
00029 End Interface
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071 contains
00072 subroutine psmile_io_fileunit(id_varid,id_unit,ierror)
00073 use psmile
00074 implicit none
00075 include 'prism.inc'
00076 integer,intent(in) :: id_varid
00077 integer,intent(out) :: id_unit
00078 integer,intent(out) :: ierror
00079
00080 logical :: l_open
00081 integer :: i,ierrp(2)
00082
00083 Character(len=len_cvs_string), save :: mycvs_io_utils =
00084 '$Id: psmile_io_utils.F90 2325 2010-04-21 15:00:07Z valcke $'
00085 #ifdef __PSMILE_WITH_IO
00086 l_open=.true.
00087 do i=7, PSMILE_IO_MAX_UNIT
00088 if(.not.any(i.eq.IO_res_units(1:PSMILE_IO_MAX_RESERVED_UNITS))) &
00089 inquire(unit=i,opened=l_open)
00090 if(.not.l_open) exit
00091 end do
00092
00093 if(i== PSMILE_IO_MAX_UNIT+1)then
00094 ierror=PRISM_Error_Internal
00095 call psmile_error ( ierror, 'Cound not find free I/O unit!', &
00096 ierrp, 0, __FILE__, __LINE__ )
00097
00098 else
00099 id_unit = i
00100 endif
00101 #endif
00102
00103 return
00104 end subroutine psmile_io_fileunit
00105
00106 subroutine combine_with_date(cd_in,cd_mode,id_initial_date,cd_on)
00107
00108
00109 character(len=*),intent(in)::cd_in
00110 character(len=*),intent(in)::cd_mode
00111 character(len=*),intent(out)::cd_on
00112 integer,intent(in)::id_initial_date(:)
00113
00114 integer,parameter::il_nsuffixes=2
00115 integer::leni,leno,lens,lenb,il_i
00116 character(len=8)::suffixes(il_nsuffixes),suffix
00117 character(len=len(cd_in))::cl_basename
00118 character(len=4)::cl_year
00119 character(len=2)::cl_date(1:size(id_initial_date)-1)
00120
00121 suffixes(1)='.nc'
00122 suffixes(2)='.grib'
00123
00124 leni=len(trim(cd_in))
00125 leno=len(cd_on)
00126
00127 cl_basename=''
00128
00129 do il_i=1,il_nsuffixes
00130
00131 suffix=suffixes(il_i)
00132 lens=len(trim(suffix))
00133
00134 if(leni.gt.0.and.leni.lt.lens) then
00135 cl_basename(1:leni)=cd_in(1:leni)
00136 lenb=leni
00137 suffix='.nc'
00138 else if(cd_in(leni-lens+1:leni).eq.suffix(1:lens)) then
00139 cl_basename(1:leni-lens)=cd_in(1:leni-lens)
00140 lenb=leni-lens
00141 EXIT
00142 else
00143 cl_basename(1:leni)=cd_in(1:leni)
00144 lenb=leni
00145 suffix='.nc'
00146 endif
00147
00148 enddo
00149
00150
00151 write(cl_year,'(i4.4)')id_initial_date(1)
00152
00153 do il_i=2,size(id_initial_date)
00154
00155 write(cl_date(il_i-1),'(i2.2)')id_initial_date(il_i)
00156
00157 enddo
00158
00159 if(trim(cd_mode) .eq. 'since' ) then
00160 cd_on=trim(cl_basename(1:lenb))//' '//trim(cd_mode)//' ' &
00161 //cl_year//'-'//cl_date(1)//'-' &
00162 //cl_date(2)//' ' &
00163 //cl_date(3)//':' &
00164 //cl_date(4)//':' &
00165 //cl_date(5)
00166 else
00167 cd_on=trim(cl_basename(1:lenb))//'_'//trim(cd_mode)//'.' &
00168 //cl_year//'-'//cl_date(1)//'-' &
00169 //cl_date(2)//'T' &
00170 //cl_date(3)//'_' &
00171 //cl_date(4)//'_' &
00172 //cl_date(5)//suffix
00173 endif
00174
00175 return
00176 end subroutine combine_with_date
00177
00178 subroutine extract_date(time_unit,curdate,id_date)
00179 use PRISM_Constants
00180 use PSMILE
00181 implicit none
00182
00183
00184
00185 character(len=*),intent(in)::time_unit
00186 Type(PRISM_Time_Struct),intent(inout):: curdate
00187 integer,dimension(6),intent(out),optional::id_date
00188
00189
00190
00191 integer::i,j,iloc,ierrp(2),ierror
00192 character(len=max_name)::tmp_unit
00193 character(len=1)::tmp_char
00194
00195
00196
00197
00198
00199
00200 iloc=1
00201 do i=1,len(trim(time_unit))
00202 if(time_unit(i:i) .ne. ' ') then
00203 j=ichar(time_unit(i:i))
00204 if(j.ge.65 .and. j.le.90) then
00205 tmp_char=char(j+32)
00206 else
00207 tmp_char=char(j)
00208 endif
00209 tmp_unit(iloc:iloc)=tmp_char
00210 iloc=iloc+1
00211 endif
00212 enddo
00213
00214 if(len(trim(tmp_unit))-4.lt.1) then
00215 ierror = PRISM_Error_Internal
00216 call psmile_error ( ierror, 'Invalid unit of time axis!', &
00217 ierrp, 0, __FILE__, __LINE__ )
00218 endif
00219
00220
00221
00222
00223 do i=1,len(trim(tmp_unit))-4
00224 if(tmp_unit(i:i+4).eq.'since') exit
00225 enddo
00226
00227 if(i.eq.len(trim(tmp_unit))-4) then
00228 ierror = PRISM_Error_Internal
00229 call psmile_error ( ierror, 'Time axis has no time origin!', &
00230 ierrp, 0, __FILE__, __LINE__ )
00231 endif
00232
00233
00234
00235
00236 i=i+5
00237
00238 read(tmp_unit(i:i+3),'(i4)')curdate%year
00239
00240
00241
00242
00243 i=i+5
00244
00245 read(tmp_unit(i:i+1),'(i2)')curdate%month
00246
00247
00248
00249
00250 i=i+3
00251
00252 read(tmp_unit(i:i+3),'(i2)')curdate%day
00253
00254
00255
00256
00257 i=i+2
00258
00259
00260
00261
00262 if(ichar(tmp_unit(i:i)).lt.48 .or. ichar(tmp_unit(i:i)).gt.57) i=i+1
00263
00264 read(tmp_unit(i:i+1),'(i2)')curdate%hour
00265
00266
00267
00268 i=i+3
00269 read(tmp_unit(i:i+1),'(i2)')curdate%minute
00270
00271
00272
00273 i=i+3
00274 read(tmp_unit(i:i+1),'(i2)') j
00275 curdate%second=dble(j)
00276
00277 if(present(id_date)) then
00278 id_date(1)=curdate%year
00279 id_date(2)=curdate%month
00280 id_date(3)=curdate%day
00281 id_date(4)=curdate%hour
00282 id_date(5)=curdate%minute
00283 id_date(6)=curdate%second
00284 endif
00285
00286 end subroutine extract_date
00287
00288
00289 subroutine psmile_io_get_jobstart_date(id_jobstart_date,id_date,ierror)
00290 USE PRISM, only : PRISM_Jobstart_date
00291 USE PRISM_Constants
00292 USE PSMILe
00293 USE prism_calendar
00294 implicit none
00295
00296 integer,intent(out) :: ierror
00297 Type(PRISM_Time_Struct),intent(out) :: id_jobstart_date
00298 integer,intent(out),optional:: id_date(:)
00299
00300
00301
00302
00303 ierror=0
00304
00305
00306
00307
00308
00309
00310
00311 id_jobstart_date= PRISM_jobstart_date
00312 #ifdef VERBOSE
00313 print*,trim(ch_id),' : psmile_io_get_jobstart_date: date',id_jobstart_date
00314 #endif
00315 if(present(id_date))then
00316 id_date(1)=id_jobstart_date%year
00317 id_date(2)=id_jobstart_date%month
00318 id_date(3)=id_jobstart_date%day
00319 id_date(4)=id_jobstart_date%hour
00320 id_date(5)=id_jobstart_date%minute
00321 id_date(6)=id_jobstart_date%second
00322 endif
00323 #ifdef VERBOSE
00324 print*,trim(ch_id),' : psmile_io_get_jobstart_date: end'
00325 call psmile_flushstd
00326 #endif
00327 return
00328 end subroutine psmile_io_get_jobstart_date
00329
00330 subroutine psmile_io_get_jobend_date(id_jobend_date,id_date,ierror)
00331 USE PRISM, only : PRISM_jobend_date
00332 USE PRISM_Constants
00333 USE PSMILe
00334 USE prism_calendar
00335 implicit none
00336
00337 integer,intent(out) :: ierror
00338 Type(PRISM_Time_Struct),intent(out) :: id_jobend_date
00339 integer,intent(out),optional:: id_date(:)
00340
00341
00342
00343
00344 ierror=0
00345
00346
00347
00348
00349
00350
00351
00352 id_jobend_date= PRISM_jobend_date
00353 #ifdef VERBOSE
00354 print*,trim(ch_id),' : psmile_io_get_jobend_date: date',id_jobend_date
00355 call psmile_flushstd
00356 #endif
00357 if(present(id_date))then
00358 id_date(1)=id_jobend_date%year
00359 id_date(2)=id_jobend_date%month
00360 id_date(3)=id_jobend_date%day
00361 id_date(4)=id_jobend_date%hour
00362 id_date(5)=id_jobend_date%minute
00363 id_date(6)=id_jobend_date%second
00364 endif
00365 #ifdef VERBOSE
00366 print*,trim(ch_id),' : psmile_io_get_jobend_date: end'
00367 call psmile_flushstd
00368 #endif
00369 return
00370 end subroutine psmile_io_get_jobend_date
00371
00372 subroutine psmile_io_get_initial_date(id_initial_date,id_date,ierror)
00373 USE PRISM_Constants
00374 USE PSMILe
00375 USE prism_calendar
00376 implicit none
00377
00378 integer,intent(out) :: ierror
00379 Type(PRISM_Time_Struct),intent(out) :: id_initial_date
00380 integer,intent(out),optional:: id_date(:)
00381
00382 ierror=0
00383
00384 call psmile_get_initial_date(id_initial_date,ierror)
00385 if(present(id_date))then
00386 id_date(1)=id_initial_date%year
00387 id_date(2)=id_initial_date%month
00388 id_date(3)=id_initial_date%day
00389 id_date(4)=id_initial_date%hour
00390 id_date(5)=id_initial_date%minute
00391 id_date(6)=id_initial_date%second
00392 endif
00393 #ifdef VERBOSE
00394 print*,trim(ch_id),' : psmile_io_get_jobstart_date: end'
00395 call psmile_flushstd
00396 #endif
00397 return
00398 end subroutine psmile_io_get_initial_date
00399
00400 subroutine psmile_io_check_basename(cd_filename,cd_suffix &
00401 ,ld_base,id_error)
00402 implicit none
00403 character(len=*),intent(in) :: cd_filename
00404 character(len=*),intent(in) :: cd_suffix
00405 logical,intent(out) :: ld_base
00406 integer,intent(out) :: id_error
00407
00408
00409 integer :: il_flsuffl,il_flnamel
00410
00411 id_error=0
00412
00413 ld_base=.TRUE.
00414 il_flnamel=len(trim(cd_filename))
00415 il_flsuffl=len(trim(cd_suffix))
00416
00417 if(il_flnamel.lt.il_flsuffl) return
00418
00419 if(cd_filename(il_flnamel-il_flsuffl+1:il_flnamel).eq.trim(cd_suffix)) &
00420 ld_base=.false.
00421
00422 end subroutine psmile_io_check_basename
00423
00424
00425 subroutine indexi(n,arr,indx)
00426
00427
00428
00429
00430
00431 INTEGER,intent(in):: n
00432 INTEGER,intent(out)::indx(*)
00433 integer,intent(in):: arr(*)
00434
00435 integer,PARAMETER:: M=7,NSTACK=128
00436 INTEGER:: i,indxt,ir,itemp,j,jstack,k,l,istack(NSTACK)
00437 integer:: a
00438
00439 do 11 j=1,n
00440 indx(j)=j
00441 11 continue
00442 jstack=0
00443 l=1
00444 ir=n
00445 1 if(ir-l.lt.M)then
00446 do 13 j=l+1,ir
00447 indxt=indx(j)
00448 a=arr(indxt)
00449 do 12 i=j-1,1,-1
00450 if(arr(indx(i)).le.a)goto 2
00451 indx(i+1)=indx(i)
00452 12 continue
00453 i=0
00454 2 indx(i+1)=indxt
00455 13 continue
00456 if(jstack.eq.0)return
00457 ir=istack(jstack)
00458 l=istack(jstack-1)
00459 jstack=jstack-2
00460 else
00461 k=(l+ir)/2
00462 itemp=indx(k)
00463 indx(k)=indx(l+1)
00464 indx(l+1)=itemp
00465 if(arr(indx(l+1)).gt.arr(indx(ir)))then
00466 itemp=indx(l+1)
00467 indx(l+1)=indx(ir)
00468 indx(ir)=itemp
00469 endif
00470 if(arr(indx(l)).gt.arr(indx(ir)))then
00471 itemp=indx(l)
00472 indx(l)=indx(ir)
00473 indx(ir)=itemp
00474 endif
00475 if(arr(indx(l+1)).gt.arr(indx(l)))then
00476 itemp=indx(l+1)
00477 indx(l+1)=indx(l)
00478 indx(l)=itemp
00479 endif
00480 i=l+1
00481 j=ir
00482 indxt=indx(l)
00483 a=arr(indxt)
00484 3 continue
00485 i=i+1
00486 if(arr(indx(i)).lt.a)goto 3
00487 4 continue
00488 j=j-1
00489 if(arr(indx(j)).gt.a)goto 4
00490 if(j.lt.i)goto 5
00491 itemp=indx(i)
00492 indx(i)=indx(j)
00493 indx(j)=itemp
00494 goto 3
00495 5 indx(l)=indx(j)
00496 indx(j)=indxt
00497 jstack=jstack+2
00498 if(jstack.gt.NSTACK)pause 'NSTACK too small in indexx'
00499 if(ir-i+1.ge.j-l)then
00500 istack(jstack)=ir
00501 istack(jstack-1)=i
00502 ir=j-1
00503 else
00504 istack(jstack)=j-1
00505 istack(jstack-1)=l
00506 l=i
00507 endif
00508 endif
00509 goto 1
00510 END subroutine indexi
00511
00512
00513 End Module psmile_io_utils
00514