obs_read_seaice.F90 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465
  1. MODULE obs_read_seaice
  2. !!======================================================================
  3. !! *** MODULE obs_read_seaice ***
  4. !! Observation diagnostics: Read the along track SEAICE data from
  5. !! GHRSST or any SEAICE data from feedback files
  6. !!======================================================================
  7. !!----------------------------------------------------------------------
  8. !! obs_rea_seaice : Driver for reading seaice data from the GHRSST/feedback
  9. !!----------------------------------------------------------------------
  10. !! * Modules used
  11. USE par_kind ! Precision variables
  12. USE in_out_manager ! I/O manager
  13. USE dom_oce ! Ocean space and time domain variables
  14. USE obs_mpp ! MPP support routines for observation diagnostics
  15. USE julian ! Julian date routines
  16. USE obs_utils ! Observation operator utility functions
  17. USE obs_grid ! Grid search
  18. USE obs_sort ! Sorting observation arrays
  19. USE obs_surf_def ! Surface observation definitions
  20. USE obs_types ! Observation type definitions
  21. USE obs_seaice_io ! I/O for seaice files
  22. USE iom ! I/O of fields for Reynolds data
  23. USE netcdf ! NetCDF library
  24. IMPLICIT NONE
  25. !! * Routine accessibility
  26. PRIVATE
  27. PUBLIC obs_rea_seaice ! Read the seaice observations from the point data
  28. !!----------------------------------------------------------------------
  29. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  30. !! $Id: obs_read_seaice.F90 4990 2014-12-15 16:42:49Z timgraham $
  31. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  32. !!----------------------------------------------------------------------
  33. CONTAINS
  34. SUBROUTINE obs_rea_seaice( kformat, &
  35. & seaicedata, knumfiles, cfilenames, &
  36. & kvars, kextr, kstp, ddobsini, ddobsend, &
  37. & ldignmis, ldmod )
  38. !!---------------------------------------------------------------------
  39. !!
  40. !! *** ROUTINE obs_rea_seaice ***
  41. !!
  42. !! ** Purpose : Read from file the seaice data
  43. !!
  44. !! ** Method : Depending on kformat either AVISO or
  45. !! feedback data files are read
  46. !!
  47. !! ** Action :
  48. !!
  49. !!
  50. !! History :
  51. !! ! : 2009-01 (K. Mogensen) Initial version based on old versions
  52. !!----------------------------------------------------------------------
  53. !! * Modules used
  54. !! * Arguments
  55. INTEGER :: kformat ! Format of input data
  56. ! ! 0: Feedback
  57. ! ! 1: GHRSST
  58. TYPE(obs_surf), INTENT(INOUT) :: &
  59. & seaicedata ! seaice data to be read
  60. INTEGER, INTENT(IN) :: knumfiles ! Number of corio format files to read in
  61. CHARACTER(LEN=128), INTENT(IN) :: cfilenames(knumfiles) ! File names to read in
  62. INTEGER, INTENT(IN) :: kvars ! Number of variables in seaicedata
  63. INTEGER, INTENT(IN) :: kextr ! Number of extra fields for each var in seaicedata
  64. INTEGER, INTENT(IN) :: kstp ! Ocean time-step index
  65. LOGICAL, INTENT(IN) :: ldignmis ! Ignore missing files
  66. LOGICAL, INTENT(IN) :: ldmod ! Initialize model from input data
  67. REAL(KIND=dp), INTENT(IN) :: ddobsini ! Obs. ini time in YYYYMMDD.HHMMSS
  68. REAL(KIND=dp), INTENT(IN) :: ddobsend ! Obs. end time in YYYYMMDD.HHMMSS
  69. !! * Local declarations
  70. CHARACTER(LEN=14), PARAMETER :: cpname='obs_rea_seaice'
  71. INTEGER :: ji
  72. INTEGER :: jj
  73. INTEGER :: jk
  74. INTEGER :: iflag
  75. INTEGER :: inobf
  76. INTEGER :: i_file_id
  77. INTEGER :: inowin
  78. INTEGER :: iyea
  79. INTEGER :: imon
  80. INTEGER :: iday
  81. INTEGER :: ihou
  82. INTEGER :: imin
  83. INTEGER :: isec
  84. INTEGER, DIMENSION(knumfiles) :: &
  85. & irefdate
  86. INTEGER :: iobsmpp
  87. INTEGER, PARAMETER :: iseaicemaxtype = 1024
  88. INTEGER, DIMENSION(0:iseaicemaxtype) :: &
  89. & ityp, &
  90. & itypmpp
  91. INTEGER, DIMENSION(:), ALLOCATABLE :: &
  92. & iobsi, &
  93. & iobsj, &
  94. & iproc, &
  95. & iindx, &
  96. & ifileidx, &
  97. & iseaiceidx
  98. INTEGER :: itype
  99. REAL(wp), DIMENSION(:), ALLOCATABLE :: &
  100. & zphi, &
  101. & zlam
  102. real(wp), DIMENSION(:), ALLOCATABLE :: &
  103. & zdat
  104. LOGICAL :: llvalprof
  105. TYPE(obfbdata), POINTER, DIMENSION(:) :: &
  106. & inpfiles
  107. real(wp), DIMENSION(knumfiles) :: &
  108. & djulini, &
  109. & djulend
  110. INTEGER :: iobs
  111. INTEGER :: iobstot
  112. INTEGER :: ios
  113. INTEGER :: ioserrcount
  114. CHARACTER(len=8) :: cl_refdate
  115. ! Local initialization
  116. iobs = 0
  117. !-----------------------------------------------------------------------
  118. ! Check data the model part is just with feedback data files
  119. !-----------------------------------------------------------------------
  120. IF ( ldmod .AND. ( kformat /= 0 ) ) THEN
  121. CALL ctl_stop( 'Model can only be read from feedback data' )
  122. RETURN
  123. ENDIF
  124. !-----------------------------------------------------------------------
  125. ! Count the number of files needed and allocate the obfbdata type
  126. !-----------------------------------------------------------------------
  127. inobf = knumfiles
  128. ALLOCATE( inpfiles(inobf) )
  129. seaice_files : DO jj = 1, inobf
  130. !---------------------------------------------------------------------
  131. ! Prints
  132. !---------------------------------------------------------------------
  133. IF(lwp) THEN
  134. WRITE(numout,*)
  135. WRITE(numout,*) ' obs_rea_seaice : Reading from file = ', &
  136. & TRIM( TRIM( cfilenames(jj) ) )
  137. WRITE(numout,*) ' ~~~~~~~~~~~~~~'
  138. WRITE(numout,*)
  139. ENDIF
  140. !---------------------------------------------------------------------
  141. ! Initialization: Open file and get dimensions only
  142. !---------------------------------------------------------------------
  143. iflag = nf90_open( TRIM( TRIM( cfilenames(jj) ) ), nf90_nowrite, &
  144. & i_file_id )
  145. IF ( iflag /= nf90_noerr ) THEN
  146. IF ( ldignmis ) THEN
  147. inpfiles(jj)%nobs = 0
  148. CALL ctl_warn( 'File ' // TRIM( TRIM( cfilenames(jj) ) ) // &
  149. & ' not found' )
  150. ELSE
  151. CALL ctl_stop( 'File ' // TRIM( TRIM( cfilenames(jj) ) ) // &
  152. & ' not found' )
  153. ENDIF
  154. ELSE
  155. !------------------------------------------------------------------
  156. ! Close the file since it is opened in read_proffile
  157. !------------------------------------------------------------------
  158. iflag = nf90_close( i_file_id )
  159. !------------------------------------------------------------------
  160. ! Read the profile file into inpfiles
  161. !------------------------------------------------------------------
  162. IF ( kformat == 0 ) THEN
  163. CALL init_obfbdata( inpfiles(jj) )
  164. IF(lwp) THEN
  165. WRITE(numout,*)
  166. WRITE(numout,*)'Reading from feedback file :', &
  167. & TRIM( cfilenames(jj) )
  168. ENDIF
  169. CALL read_obfbdata( TRIM( cfilenames(jj) ), inpfiles(jj), &
  170. & ldgrid = .TRUE. )
  171. IF ( ldmod .AND. ( ( inpfiles(jj)%nadd == 0 ) .OR.&
  172. & ( inpfiles(jj)%next < 2 ) ) ) THEN
  173. CALL ctl_stop( 'Model not in input data' )
  174. RETURN
  175. ENDIF
  176. ELSEIF ( kformat == 1) THEN
  177. CALL read_seaice( TRIM( cfilenames(jj) ), inpfiles(jj), &
  178. & numout, lwp, .TRUE. )
  179. ELSE
  180. CALL ctl_stop( 'File format unknown' )
  181. ENDIF
  182. !------------------------------------------------------------------
  183. ! Change longitude (-180,180)
  184. !------------------------------------------------------------------
  185. DO ji = 1, inpfiles(jj)%nobs
  186. IF ( inpfiles(jj)%plam(ji) < -180. ) &
  187. & inpfiles(jj)%plam(ji) = inpfiles(jj)%plam(ji) + 360.
  188. IF ( inpfiles(jj)%plam(ji) > 180. ) &
  189. & inpfiles(jj)%plam(ji) = inpfiles(jj)%plam(ji) - 360.
  190. END DO
  191. !------------------------------------------------------------------
  192. ! Calculate the date (change eventually)
  193. !------------------------------------------------------------------
  194. cl_refdate=inpfiles(jj)%cdjuldref(1:8)
  195. READ(cl_refdate,'(I8)') irefdate(jj)
  196. CALL ddatetoymdhms( ddobsini, iyea, imon, iday, ihou, imin, isec )
  197. CALL greg2jul( isec, imin, ihou, iday, imon, iyea, djulini(jj), &
  198. & krefdate = irefdate(jj) )
  199. CALL ddatetoymdhms( ddobsend, iyea, imon, iday, ihou, imin, isec )
  200. CALL greg2jul( isec, imin, ihou, iday, imon, iyea, djulend(jj), &
  201. & krefdate = irefdate(jj) )
  202. IF ( inpfiles(jj)%nobs > 0 ) THEN
  203. inpfiles(jj)%iproc = -1
  204. inpfiles(jj)%iobsi = -1
  205. inpfiles(jj)%iobsj = -1
  206. ENDIF
  207. inowin = 0
  208. DO ji = 1, inpfiles(jj)%nobs
  209. IF ( ( inpfiles(jj)%ptim(ji) > djulini(jj) ) .AND. &
  210. & ( inpfiles(jj)%ptim(ji) <= djulend(jj) ) ) THEN
  211. inowin = inowin + 1
  212. ENDIF
  213. END DO
  214. ALLOCATE( zlam(inowin) )
  215. ALLOCATE( zphi(inowin) )
  216. ALLOCATE( iobsi(inowin) )
  217. ALLOCATE( iobsj(inowin) )
  218. ALLOCATE( iproc(inowin) )
  219. inowin = 0
  220. DO ji = 1, inpfiles(jj)%nobs
  221. IF ( ( inpfiles(jj)%ptim(ji) > djulini(jj) ) .AND. &
  222. & ( inpfiles(jj)%ptim(ji) <= djulend(jj) ) ) THEN
  223. inowin = inowin + 1
  224. zlam(inowin) = inpfiles(jj)%plam(ji)
  225. zphi(inowin) = inpfiles(jj)%pphi(ji)
  226. ENDIF
  227. END DO
  228. CALL obs_grid_search( inowin, zlam, zphi, iobsi, iobsj, iproc, 'T' )
  229. inowin = 0
  230. DO ji = 1, inpfiles(jj)%nobs
  231. IF ( ( inpfiles(jj)%ptim(ji) > djulini(jj) ) .AND. &
  232. & ( inpfiles(jj)%ptim(ji) <= djulend(jj) ) ) THEN
  233. inowin = inowin + 1
  234. inpfiles(jj)%iproc(ji,1) = iproc(inowin)
  235. inpfiles(jj)%iobsi(ji,1) = iobsi(inowin)
  236. inpfiles(jj)%iobsj(ji,1) = iobsj(inowin)
  237. ENDIF
  238. END DO
  239. DEALLOCATE( zlam, zphi, iobsi, iobsj, iproc )
  240. DO ji = 1, inpfiles(jj)%nobs
  241. IF ( ( inpfiles(jj)%ptim(ji) > djulini(jj) ) .AND. &
  242. & ( inpfiles(jj)%ptim(ji) <= djulend(jj) ) ) THEN
  243. IF ( nproc == 0 ) THEN
  244. IF ( inpfiles(jj)%iproc(ji,1) > nproc ) CYCLE
  245. ELSE
  246. IF ( inpfiles(jj)%iproc(ji,1) /= nproc ) CYCLE
  247. ENDIF
  248. llvalprof = .FALSE.
  249. IF ( ( inpfiles(jj)%ivlqc(1,ji,1) == 1 ) .OR. &
  250. & ( inpfiles(jj)%ivlqc(1,ji,1) == 2 ) ) THEN
  251. iobs = iobs + 1
  252. ENDIF
  253. ENDIF
  254. END DO
  255. ENDIF
  256. END DO seaice_files
  257. !-----------------------------------------------------------------------
  258. ! Get the time ordered indices of the input data
  259. !-----------------------------------------------------------------------
  260. !---------------------------------------------------------------------
  261. ! Loop over input data files to count total number of profiles
  262. !---------------------------------------------------------------------
  263. iobstot = 0
  264. DO jj = 1, inobf
  265. DO ji = 1, inpfiles(jj)%nobs
  266. IF ( ( inpfiles(jj)%ptim(ji) > djulini(jj) ) .AND. &
  267. & ( inpfiles(jj)%ptim(ji) <= djulend(jj) ) ) THEN
  268. iobstot = iobstot + 1
  269. ENDIF
  270. END DO
  271. END DO
  272. ALLOCATE( iindx(iobstot), ifileidx(iobstot), &
  273. & iseaiceidx(iobstot), zdat(iobstot) )
  274. jk = 0
  275. DO jj = 1, inobf
  276. DO ji = 1, inpfiles(jj)%nobs
  277. IF ( ( inpfiles(jj)%ptim(ji) > djulini(jj) ) .AND. &
  278. & ( inpfiles(jj)%ptim(ji) <= djulend(jj) ) ) THEN
  279. jk = jk + 1
  280. ifileidx(jk) = jj
  281. iseaiceidx(jk) = ji
  282. zdat(jk) = inpfiles(jj)%ptim(ji)
  283. ENDIF
  284. END DO
  285. END DO
  286. CALL sort_dp_indx( iobstot, &
  287. & zdat, &
  288. & iindx )
  289. CALL obs_surf_alloc( seaicedata, iobs, &
  290. kvars, kextr, kstp, jpi, jpj )
  291. ! * Read obs/positions, QC, all variable and assign to seaicedata
  292. iobs = 0
  293. ityp (:) = 0
  294. itypmpp(:) = 0
  295. ioserrcount=0
  296. DO jk = 1, iobstot
  297. jj = ifileidx(iindx(jk))
  298. ji = iseaiceidx(iindx(jk))
  299. IF ( ( inpfiles(jj)%ptim(ji) > djulini(jj) ) .AND. &
  300. & ( inpfiles(jj)%ptim(ji) <= djulend(jj) ) ) THEN
  301. IF ( nproc == 0 ) THEN
  302. IF ( inpfiles(jj)%iproc(ji,1) > nproc ) CYCLE
  303. ELSE
  304. IF ( inpfiles(jj)%iproc(ji,1) /= nproc ) CYCLE
  305. ENDIF
  306. ! Set observation information
  307. IF ( ( inpfiles(jj)%ivlqc(1,ji,1) == 1 ) .OR. &
  308. & ( inpfiles(jj)%ivlqc(1,ji,1) == 2 ) ) THEN
  309. iobs = iobs + 1
  310. CALL jul2greg( isec, &
  311. & imin, &
  312. & ihou, &
  313. & iday, &
  314. & imon, &
  315. & iyea, &
  316. & inpfiles(jj)%ptim(ji), &
  317. & irefdate(jj) )
  318. ! seaice time coordinates
  319. seaicedata%nyea(iobs) = iyea
  320. seaicedata%nmon(iobs) = imon
  321. seaicedata%nday(iobs) = iday
  322. seaicedata%nhou(iobs) = ihou
  323. seaicedata%nmin(iobs) = imin
  324. ! seaice space coordinates
  325. seaicedata%rlam(iobs) = inpfiles(jj)%plam(ji)
  326. seaicedata%rphi(iobs) = inpfiles(jj)%pphi(ji)
  327. ! Coordinate search parameters
  328. seaicedata%mi (iobs) = inpfiles(jj)%iobsi(ji,1)
  329. seaicedata%mj (iobs) = inpfiles(jj)%iobsj(ji,1)
  330. ! Instrument type
  331. READ( inpfiles(jj)%cdtyp(ji), '(I4)', IOSTAT = ios, ERR = 901 ) itype
  332. 901 IF ( ios /= 0 ) THEN
  333. IF (ioserrcount == 0) CALL ctl_warn ( 'Problem converting an instrument type to integer. Setting type to zero' )
  334. ioserrcount = ioserrcount + 1
  335. itype = 0
  336. ENDIF
  337. seaicedata%ntyp(iobs) = itype
  338. IF ( itype < iseaicemaxtype + 1 ) THEN
  339. ityp(itype+1) = ityp(itype+1) + 1
  340. ELSE
  341. IF(lwp)WRITE(numout,*)'WARNING:Increase iseaicemaxtype in ',&
  342. & cpname
  343. ENDIF
  344. ! Bookkeeping data to match observations
  345. seaicedata%nsidx(iobs) = iobs
  346. seaicedata%nsfil(iobs) = iindx(jk)
  347. ! QC flags
  348. seaicedata%nqc(iobs) = inpfiles(jj)%ivqc(ji,1)
  349. ! Observed value
  350. seaicedata%robs(iobs,1) = inpfiles(jj)%pob(1,ji,1)
  351. ! Model and MDT is set to fbrmdi unless read from file
  352. IF ( ldmod ) THEN
  353. seaicedata%rmod(iobs,1) = inpfiles(jj)%padd(1,ji,1,1)
  354. ELSE
  355. seaicedata%rmod(iobs,1) = fbrmdi
  356. ENDIF
  357. ENDIF
  358. ENDIF
  359. END DO
  360. !-----------------------------------------------------------------------
  361. ! Sum up over processors
  362. !-----------------------------------------------------------------------
  363. CALL obs_mpp_sum_integer( iobs, iobsmpp )
  364. !-----------------------------------------------------------------------
  365. ! Output number of observations.
  366. !-----------------------------------------------------------------------
  367. IF (lwp) THEN
  368. WRITE(numout,*)
  369. WRITE(numout,'(1X,A)')'Seaice data types'
  370. WRITE(numout,'(1X,A)')'-----------------'
  371. DO jj = 1,8
  372. IF ( itypmpp(jj) > 0 ) THEN
  373. WRITE(numout,'(1X,A4,I4,A3,I10)')'Type ', jj,' = ',itypmpp(jj)
  374. ENDIF
  375. END DO
  376. WRITE(numout,'(1X,A50)')'--------------------------------------------------'
  377. WRITE(numout,'(1X,A40,I10)')'Total = ',iobsmpp
  378. WRITE(numout,*)
  379. ENDIF
  380. !-----------------------------------------------------------------------
  381. ! Deallocate temporary data
  382. !-----------------------------------------------------------------------
  383. DEALLOCATE( ifileidx, iseaiceidx, zdat )
  384. !-----------------------------------------------------------------------
  385. ! Deallocate input data
  386. !-----------------------------------------------------------------------
  387. DO jj = 1, inobf
  388. CALL dealloc_obfbdata( inpfiles(jj) )
  389. END DO
  390. DEALLOCATE( inpfiles )
  391. END SUBROUTINE obs_rea_seaice
  392. END MODULE obs_read_seaice