p_consistency.F90 9.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. !KAL -- A change of Laurents cosistency program to fit with the new stuff
  2. !KAL -- it is called on a file-by-file (member - by - member) basis
  3. !KAL --
  4. !KAL -- Two argument, the file to check, and the corresponding ensemble member.
  5. !KAL -- the latter is needed when checking ice files as well.
  6. !KAL -- Output file is consistency_"input_file"
  7. !KAL
  8. program consistency
  9. use mod_raw_io
  10. use m_parse_blkdat
  11. use m_get_mod_grid
  12. use m_get_mod_fld
  13. use nfw_mod
  14. use mod_testinfo
  15. implicit none
  16. integer*4, external :: iargc
  17. integer, parameter :: maxweird = 100 ! give up reporting after 100 weird values
  18. real, parameter :: onem=9806.0, undef=-1e14
  19. logical isweird ! error locally at certain i,j,k
  20. integer iens,i,j,k, count_weird ! counting weird values in A
  21. character(len=80) :: rstfile, rstbase, outfile, icerstfile
  22. character(len=8) :: cfld
  23. character(len=80) :: cmem
  24. real, dimension(:,:), allocatable :: readfld,modlon,modlat,depths, dpsum
  25. real, dimension(:,:), allocatable :: countprobs, dpprobs, tempprobs
  26. real*4, dimension(:,:), allocatable :: fldr4
  27. logical :: process_ice
  28. integer :: iter
  29. integer :: ncid
  30. integer :: dimids(2)
  31. integer :: lon_id, lat_id, tot_id,tem_id, dp_id
  32. real :: bmin, bmax
  33. real*4 :: amin, amax, spval=0.0
  34. integer :: vlevel,tlevel,rstind
  35. logical :: readok, ex
  36. integer :: testindex
  37. integer :: idm,jdm,kdm
  38. integer :: ios, fnd
  39. integer :: imem, itime
  40. real :: rdummy
  41. real*8, allocatable, dimension(:,:) :: ficem,hicem,hsnwm,ticem,tsrfm
  42. integer :: reclice
  43. type(testinfo), dimension(:), allocatable :: tests
  44. integer :: numtest
  45. character(len=80) :: ncfile
  46. integer :: dimx,dimy,var_id,var2d(2),ierr
  47. real :: mindx,meandx
  48. process_ice=.false.
  49. imem=1 ! Only really needed when reading ice restart file
  50. if (iargc()==1) then
  51. call getarg(1,rstfile)
  52. elseif (iargc()==3) then
  53. call getarg(1,rstfile)
  54. call getarg(2,icerstfile)
  55. call getarg(3,cmem)
  56. read(cmem,*) imem
  57. process_ice=.true.
  58. else
  59. print *,'Usage: consistency restartfile icerestartfile ensemble_member'
  60. call exit(1)
  61. end if
  62. fnd=max(index(rstfile,'.a'),index(rstfile,'.b'))
  63. rstbase=rstfile(1:fnd-1)
  64. ! Set up test info
  65. numtest=9
  66. allocate(tests(9))
  67. call tests_init(tests, numtest)
  68. !Get model dimensions -
  69. call parse_blkdat('idm ','integer',rdummy,idm)
  70. call parse_blkdat('jdm ','integer',rdummy,jdm)
  71. call parse_blkdat('kdm ','integer',rdummy,kdm)
  72. ! Allocate fields
  73. allocate(readfld(idm,jdm))
  74. allocate(fldr4 (idm,jdm))
  75. allocate(modlon (idm,jdm))
  76. allocate(modlat (idm,jdm))
  77. allocate(depths (idm,jdm))
  78. allocate(dpsum (idm,jdm))
  79. allocate(countprobs (idm,jdm))
  80. allocate(dpprobs (idm,jdm))
  81. allocate(tempprobs (idm,jdm))
  82. ! Get model grid
  83. call get_mod_grid(modlon,modlat,depths,mindx,meandx,idm,jdm)
  84. ! Loop through the file header, extract field information, then:
  85. ! |--> extract header info
  86. ! |--> match header info with test cases
  87. ! |--> If match, read field from .a - file
  88. ! |--> Check for inconcistencies
  89. outfile='consistency_'//trim(rstbase)
  90. open(10, file=trim(outfile), access='sequential',status='replace')
  91. write(10,*) '**************************************************************'
  92. write(10,*) 'THIS FILE CONTAINS ERRORS DETECTED IN THE HYCOM STATE VARIABLE'
  93. write(10,*) 'Go to the end of this file for a summary of all errors '
  94. write(10,*) '**************************************************************'
  95. write(10,*) ''
  96. countprobs=0.
  97. dpprobs=0.
  98. tempprobs=0.
  99. rstind=1
  100. ios=0
  101. count_weird=0
  102. readok=.true.
  103. do while (readok)
  104. ! Get header info
  105. call rst_header_from_index(trim(rstbase)//'.b', &
  106. cfld,vlevel,tlevel,rstind,bmin,bmax,.true.)
  107. readok=tlevel/=-1 ! test to see if read was ok
  108. if (readok) then
  109. call matchtest(cfld,tests,numtest,testindex)
  110. if (testindex/=-1) then
  111. print *,'Checking : ',cfld,vlevel,tlevel
  112. call READRAW(fldr4,amin,amax,idm,jdm,.false.,spval,&
  113. trim(rstbase)//'.a',rstind)
  114. readfld=fldr4
  115. write(10,'(a,2i5)') 'Testing '//cfld//' at time and layer :',&
  116. tlevel,vlevel
  117. do j=1,jdm
  118. do i=1,idm
  119. if (depths(i,j)>.1) then
  120. isweird=.false.
  121. if (readfld(i,j)>tests(testindex)%max) then
  122. tests(testindex)%toolarge=tests(testindex)%toolarge+1
  123. isweird=.true.
  124. else if (readfld(i,j)<tests(testindex)%min) then
  125. tests(testindex)%toosmall=tests(testindex)%toosmall+1
  126. isweird=.true.
  127. end if
  128. if (tests(testindex)%toosmall + tests(testindex)%toolarge&
  129. <maxweird .and. isweird) then
  130. write(10,'(a,4i5,e14.4)') ' '//cfld//'&
  131. Error at i,j,z,t:',i,j,vlevel,tlevel,readfld(i,j)
  132. end if
  133. if (isweird) countprobs(i,j)=countprobs(i,j)+1
  134. if (isweird.and.trim(cfld)=='dp')&
  135. dpprobs(i,j)=dpprobs(i,j)+1
  136. if (isweird.and.trim(cfld)=='temp')&
  137. tempprobs(i,j)=tempprobs(i,j)+1
  138. end if
  139. end do
  140. end do
  141. if ( tests(testindex)%toosmall + tests(testindex)%toolarge&
  142. >=maxweird) then
  143. write(10,*) 'Found ', tests(testindex)%toosmall +&
  144. tests(testindex)%toolarge,' errors for ', cfld
  145. end if
  146. else
  147. print *,'Skipping : ',cfld,vlevel,tlevel
  148. end if
  149. end if
  150. rstind=rstind+1
  151. end do
  152. ! KAL -- test 2, see if layer thicknesses sum up to depths*onem
  153. do itime=1,2
  154. dpsum=0.
  155. do k=1,kdm
  156. call get_mod_fld_new(trim(rstbase),readfld,imem,'dp ',k,itime,&
  157. idm,jdm)
  158. dpsum=dpsum+readfld
  159. end do
  160. print '(a,i3)','Max difference dpsum / depths at time index ',itime
  161. print *,maxval(dpsum-depths*onem)/onem
  162. end do
  163. ! KAL -- test 3, see if ice thickness
  164. if (process_ice) then
  165. allocate(ficem(idm,jdm))
  166. allocate(hicem(idm,jdm))
  167. allocate(hsnwm(idm,jdm))
  168. allocate(ticem(idm,jdm))
  169. allocate(tsrfm(idm,jdm))
  170. print *,'TODO -- check ice fields'
  171. inquire(iolength=reclICE)ficem,hicem,hsnwm,ticem,tsrfm !,iceU,iceV
  172. open(20,file=trim(icerstfile),form='unformatted',access='direct',recl=reclICE,status='old')
  173. read(20,rec=imem,iostat=ios)ficem,hicem,hsnwm,ticem,tsrfm !,iceU,iceV
  174. close(20)
  175. do iter=1,2
  176. if (iter==1) then
  177. cfld='icec'
  178. call matchtest(cfld,tests,numtest,testindex)
  179. readfld=ficem
  180. else if (iter==2) then
  181. cfld='hice'
  182. call matchtest(cfld,tests,numtest,testindex)
  183. readfld=hicem
  184. end if
  185. if (testindex/=-1) then
  186. write(10,'(a,2i5)') 'Testing '//cfld//' at time and layer :',&
  187. tlevel,vlevel
  188. do j=1,jdm
  189. do i=1,idm
  190. if (depths(i,j)>.1) then
  191. isweird=.false.
  192. if (readfld(i,j)>tests(testindex)%max) then
  193. tests(testindex)%toolarge=tests(testindex)%toolarge+1
  194. isweird=.true.
  195. else if (readfld(i,j)<tests(testindex)%min) then
  196. tests(testindex)%toosmall=tests(testindex)%toosmall+1
  197. isweird=.true.
  198. end if
  199. if (tests(testindex)%toosmall + tests(testindex)%toolarge&
  200. <maxweird .and. isweird) then
  201. write(10,'(a,4i5,e14.4)') ' '//cfld//&
  202. ' Error at i,j,z,t:',i,j,vlevel,tlevel,readfld(i,j)
  203. end if
  204. end if
  205. if (isweird) countprobs(i,j)=countprobs(i,j)+1
  206. end do
  207. end do
  208. if (tests(testindex)%toosmall + tests(testindex)%toolarge&
  209. >=maxweird) then
  210. write(10,*) 'Found ', tests(testindex)%toosmall + tests(testindex)%toolarge,' errors for ',cfld
  211. end if
  212. end if
  213. end do
  214. end if
  215. close(10)
  216. print *,minval(countprobs),maxval(countprobs)
  217. where (depths<.1)
  218. countprobs=undef
  219. dpprobs=undef
  220. tempprobs=undef
  221. end where
  222. print *,minval(countprobs),maxval(countprobs)
  223. ! Netcdf - distribution of "problematic" areas
  224. ncfile=trim(outfile)//'.nc'
  225. call nfw_create(ncfile, nf_clobber, ncid)
  226. call nfw_def_dim(ncfile, ncid, 'idm', idm, dimids(1))
  227. call nfw_def_dim(ncfile, ncid, 'jdm', jdm, dimids(2))
  228. call nfw_def_var(ncfile, ncid, 'lon', nf_float, 2, dimids, lon_id)
  229. call nfw_def_var(ncfile, ncid, 'lat', nf_float, 2, dimids, lat_id)
  230. call nfw_def_var(ncfile, ncid, 'tempprob', nf_float, 2, dimids, tem_id)
  231. call nfw_def_var(ncfile, ncid, 'totprob', nf_float, 2, dimids, tot_id)
  232. call nfw_def_var(ncfile, ncid, 'dpprob', nf_float, 2, dimids, dp_id)
  233. call nfw_enddef(ncfile, ncid)
  234. call nfw_put_var_double(ncfile, ncid, lon_id, modlon)
  235. call nfw_put_var_double(ncfile, ncid, lat_id, modlat)
  236. call nfw_put_var_double(ncfile, ncid, tot_id, countprobs)
  237. call nfw_put_var_double(ncfile, ncid, tem_id, tempprobs)
  238. call nfw_put_var_double(ncfile, ncid, dp_id, dpprobs)
  239. call nfw_close(ncfile, ncid)
  240. end program consistency