obsvel_io.h90 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. !!----------------------------------------------------------------------
  2. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  3. !! $Id: obsvel_io.h90 2287 2010-10-18 07:53:52Z smasson $
  4. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  5. !!----------------------------------------------------------------------
  6. SUBROUTINE read_taondbc( cdfilename, inpfile, kunit, ldwp, ldgrid )
  7. !!---------------------------------------------------------------------
  8. !!
  9. !! ** ROUTINE read_enactfile **
  10. !!
  11. !! ** Purpose : Read from file the TAO data fro NDBC.
  12. !!
  13. !! ** Method : The data file is a NetCDF file.
  14. !!
  15. !! ** Action :
  16. !!
  17. !! ** Reference : http://tao.noaa.gov/tao/data_deliv/deliv_ndbc.shtml
  18. !! History :
  19. !! ! 09-01 (K. Mogensen) Original version.
  20. !!----------------------------------------------------------------------
  21. !! * Arguments
  22. CHARACTER(LEN=*) :: cdfilename ! Input filename
  23. TYPE(obfbdata) :: inpfile ! Output obfbdata structure
  24. INTEGER :: kunit ! Unit for output
  25. LOGICAL :: ldwp ! Print info
  26. LOGICAL :: ldgrid ! Save grid info in data structure
  27. !! * Local declarations
  28. INTEGER :: iobs ! Number of observations
  29. INTEGER :: ilev ! Number of levels
  30. INTEGER :: ilat ! Number of latitudes
  31. INTEGER :: ilon ! Number of longtudes
  32. INTEGER :: itim ! Number of obs. times
  33. INTEGER :: i_file_id
  34. INTEGER :: i_dimid_id
  35. INTEGER :: i_phi_id
  36. INTEGER :: i_lam_id
  37. INTEGER :: i_depth_id
  38. INTEGER :: i_var_id
  39. INTEGER :: i_time_id
  40. INTEGER :: i_time2_id
  41. INTEGER :: i_qc_var_id
  42. CHARACTER(LEN=40) :: cl_fld_lam
  43. CHARACTER(LEN=40) :: cl_fld_phi
  44. CHARACTER(LEN=40) :: cl_fld_depth
  45. CHARACTER(LEN=40) :: cl_fld_var_u
  46. CHARACTER(LEN=40) :: cl_fld_var_v
  47. CHARACTER(LEN=40) :: cl_fld_var_qc_uv1
  48. CHARACTER(LEN=40) :: cl_fld_var_qc_uv2
  49. CHARACTER(LEN=40) :: cl_fld_time
  50. CHARACTER(LEN=40) :: cl_fld_time2
  51. INTEGER :: ja
  52. INTEGER :: jo
  53. INTEGER :: jk
  54. INTEGER :: jt
  55. REAL(wp), ALLOCATABLE, DIMENSION(:,:,:,:) :: &
  56. & zv, &
  57. & zu, &
  58. & zuv1qc, &
  59. & zuv2qc
  60. REAL(wp), ALLOCATABLE, DIMENSION(:) :: &
  61. & zdep, &
  62. & zlat, &
  63. & zlon, &
  64. & zjuld
  65. REAL(wp) :: zl
  66. INTEGER, ALLOCATABLE, DIMENSION(:) :: &
  67. & itime, &
  68. & itime2
  69. CHARACTER(LEN=50) :: cdjulref
  70. CHARACTER(LEN=12), PARAMETER :: cl_name = 'read_taondbc'
  71. CHARACTER(len=1) :: cns, cew
  72. !-----------------------------------------------------------------------
  73. ! Initialization
  74. !-----------------------------------------------------------------------
  75. cl_fld_lam = 'lon'
  76. cl_fld_phi = 'lat'
  77. cl_fld_depth = 'depth'
  78. cl_fld_time = 'time'
  79. cl_fld_time2 = 'time2'
  80. !-----------------------------------------------------------------------
  81. ! Open file
  82. !-----------------------------------------------------------------------
  83. CALL chkerr( nf90_open( TRIM( cdfilename ), nf90_nowrite, &
  84. & i_file_id ), cl_name, __LINE__ )
  85. !-----------------------------------------------------------------------
  86. ! Read the heading of the file
  87. !-----------------------------------------------------------------------
  88. IF(ldwp) WRITE(kunit,*)
  89. IF(ldwp) WRITE(kunit,*) ' read_taondbc :'
  90. IF(ldwp) WRITE(kunit,*) ' ~~~~~~~~~~~~'
  91. !---------------------------------------------------------------------
  92. ! Read the number of observations and of levels to allocate array
  93. !---------------------------------------------------------------------
  94. CALL chkerr( nf90_inq_dimid ( i_file_id, 'time', i_dimid_id ), &
  95. & cl_name, __LINE__ )
  96. CALL chkerr( nf90_inquire_dimension( i_file_id, i_dimid_id, len = itim ), &
  97. & cl_name, __LINE__ )
  98. CALL chkerr( nf90_inq_dimid ( i_file_id, 'depth', i_dimid_id ), &
  99. & cl_name, __LINE__ )
  100. CALL chkerr( nf90_inquire_dimension( i_file_id, i_dimid_id, len = ilev ), &
  101. & cl_name, __LINE__ )
  102. CALL chkerr( nf90_inq_dimid ( i_file_id, 'lat', i_dimid_id ), &
  103. & cl_name, __LINE__ )
  104. CALL chkerr( nf90_inquire_dimension( i_file_id, i_dimid_id, len = ilat ), &
  105. & cl_name, __LINE__ )
  106. CALL chkerr( nf90_inq_dimid ( i_file_id, 'lon', i_dimid_id ), &
  107. & cl_name, __LINE__ )
  108. CALL chkerr( nf90_inquire_dimension( i_file_id, i_dimid_id, len = ilon ), &
  109. & cl_name, __LINE__ )
  110. iobs = itim * ilat * ilon
  111. IF(ldwp)WRITE(kunit,*) ' No. of data records = ', iobs
  112. IF(ldwp)WRITE(kunit,*) ' No. of levels = ', ilev
  113. IF(ldwp)WRITE(kunit,*)
  114. !---------------------------------------------------------------------
  115. ! Allocate arrays
  116. !---------------------------------------------------------------------
  117. CALL init_obfbdata( inpfile )
  118. CALL alloc_obfbdata( inpfile, 2, iobs, ilev, 0, 0, ldgrid )
  119. inpfile%cname(1) = 'UVEL'
  120. inpfile%cname(2) = 'VVEL'
  121. inpfile%coblong(1) = 'Zonal current'
  122. inpfile%coblong(2) = 'Meridional current'
  123. inpfile%cobunit(1) = 'Meters per second'
  124. inpfile%cobunit(2) = 'Meters per second'
  125. ALLOCATE( &
  126. & zu(ilon,ilat,ilev,itim), &
  127. & zv(ilon,ilat,ilev,itim), &
  128. & zdep(ilev), &
  129. & zuv1qc(ilon,ilat,ilev,itim), &
  130. & zuv2qc(ilon,ilat,ilev,itim), &
  131. & itime(itim), &
  132. & itime2(itim), &
  133. & zlat(ilat), &
  134. & zlon(ilon), &
  135. & zjuld(itim) &
  136. & )
  137. !---------------------------------------------------------------------
  138. ! Read the time/position variables
  139. !---------------------------------------------------------------------
  140. CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_time, i_time_id ), &
  141. & cl_name, __LINE__ )
  142. CALL chkerr( nf90_get_var ( i_file_id, i_time_id, itime ), &
  143. & cl_name, __LINE__ )
  144. CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_time2, i_time2_id ), &
  145. & cl_name, __LINE__ )
  146. CALL chkerr( nf90_get_var ( i_file_id, i_time2_id, itime2 ), &
  147. & cl_name, __LINE__ )
  148. CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_depth, i_depth_id ), &
  149. & cl_name, __LINE__ )
  150. CALL chkerr( nf90_get_var ( i_file_id, i_depth_id, zdep ), &
  151. & cl_name, __LINE__ )
  152. CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_phi, i_phi_id ), &
  153. & cl_name, __LINE__ )
  154. CALL chkerr( nf90_get_var ( i_file_id, i_phi_id, zlat ), &
  155. & cl_name, __LINE__ )
  156. CALL chkerr( nf90_inq_varid( i_file_id, cl_fld_lam, i_lam_id ), &
  157. & cl_name, __LINE__ )
  158. CALL chkerr( nf90_get_var ( i_file_id, i_lam_id, zlon ), &
  159. & cl_name, __LINE__ )
  160. !---------------------------------------------------------------------
  161. ! Read the variables
  162. !---------------------------------------------------------------------
  163. ! ADCP format assumed
  164. cl_fld_var_u = 'u_1205'
  165. IF ( nf90_inq_varid( i_file_id, cl_fld_var_u, i_var_id ) /= nf90_noerr ) THEN
  166. ! Try again with current meter format
  167. cl_fld_var_u = 'U_320'
  168. IF ( nf90_inq_varid( i_file_id, cl_fld_var_u, i_var_id ) /= nf90_noerr ) THEN
  169. CALL fatal_error( 'Unknown format in read_taondbc', __LINE__ )
  170. ENDIF
  171. ENDIF
  172. CALL chkerr( nf90_get_var ( i_file_id, i_var_id, zu ), &
  173. & cl_name, __LINE__ )
  174. ! ADCP format assumed
  175. cl_fld_var_v = 'v_1206'
  176. IF ( nf90_inq_varid( i_file_id, cl_fld_var_v, i_var_id ) /= nf90_noerr ) THEN
  177. ! Try again with current meter format
  178. cl_fld_var_v = 'V_321'
  179. IF ( nf90_inq_varid( i_file_id, cl_fld_var_v, i_var_id ) /= nf90_noerr ) THEN
  180. CALL fatal_error( 'Unknown format in read_taondbc', __LINE__ )
  181. ENDIF
  182. ENDIF
  183. CALL chkerr( nf90_get_var ( i_file_id, i_var_id, zv ), &
  184. & cl_name, __LINE__ )
  185. !---------------------------------------------------------------------
  186. ! Read the QC attributes
  187. !---------------------------------------------------------------------
  188. ! ADCP format assumed
  189. cl_fld_var_qc_uv1 = 'QU_5205'
  190. IF ( nf90_inq_varid( i_file_id, cl_fld_var_qc_uv1, i_qc_var_id ) /= nf90_noerr ) THEN
  191. ! Try again with current meter format
  192. cl_fld_var_qc_uv1 = 'QCS_5300'
  193. IF ( nf90_inq_varid( i_file_id, cl_fld_var_qc_uv1, i_qc_var_id ) /= nf90_noerr ) THEN
  194. ! Try again with high freq. current meter format
  195. cl_fld_var_qc_uv1 = 'QCU_5320'
  196. IF ( nf90_inq_varid( i_file_id, cl_fld_var_qc_uv1, i_qc_var_id ) /= nf90_noerr ) THEN
  197. CALL fatal_error( 'Unknown format in read_taondbc', __LINE__ )
  198. ENDIF
  199. ENDIF
  200. ENDIF
  201. CALL chkerr( nf90_get_var ( i_file_id, i_qc_var_id, zuv1qc), &
  202. & cl_name, __LINE__ )
  203. ! ADCP format assumed
  204. cl_fld_var_qc_uv2 = 'QV_5206'
  205. IF ( nf90_inq_varid( i_file_id, cl_fld_var_qc_uv2, i_qc_var_id ) /= nf90_noerr ) THEN
  206. ! Try again with current meter format
  207. cl_fld_var_qc_uv2 = 'QCD_5310'
  208. IF ( nf90_inq_varid( i_file_id, cl_fld_var_qc_uv2, i_qc_var_id ) /= nf90_noerr ) THEN
  209. ! Try again with high freq. current meter format
  210. cl_fld_var_qc_uv2 = 'QCV_5321'
  211. IF ( nf90_inq_varid( i_file_id, cl_fld_var_qc_uv2, i_qc_var_id ) /= nf90_noerr ) THEN
  212. CALL fatal_error( 'Unknown format in read_taondbc', __LINE__ )
  213. ENDIF
  214. ENDIF
  215. ENDIF
  216. CALL chkerr( nf90_get_var ( i_file_id, i_qc_var_id, zuv2qc), &
  217. & cl_name, __LINE__ )
  218. !---------------------------------------------------------------------
  219. ! Close file
  220. !---------------------------------------------------------------------
  221. CALL chkerr( nf90_close( i_file_id ), cl_name, __LINE__ )
  222. !---------------------------------------------------------------------
  223. ! Convert to to 19500101 based Julian date
  224. !---------------------------------------------------------------------
  225. DO jt = 1, itim
  226. zjuld(jt) = REAL(itime(jt),wp) + REAL(itime2(jt),wp)/86400000.0_wp &
  227. & - 2433283.0_wp
  228. END DO
  229. inpfile%cdjuldref = '19500101000000'
  230. !---------------------------------------------------------------------
  231. ! Copy info to obfbdata structure
  232. !---------------------------------------------------------------------
  233. iobs = 0
  234. DO jt = 1, itim
  235. DO ja = 1, ilat
  236. DO jo = 1, ilon
  237. iobs = iobs + 1
  238. zl = zlon(jo)
  239. IF ( zl > 180.0_wp ) zl = zl - 360.0_wp
  240. IF ( zl < 0 ) THEN
  241. cew = 'w'
  242. ELSE
  243. cew = 'e'
  244. ENDIF
  245. IF ( zlat(jo) < 0 ) THEN
  246. cns = 's'
  247. ELSE
  248. cns = 'n'
  249. ENDIF
  250. WRITE(inpfile%cdwmo(iobs),'(A1,I2.2,A1,I3.3)') &
  251. & cns, ABS(NINT(zlat(ja))), cew, ABS(NINT(zl))
  252. DO jk = 1, ilev
  253. inpfile%pob(jk,iobs,1) = zu(jo,ja,jk,jt)
  254. inpfile%pob(jk,iobs,2) = zv(jo,ja,jk,jt)
  255. inpfile%pdep(jk,iobs) = zdep(jk)
  256. inpfile%ivlqc(jk,iobs,1:2) = INT( MAX( zuv1qc(jo,ja,jk,jt), zuv2qc(jo,ja,jk,jt) ) )
  257. END DO
  258. inpfile%plam(iobs) = zlon(jo)
  259. inpfile%pphi(iobs) = zlat(ja)
  260. inpfile%ptim(iobs) = zjuld(jt)
  261. END DO
  262. END DO
  263. END DO
  264. ! No position, time, depth and variable QC in input files
  265. DO jo = 1, iobs
  266. inpfile%ipqc(jo) = 1
  267. inpfile%itqc(jo) = 1
  268. inpfile%ivqc(jo,1:2) = 1
  269. DO jk = 1, ilev
  270. inpfile%idqc(jk,jo) = 1
  271. END DO
  272. END DO
  273. !---------------------------------------------------------------------
  274. ! Set the platform information
  275. !---------------------------------------------------------------------
  276. inpfile%cdtyp(:)=' 820'
  277. !---------------------------------------------------------------------
  278. ! Set QC flags for missing data and rescale to m/s
  279. !---------------------------------------------------------------------
  280. DO jo = 1, iobs
  281. DO jk = 1, ilev
  282. IF ( ( ABS(inpfile%pob(jk,jo,1)) > 10000.0_wp ) .OR. &
  283. & ( ABS(inpfile%pob(jk,jo,2)) > 10000.0_wp ) ) THEN
  284. inpfile%ivlqc(jk,jo,:) = 4
  285. inpfile%pob(jk,jo,1) = fbrmdi
  286. inpfile%pob(jk,jo,2) = fbrmdi
  287. ELSE
  288. inpfile%pob(jk,jo,1) = 0.01 * inpfile%pob(jk,jo,1)
  289. inpfile%pob(jk,jo,2) = 0.01 * inpfile%pob(jk,jo,2)
  290. ENDIF
  291. END DO
  292. END DO
  293. !---------------------------------------------------------------------
  294. ! Set file indexes
  295. !---------------------------------------------------------------------
  296. DO jo = 1, inpfile%nobs
  297. inpfile%kindex(jo) = jo
  298. END DO
  299. !---------------------------------------------------------------------
  300. ! Initialize flags since they are not in the TAO input files
  301. !---------------------------------------------------------------------
  302. inpfile%ioqcf(:,:) = 0
  303. inpfile%ipqcf(:,:) = 0
  304. inpfile%itqcf(:,:) = 0
  305. inpfile%idqcf(:,:,:) = 0
  306. inpfile%ivqcf(:,:,:) = 0
  307. inpfile%ivlqcf(:,:,:,:) = 0
  308. !---------------------------------------------------------------------
  309. ! Deallocate data
  310. !---------------------------------------------------------------------
  311. DEALLOCATE( &
  312. & zu, &
  313. & zv, &
  314. & zdep, &
  315. & zuv1qc, &
  316. & zuv2qc, &
  317. & itime, &
  318. & itime2, &
  319. & zlat, &
  320. & zlon, &
  321. & zjuld &
  322. & )
  323. END SUBROUTINE read_taondbc