mod_raw_io.f 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448
  1. # 0 "<stdin>"
  2. # 0 "<built-in>"
  3. # 0 "<command-line>"
  4. # 1 "/usr/include/stdc-predef.h" 1 3 4
  5. # 17 "/usr/include/stdc-predef.h" 3 4
  6. # 2 "<command-line>" 2
  7. # 1 "<stdin>"
  8. # 10 "<stdin>"
  9. module mod_raw_io
  10. contains
  11. ! Modified from Alan Wallcraft's RAW routine by Knut Liseter @ NERSC
  12. ! So far only the "I" in "IO" is present
  13. SUBROUTINE READRAW(A,AMN,AMX,IDM,JDM,LSPVAL,SPVAL,CFILE1,K)
  14. IMPLICIT NONE
  15. C
  16. REAL*4 SPVALH
  17. PARAMETER (SPVALH=1.0E30_4)
  18. C
  19. REAL*4, INTENT(OUT) :: A(IDM,JDM)
  20. REAL*4, INTENT(OUT) :: AMN,AMX
  21. INTEGER, INTENT(IN) :: IDM,JDM
  22. LOGICAL, INTENT(IN) :: LSPVAL
  23. REAL*4, INTENT(INOUT) :: SPVAL
  24. INTEGER, INTENT(IN) :: K
  25. CHARACTER(len=*), INTENT(IN) :: CFILE1
  26. C
  27. REAL*4 :: PADA(4096)
  28. C
  29. C MOST OF WORK IS DONE HERE.
  30. C
  31. INTEGER LEN_TRIM
  32. INTEGER I,J,IOS,NRECL
  33. INTEGER NPAD
  34. C
  35. IF(.NOT.LSPVAL) THEN
  36. SPVAL = SPVALH
  37. ENDIF
  38. C
  39. !!! Calculate the number of elements padded!!!!!!!!!!!!!!!!!!!!!!!!
  40. NPAD=GET_NPAD(IDM,JDM)
  41. C
  42. INQUIRE( IOLENGTH=NRECL) A,PADA(1:NPAD)
  43. C
  44. C
  45. OPEN(UNIT=11, FILE=CFILE1, FORM='UNFORMATTED', STATUS='old',
  46. + ACCESS='DIRECT', RECL=NRECL, IOSTAT=IOS, ACTION='READ')
  47. IF (IOS.NE.0) THEN
  48. write(6,*) 'Error: can''t open ',CFILE1(1:LEN_TRIM(CFILE1))
  49. write(6,*) 'ios = ',ios
  50. write(6,*) 'nrecl = ',nrecl
  51. CALL EXIT(3)
  52. ENDIF
  53. C
  54. READ(11,REC=K,IOSTAT=IOS) A
  55. close(11)
  56. C
  57. IF (IOS.NE.0) THEN
  58. WRITE(6,*) 'can''t read record ',K,
  59. & ' from '//CFILE1(1:LEN_TRIM(CFILE1))
  60. CALL EXIT(4)
  61. ENDIF
  62. C
  63. AMN = SPVALH
  64. AMX = -SPVALH
  65. DO J= 1,JDM
  66. DO I=1,IDM
  67. IF (A(I,J).LE.SPVALH) THEN
  68. AMN = MIN(real(AMN, 4), real(A(I,J), 4))
  69. AMX = MAX(real(AMX, 4), real(A(I,J), 4))
  70. ELSEIF (LSPVAL) THEN
  71. A(I,J) = SPVAL
  72. ENDIF
  73. END DO
  74. END DO
  75. C
  76. RETURN
  77. END SUBROUTINE
  78. ! Modified from Alan Wallcraft's RAW routine by Knut Liseter @ NERSC
  79. ! This wll be the "O" in "IO" is present
  80. SUBROUTINE WRITERAW(A,AMN,AMX,IDM,JDM,LSPVAL,SPVAL,CFILE1,K)
  81. IMPLICIT NONE
  82. C
  83. REAL*4 SPVALH
  84. PARAMETER (SPVALH=1.0e30_4)
  85. C
  86. REAL*4, INTENT(INOUT) :: A(IDM,JDM)
  87. REAL*4, INTENT(OUT) :: AMN,AMX
  88. INTEGER, INTENT(IN) :: IDM,JDM
  89. LOGICAL, INTENT(IN) :: LSPVAL
  90. REAL*4, INTENT(INOUT) :: SPVAL
  91. INTEGER, INTENT(IN) :: K
  92. CHARACTER(len=*), INTENT(IN) :: CFILE1
  93. C
  94. REAL*4 :: PADA(4096)
  95. C
  96. C MOST OF WORK IS DONE HERE.
  97. C
  98. INTEGER LEN_TRIM
  99. INTEGER I,J,IOS,NRECL
  100. INTEGER NPAD
  101. C
  102. IF(.NOT.LSPVAL) THEN
  103. SPVAL = SPVALH
  104. ENDIF
  105. C
  106. !!! Calculate the number of elements padded!!!!!!!!!!!!!!!!!!!!!!!!
  107. NPAD=GET_NPAD(IDM,JDM)
  108. C
  109. PADA=0.
  110. INQUIRE( IOLENGTH=NRECL) A,PADA(1:NPAD)
  111. C
  112. C
  113. OPEN(UNIT=11, FILE=CFILE1, FORM='UNFORMATTED', STATUS='unknown',
  114. + ACCESS='DIRECT', RECL=NRECL, IOSTAT=IOS)
  115. IF (IOS.NE.0) THEN
  116. write(6,*) 'Error: can''t open ',CFILE1(1:LEN_TRIM(CFILE1))
  117. write(6,*) 'ios = ',ios
  118. write(6,*) 'nrecl = ',nrecl
  119. CALL EXIT(3)
  120. ENDIF
  121. C
  122. WRITE(11,REC=K,IOSTAT=IOS) A,PADA(1:NPAD)
  123. close(11)
  124. C
  125. IF (IOS.NE.0) THEN
  126. WRITE(6,*) 'can''t write record ',K,
  127. & ' from '//CFILE1(1:LEN_TRIM(CFILE1))
  128. CALL EXIT(4)
  129. ENDIF
  130. C
  131. AMN = SPVALH
  132. AMX = -SPVALH
  133. DO J= 1,JDM
  134. DO I=1,IDM
  135. IF (A(I,J).LE.SPVALH) THEN
  136. AMN = MIN(real(AMN, 4), real(A(I,J), 4))
  137. AMX = MAX(real(AMX, 4), real(A(I,J), 4))
  138. ELSEIF (LSPVAL) THEN
  139. A(I,J) = SPVAL
  140. ENDIF
  141. END DO
  142. END DO
  143. C
  144. RETURN
  145. END SUBROUTINE
  146. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  147. ! Routine to get index of fields in data file (.a) from header file (.b)
  148. subroutine rst_index_from_header(fname,cfld,vlevel,tlevel,
  149. & indx,bmin,bmax,skiphdr)
  150. implicit none
  151. character(len=*), intent(in) :: fname ! filename without extention
  152. character(len=*), intent(in) :: cfld ! variable name
  153. integer , intent(in) :: tlevel ! time level
  154. integer , intent(in) :: vlevel ! vertical level
  155. integer , intent(out):: indx ! index in .a file
  156. real , intent(out):: bmin,bmax ! min and max from b file
  157. logical , intent(in) :: skiphdr
  158. integer :: itlevel, ivlevel
  159. character(len=8) :: icfld
  160. integer :: ios,i
  161. integer :: nskip_rst,nop
  162. logical :: match, ex
  163. nskip_rst=2
  164. nop = 999
  165. ! Open file
  166. inquire(exist=ex,file=trim(fname))
  167. if (.not. ex) then
  168. print *,'file '//trim(fname)//' is not present'
  169. call exit(1)
  170. end if
  171. open(nop,file=trim(fname),status='old',action='read')
  172. ! Skip first nskip lines
  173. if (skiphdr) then
  174. do i=1,nskip_rst
  175. read(nop,*)
  176. end do
  177. end if
  178. match=.false.
  179. indx=0
  180. ios=0
  181. do while (ios==0 .and. .not.match)
  182. read(nop,117,iostat=ios) icfld,ivlevel,itlevel,bmin,bmax
  183. match= icfld==cfld .and. ivlevel==vlevel .and. itlevel==tlevel
  184. indx=indx+1
  185. !print *,icfld,itlevel,ivlevel,bmin,bmax
  186. end do
  187. close(nop)
  188. if (.not.match) then
  189. !print *,'Could not find field '//cfld
  190. !print *,'Vertical level :',vlevel
  191. !print *,'Time level :',tlevel
  192. indx=-1
  193. !call exit(1) ! Always return to caller
  194. endif
  195. 117 format (a8,23x,i3,i3,2x,2e16.7)
  196. end subroutine
  197. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  198. ! Routine to get field desc in header file (.b) from index in data file (.a)
  199. subroutine rst_header_from_index(fname,cfld,vlevel,tlevel,
  200. & indx,bmin,bmax,skiphdr)
  201. implicit none
  202. character(len=*), intent(in) :: fname ! filename without extention
  203. character(len=8), intent(out) :: cfld ! variable name
  204. integer , intent(out) :: tlevel ! time level
  205. integer , intent(out) :: vlevel ! vertical level
  206. integer , intent(in) :: indx ! index in .a file
  207. real , intent(out) :: bmin,bmax ! min and max from b file
  208. logical , intent(in ) :: skiphdr ! Skip header of .b file
  209. integer :: ios,i
  210. integer :: nskip_rst,nop
  211. logical :: ex
  212. nskip_rst=2
  213. nop = 999
  214. ! Open file
  215. inquire(exist=ex,file=trim(fname))
  216. if (.not. ex) then
  217. print *,'file '//trim(fname)//' not present'
  218. call exit(1)
  219. end if
  220. open(nop,file=trim(fname),status='old',action='read')
  221. ! Skip first nskip + index-1 lines
  222. !print *,'hei'
  223. if (skiphdr) then
  224. do i=1,nskip_rst
  225. read(nop,*)
  226. end do
  227. end if
  228. do i=1,indx-1
  229. read(nop,*)
  230. end do
  231. read(nop,117,iostat=ios) cfld,vlevel,tlevel,bmin,bmax
  232. close(nop)
  233. if (ios/=0) then
  234. !print *,'Could not get info from index',indx
  235. !call exit(1)
  236. cfld=''
  237. tlevel=-1
  238. vlevel=-1
  239. endif
  240. 117 format (a8,23x,i3,i3,2x,2e16.7)
  241. end subroutine
  242. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  243. ! Routine to get index of fields in regional grid file (.a) from header file (.b)
  244. subroutine grid_index_from_header(fname,cfld,indx,bmin,bmax
  245. & ,skiphdr)
  246. implicit none
  247. character(len=*), intent(in) :: fname ! filename without extention
  248. character(len=*), intent(in) :: cfld ! variable name
  249. integer , intent(out):: indx ! index in .a file
  250. real , intent(out):: bmin,bmax ! min and max from b file
  251. logical , intent(in) :: skiphdr
  252. character(len=4) :: icfld
  253. character*80 :: cline
  254. integer :: ios,i
  255. integer :: nskip_grid,nop
  256. logical :: match, ex
  257. nskip_grid=3
  258. nop = 999
  259. ! Open file
  260. inquire(exist=ex,file=trim(fname))
  261. if (.not. ex) then
  262. print *,'file '//trim(fname)//' is not present'
  263. call exit(1)
  264. end if
  265. open(nop,file=trim(fname),status='old',action='read')
  266. ! Skip first nskip lines
  267. if (skiphdr) then
  268. do i=1,nskip_grid
  269. read(nop,*)
  270. end do
  271. end if
  272. match=.false.
  273. indx=0
  274. ios=0
  275. do while (ios==0 .and. .not.match)
  276. read(nop,'(a)') cline
  277. icfld=cline(1:4)
  278. i=index(cline,'=')
  279. read (cline(i+1:),*) bmin,bmax
  280. match= trim(icfld)==trim(cfld)
  281. indx=indx+1
  282. end do
  283. close(nop)
  284. if (.not.match) then
  285. indx=-1
  286. endif
  287. end subroutine grid_index_from_header
  288. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  289. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  290. ! Routine to get index of fields in regional grid file (.a) from header file (.b)
  291. subroutine daily_index_from_header(fname,cfld,coord,indx,
  292. & bmin,bmax)
  293. implicit none
  294. character(len=*), intent(in) :: fname ! filename without extention
  295. character(len=*), intent(in) :: cfld ! variable name
  296. integer , intent(in) :: coord ! vertical coordinate
  297. integer , intent(out):: indx ! index in .a file
  298. real , intent(out):: bmin,bmax ! min and max from b file
  299. logical, parameter:: skiphdr=.true.
  300. character(len=5) :: char5
  301. character(len=8) :: char8
  302. integer :: ios
  303. integer :: nop
  304. logical :: match, ex
  305. real :: dens,rday
  306. integer :: lcoord,nstep
  307. nop = 999
  308. ! Open file
  309. inquire(exist=ex,file=trim(fname))
  310. if (.not. ex) then
  311. print *,'file '//trim(fname)//' is not present'
  312. call exit(1)
  313. end if
  314. open(nop,file=trim(fname),status='old')
  315. ! Skip first nskip lines
  316. if (skiphdr) then
  317. do while (char5/='field' .and. ios==0)
  318. read(nop,'(a5)',iostat=ios) char5
  319. end do
  320. end if
  321. ! Read until we get the field we want
  322. indx=0
  323. ios=0
  324. char8=''
  325. lcoord=-1
  326. match=.false.
  327. do while(.not.match .and. ios==0)
  328. read(nop,117,iostat=ios) char8,nstep,rday,lcoord,dens,
  329. & bmin,bmax
  330. match=(trim(cfld)==trim(char8) .and. lcoord==coord)
  331. indx=indx+1
  332. end do
  333. close(nop)
  334. if (.not.match) then
  335. indx=-1
  336. endif
  337. 117 format (a8,' = ',i11,f11.2,i3,f7.3,1p2e16.7)
  338. end subroutine daily_index_from_header
  339. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
  340. INTEGER FUNCTION GET_NPAD(IDM,JDM)
  341. IMPLICIT NONE
  342. INTEGER, INTENT(IN) :: IDM,JDM
  343. GET_NPAD = 4096 - MOD(IDM*JDM,4096)
  344. GET_NPAD = mod(GET_NPAD,4096)
  345. END FUNCTION
  346. end module mod_raw_io