obs_write.F90 35 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002
  1. MODULE obs_write
  2. !!======================================================================
  3. !! *** MODULE obs_write ***
  4. !! Observation diagnosticss: Write observation related diagnostics
  5. !!=====================================================================
  6. !!----------------------------------------------------------------------
  7. !! obs_wri_p3d : Write profile observation diagnostics in NetCDF format
  8. !! obs_wri_sla : Write SLA observation related diagnostics
  9. !! obs_wri_sst : Write SST observation related diagnostics
  10. !! obs_wri_seaice: Write seaice observation related diagnostics
  11. !! obs_wri_vel : Write velocity observation diagnostics in NetCDF format
  12. !! obs_wri_stats : Print basic statistics on the data being written out
  13. !!----------------------------------------------------------------------
  14. !! * Modules used
  15. USE par_kind, ONLY : & ! Precision variables
  16. & wp
  17. USE in_out_manager ! I/O manager
  18. USE dom_oce ! Ocean space and time domain variables
  19. USE obs_types ! Observation type integer to character translation
  20. USE julian, ONLY : & ! Julian date routines
  21. & greg2jul
  22. USE obs_utils, ONLY : & ! Observation operator utility functions
  23. & chkerr
  24. USE obs_profiles_def ! Type definitions for profiles
  25. USE obs_surf_def ! Type defintions for surface observations
  26. USE obs_fbm ! Observation feedback I/O
  27. USE obs_grid ! Grid tools
  28. USE obs_conv ! Conversion between units
  29. USE obs_const
  30. USE obs_sla_types
  31. USE obs_rot_vel ! Rotation of velocities
  32. USE obs_mpp ! MPP support routines for observation diagnostics
  33. USE lib_mpp ! MPP routines
  34. IMPLICIT NONE
  35. !! * Routine accessibility
  36. PRIVATE
  37. PUBLIC obs_wri_p3d, & ! Write profile observation related diagnostics
  38. & obs_wri_sla, & ! Write SLA observation related diagnostics
  39. & obs_wri_sst, & ! Write SST observation related diagnostics
  40. & obs_wri_sss, & ! Write SSS observation related diagnostics
  41. & obs_wri_seaice, & ! Write seaice observation related diagnostics
  42. & obs_wri_vel, & ! Write velocity observation related diagnostics
  43. & obswriinfo
  44. TYPE obswriinfo
  45. INTEGER :: inum
  46. INTEGER, POINTER, DIMENSION(:) :: ipoint
  47. CHARACTER(len=ilenname), POINTER, DIMENSION(:) :: cdname
  48. CHARACTER(len=ilenlong), POINTER, DIMENSION(:,:) :: cdlong
  49. CHARACTER(len=ilenunit), POINTER, DIMENSION(:,:) :: cdunit
  50. END TYPE obswriinfo
  51. !!----------------------------------------------------------------------
  52. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  53. !! $Id: obs_write.F90 4990 2014-12-15 16:42:49Z timgraham $
  54. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  55. !!----------------------------------------------------------------------
  56. CONTAINS
  57. SUBROUTINE obs_wri_p3d( cprefix, profdata, padd, pext )
  58. !!-----------------------------------------------------------------------
  59. !!
  60. !! *** ROUTINE obs_wri_p3d ***
  61. !!
  62. !! ** Purpose : Write temperature and salinity (profile) observation
  63. !! related diagnostics
  64. !!
  65. !! ** Method : NetCDF
  66. !!
  67. !! ** Action :
  68. !!
  69. !! History :
  70. !! ! 06-04 (A. Vidard) Original
  71. !! ! 06-04 (A. Vidard) Reformatted
  72. !! ! 06-10 (A. Weaver) Cleanup
  73. !! ! 07-01 (K. Mogensen) Use profile data types
  74. !! ! 07-03 (K. Mogensen) General handling of profiles
  75. !! ! 09-01 (K. Mogensen) New feedback format
  76. !!-----------------------------------------------------------------------
  77. !! * Modules used
  78. !! * Arguments
  79. CHARACTER(LEN=*), INTENT(IN) :: cprefix ! Prefix for output files
  80. TYPE(obs_prof), INTENT(INOUT) :: profdata ! Full set of profile data
  81. TYPE(obswriinfo), OPTIONAL :: padd ! Additional info for each variable
  82. TYPE(obswriinfo), OPTIONAL :: pext ! Extra info
  83. !! * Local declarations
  84. TYPE(obfbdata) :: fbdata
  85. CHARACTER(LEN=40) :: cfname
  86. INTEGER :: ilevel
  87. INTEGER :: jvar
  88. INTEGER :: jo
  89. INTEGER :: jk
  90. INTEGER :: ik
  91. INTEGER :: ja
  92. INTEGER :: je
  93. REAL(wp) :: zpres
  94. INTEGER :: nadd
  95. INTEGER :: next
  96. IF ( PRESENT( padd ) ) THEN
  97. nadd = padd%inum
  98. ELSE
  99. nadd = 0
  100. ENDIF
  101. IF ( PRESENT( pext ) ) THEN
  102. next = pext%inum
  103. ELSE
  104. next = 0
  105. ENDIF
  106. CALL init_obfbdata( fbdata )
  107. ! Find maximum level
  108. ilevel = 0
  109. DO jvar = 1, 2
  110. ilevel = MAX( ilevel, MAXVAL( profdata%var(jvar)%nvlidx(:) ) )
  111. END DO
  112. CALL alloc_obfbdata( fbdata, 2, profdata%nprof, ilevel, &
  113. & 1 + nadd, 1 + next, .TRUE. )
  114. fbdata%cname(1) = 'POTM'
  115. fbdata%cname(2) = 'PSAL'
  116. fbdata%coblong(1) = 'Potential temperature'
  117. fbdata%coblong(2) = 'Practical salinity'
  118. fbdata%cobunit(1) = 'Degrees centigrade'
  119. fbdata%cobunit(2) = 'PSU'
  120. fbdata%cextname(1) = 'TEMP'
  121. fbdata%cextlong(1) = 'Insitu temperature'
  122. fbdata%cextunit(1) = 'Degrees centigrade'
  123. DO je = 1, next
  124. fbdata%cextname(1+je) = pext%cdname(je)
  125. fbdata%cextlong(1+je) = pext%cdlong(je,1)
  126. fbdata%cextunit(1+je) = pext%cdunit(je,1)
  127. END DO
  128. fbdata%caddname(1) = 'Hx'
  129. fbdata%caddlong(1,1) = 'Model interpolated potential temperature'
  130. fbdata%caddlong(1,2) = 'Model interpolated practical salinity'
  131. fbdata%caddunit(1,1) = 'Degrees centigrade'
  132. fbdata%caddunit(1,2) = 'PSU'
  133. fbdata%cgrid(:) = 'T'
  134. DO ja = 1, nadd
  135. fbdata%caddname(1+ja) = padd%cdname(ja)
  136. DO jvar = 1, 2
  137. fbdata%caddlong(1+ja,jvar) = padd%cdlong(ja,jvar)
  138. fbdata%caddunit(1+ja,jvar) = padd%cdunit(ja,jvar)
  139. END DO
  140. END DO
  141. WRITE(cfname, FMT="(A,'_fdbk_',I4.4,'.nc')") TRIM(cprefix), nproc
  142. IF(lwp) THEN
  143. WRITE(numout,*)
  144. WRITE(numout,*)'obs_wri_p3d :'
  145. WRITE(numout,*)'~~~~~~~~~~~~~'
  146. WRITE(numout,*)'Writing profile feedback file : ',TRIM(cfname)
  147. ENDIF
  148. ! Transform obs_prof data structure into obfbdata structure
  149. fbdata%cdjuldref = '19500101000000'
  150. DO jo = 1, profdata%nprof
  151. fbdata%plam(jo) = profdata%rlam(jo)
  152. fbdata%pphi(jo) = profdata%rphi(jo)
  153. WRITE(fbdata%cdtyp(jo),'(I4)') profdata%ntyp(jo)
  154. fbdata%ivqc(jo,:) = profdata%ivqc(jo,:)
  155. fbdata%ivqcf(:,jo,:) = profdata%ivqcf(:,jo,:)
  156. IF ( profdata%nqc(jo) > 10 ) THEN
  157. fbdata%ioqc(jo) = 4
  158. fbdata%ioqcf(1,jo) = profdata%nqcf(1,jo)
  159. fbdata%ioqcf(2,jo) = profdata%nqc(jo) - 10
  160. ELSE
  161. fbdata%ioqc(jo) = profdata%nqc(jo)
  162. fbdata%ioqcf(:,jo) = profdata%nqcf(:,jo)
  163. ENDIF
  164. fbdata%ipqc(jo) = profdata%ipqc(jo)
  165. fbdata%ipqcf(:,jo) = profdata%ipqcf(:,jo)
  166. fbdata%itqc(jo) = profdata%itqc(jo)
  167. fbdata%itqcf(:,jo) = profdata%itqcf(:,jo)
  168. fbdata%cdwmo(jo) = profdata%cwmo(jo)
  169. fbdata%kindex(jo) = profdata%npfil(jo)
  170. DO jvar = 1, profdata%nvar
  171. IF (ln_grid_global) THEN
  172. fbdata%iobsi(jo,jvar) = profdata%mi(jo,jvar)
  173. fbdata%iobsj(jo,jvar) = profdata%mj(jo,jvar)
  174. ELSE
  175. fbdata%iobsi(jo,jvar) = mig(profdata%mi(jo,jvar))
  176. fbdata%iobsj(jo,jvar) = mjg(profdata%mj(jo,jvar))
  177. ENDIF
  178. END DO
  179. CALL greg2jul( 0, &
  180. & profdata%nmin(jo), &
  181. & profdata%nhou(jo), &
  182. & profdata%nday(jo), &
  183. & profdata%nmon(jo), &
  184. & profdata%nyea(jo), &
  185. & fbdata%ptim(jo), &
  186. & krefdate = 19500101 )
  187. ! Reform the profiles arrays for output
  188. DO jvar = 1, 2
  189. DO jk = profdata%npvsta(jo,jvar), profdata%npvend(jo,jvar)
  190. ik = profdata%var(jvar)%nvlidx(jk)
  191. fbdata%padd(ik,jo,1,jvar) = profdata%var(jvar)%vmod(jk)
  192. fbdata%pob(ik,jo,jvar) = profdata%var(jvar)%vobs(jk)
  193. fbdata%pdep(ik,jo) = profdata%var(jvar)%vdep(jk)
  194. fbdata%idqc(ik,jo) = profdata%var(jvar)%idqc(jk)
  195. fbdata%idqcf(:,ik,jo) = profdata%var(jvar)%idqcf(:,jk)
  196. IF ( profdata%var(jvar)%nvqc(jk) > 10 ) THEN
  197. fbdata%ivlqc(ik,jo,jvar) = 4
  198. fbdata%ivlqcf(1,ik,jo,jvar) = profdata%var(jvar)%nvqcf(1,jk)
  199. fbdata%ivlqcf(2,ik,jo,jvar) = profdata%var(jvar)%nvqc(jk) - 10
  200. ELSE
  201. fbdata%ivlqc(ik,jo,jvar) = profdata%var(jvar)%nvqc(jk)
  202. fbdata%ivlqcf(:,ik,jo,jvar) = profdata%var(jvar)%nvqcf(:,jk)
  203. ENDIF
  204. fbdata%iobsk(ik,jo,jvar) = profdata%var(jvar)%mvk(jk)
  205. DO ja = 1, nadd
  206. fbdata%padd(ik,jo,1+ja,jvar) = &
  207. & profdata%var(jvar)%vext(jk,padd%ipoint(ja))
  208. END DO
  209. DO je = 1, next
  210. fbdata%pext(ik,jo,1+je) = &
  211. & profdata%var(jvar)%vext(jk,pext%ipoint(je))
  212. END DO
  213. IF ( jvar == 1 ) THEN
  214. fbdata%pext(ik,jo,1) = profdata%var(jvar)%vext(jk,1)
  215. ENDIF
  216. END DO
  217. END DO
  218. END DO
  219. ! Convert insitu temperature to potential temperature using the model
  220. ! salinity if no potential temperature
  221. DO jo = 1, fbdata%nobs
  222. IF ( fbdata%pphi(jo) < 9999.0 ) THEN
  223. DO jk = 1, fbdata%nlev
  224. IF ( ( fbdata%pob(jk,jo,1) >= 9999.0 ) .AND. &
  225. & ( fbdata%pdep(jk,jo) < 9999.0 ) .AND. &
  226. & ( fbdata%padd(jk,jo,1,2) < 9999.0 ) .AND. &
  227. & ( fbdata%pext(jk,jo,1) < 9999.0 ) ) THEN
  228. zpres = dep_to_p( REAL(fbdata%pdep(jk,jo),wp), &
  229. & REAL(fbdata%pphi(jo),wp) )
  230. fbdata%pob(jk,jo,1) = potemp( &
  231. & REAL(fbdata%padd(jk,jo,1,2), wp), &
  232. & REAL(fbdata%pext(jk,jo,1), wp), &
  233. & zpres, 0.0_wp )
  234. ENDIF
  235. END DO
  236. ENDIF
  237. END DO
  238. ! Write the obfbdata structure
  239. CALL write_obfbdata( cfname, fbdata )
  240. ! Output some basic statistics
  241. CALL obs_wri_stats( fbdata )
  242. CALL dealloc_obfbdata( fbdata )
  243. END SUBROUTINE obs_wri_p3d
  244. SUBROUTINE obs_wri_sla( cprefix, sladata, padd, pext )
  245. !!-----------------------------------------------------------------------
  246. !!
  247. !! *** ROUTINE obs_wri_sla ***
  248. !!
  249. !! ** Purpose : Write SLA observation diagnostics
  250. !! related
  251. !!
  252. !! ** Method : NetCDF
  253. !!
  254. !! ** Action :
  255. !!
  256. !! ! 07-03 (K. Mogensen) Original
  257. !! ! 09-01 (K. Mogensen) New feedback format.
  258. !!-----------------------------------------------------------------------
  259. !! * Modules used
  260. IMPLICIT NONE
  261. !! * Arguments
  262. CHARACTER(LEN=*), INTENT(IN) :: cprefix ! Prefix for output files
  263. TYPE(obs_surf), INTENT(INOUT) :: sladata ! Full set of SLAa
  264. TYPE(obswriinfo), OPTIONAL :: padd ! Additional info for each variable
  265. TYPE(obswriinfo), OPTIONAL :: pext ! Extra info
  266. !! * Local declarations
  267. TYPE(obfbdata) :: fbdata
  268. CHARACTER(LEN=40) :: cfname ! netCDF filename
  269. CHARACTER(LEN=12), PARAMETER :: cpname = 'obs_wri_sla'
  270. INTEGER :: jo
  271. INTEGER :: ja
  272. INTEGER :: je
  273. INTEGER :: nadd
  274. INTEGER :: next
  275. IF ( PRESENT( padd ) ) THEN
  276. nadd = padd%inum
  277. ELSE
  278. nadd = 0
  279. ENDIF
  280. IF ( PRESENT( pext ) ) THEN
  281. next = pext%inum
  282. ELSE
  283. next = 0
  284. ENDIF
  285. CALL init_obfbdata( fbdata )
  286. CALL alloc_obfbdata( fbdata, 1, sladata%nsurf, 1, &
  287. & 2 + nadd, 1 + next, .TRUE. )
  288. fbdata%cname(1) = 'SLA'
  289. fbdata%coblong(1) = 'Sea level anomaly'
  290. fbdata%cobunit(1) = 'Metres'
  291. fbdata%cextname(1) = 'MDT'
  292. fbdata%cextlong(1) = 'Mean dynamic topography'
  293. fbdata%cextunit(1) = 'Metres'
  294. DO je = 1, next
  295. fbdata%cextname(1+je) = pext%cdname(je)
  296. fbdata%cextlong(1+je) = pext%cdlong(je,1)
  297. fbdata%cextunit(1+je) = pext%cdunit(je,1)
  298. END DO
  299. fbdata%caddname(1) = 'Hx'
  300. fbdata%caddlong(1,1) = 'Model interpolated SSH - MDT'
  301. fbdata%caddunit(1,1) = 'Metres'
  302. fbdata%caddname(2) = 'SSH'
  303. fbdata%caddlong(2,1) = 'Model Sea surface height'
  304. fbdata%caddunit(2,1) = 'Metres'
  305. fbdata%cgrid(1) = 'T'
  306. DO ja = 1, nadd
  307. fbdata%caddname(2+ja) = padd%cdname(ja)
  308. fbdata%caddlong(2+ja,1) = padd%cdlong(ja,1)
  309. fbdata%caddunit(2+ja,1) = padd%cdunit(ja,1)
  310. END DO
  311. WRITE(cfname, FMT="(A,'_fdbk_',I4.4,'.nc')") TRIM(cprefix), nproc
  312. IF(lwp) THEN
  313. WRITE(numout,*)
  314. WRITE(numout,*)'obs_wri_sla :'
  315. WRITE(numout,*)'~~~~~~~~~~~~~'
  316. WRITE(numout,*)'Writing SLA feedback file : ',TRIM(cfname)
  317. ENDIF
  318. ! Transform obs_prof data structure into obfbdata structure
  319. fbdata%cdjuldref = '19500101000000'
  320. DO jo = 1, sladata%nsurf
  321. fbdata%plam(jo) = sladata%rlam(jo)
  322. fbdata%pphi(jo) = sladata%rphi(jo)
  323. WRITE(fbdata%cdtyp(jo),'(I4)') sladata%ntyp(jo)
  324. fbdata%ivqc(jo,:) = 0
  325. fbdata%ivqcf(:,jo,:) = 0
  326. IF ( sladata%nqc(jo) > 10 ) THEN
  327. fbdata%ioqc(jo) = 4
  328. fbdata%ioqcf(1,jo) = 0
  329. fbdata%ioqcf(2,jo) = sladata%nqc(jo) - 10
  330. ELSE
  331. fbdata%ioqc(jo) = sladata%nqc(jo)
  332. fbdata%ioqcf(:,jo) = 0
  333. ENDIF
  334. fbdata%ipqc(jo) = 0
  335. fbdata%ipqcf(:,jo) = 0
  336. fbdata%itqc(jo) = 0
  337. fbdata%itqcf(:,jo) = 0
  338. fbdata%cdwmo(jo) = sladata%cwmo(jo)
  339. fbdata%kindex(jo) = sladata%nsfil(jo)
  340. IF (ln_grid_global) THEN
  341. fbdata%iobsi(jo,1) = sladata%mi(jo)
  342. fbdata%iobsj(jo,1) = sladata%mj(jo)
  343. ELSE
  344. fbdata%iobsi(jo,1) = mig(sladata%mi(jo))
  345. fbdata%iobsj(jo,1) = mjg(sladata%mj(jo))
  346. ENDIF
  347. CALL greg2jul( 0, &
  348. & sladata%nmin(jo), &
  349. & sladata%nhou(jo), &
  350. & sladata%nday(jo), &
  351. & sladata%nmon(jo), &
  352. & sladata%nyea(jo), &
  353. & fbdata%ptim(jo), &
  354. & krefdate = 19500101 )
  355. fbdata%padd(1,jo,1,1) = sladata%rmod(jo,1)
  356. fbdata%padd(1,jo,2,1) = sladata%rext(jo,1)
  357. fbdata%pob(1,jo,1) = sladata%robs(jo,1)
  358. fbdata%pdep(1,jo) = 0.0
  359. fbdata%idqc(1,jo) = 0
  360. fbdata%idqcf(:,1,jo) = 0
  361. IF ( sladata%nqc(jo) > 10 ) THEN
  362. fbdata%ivqc(jo,1) = 4
  363. fbdata%ivlqc(1,jo,1) = 4
  364. fbdata%ivlqcf(1,1,jo,1) = 0
  365. fbdata%ivlqcf(2,1,jo,1) = sladata%nqc(jo) - 10
  366. ELSE
  367. fbdata%ivqc(jo,1) = sladata%nqc(jo)
  368. fbdata%ivlqc(1,jo,1) = sladata%nqc(jo)
  369. fbdata%ivlqcf(:,1,jo,1) = 0
  370. ENDIF
  371. fbdata%iobsk(1,jo,1) = 0
  372. fbdata%pext(1,jo,1) = sladata%rext(jo,2)
  373. DO ja = 1, nadd
  374. fbdata%padd(1,jo,2+ja,1) = &
  375. & sladata%rext(jo,padd%ipoint(ja))
  376. END DO
  377. DO je = 1, next
  378. fbdata%pext(1,jo,1+je) = &
  379. & sladata%rext(jo,pext%ipoint(je))
  380. END DO
  381. END DO
  382. ! Write the obfbdata structure
  383. CALL write_obfbdata( cfname, fbdata )
  384. ! Output some basic statistics
  385. CALL obs_wri_stats( fbdata )
  386. CALL dealloc_obfbdata( fbdata )
  387. END SUBROUTINE obs_wri_sla
  388. SUBROUTINE obs_wri_sst( cprefix, sstdata, padd, pext )
  389. !!-----------------------------------------------------------------------
  390. !!
  391. !! *** ROUTINE obs_wri_sst ***
  392. !!
  393. !! ** Purpose : Write SST observation diagnostics
  394. !! related
  395. !!
  396. !! ** Method : NetCDF
  397. !!
  398. !! ** Action :
  399. !!
  400. !! ! 07-07 (S. Ricci) Original
  401. !! ! 09-01 (K. Mogensen) New feedback format.
  402. !!-----------------------------------------------------------------------
  403. !! * Modules used
  404. IMPLICIT NONE
  405. !! * Arguments
  406. CHARACTER(LEN=*), INTENT(IN) :: cprefix ! Prefix for output files
  407. TYPE(obs_surf), INTENT(INOUT) :: sstdata ! Full set of SST
  408. TYPE(obswriinfo), OPTIONAL :: padd ! Additional info for each variable
  409. TYPE(obswriinfo), OPTIONAL :: pext ! Extra info
  410. !! * Local declarations
  411. TYPE(obfbdata) :: fbdata
  412. CHARACTER(LEN=40) :: cfname ! netCDF filename
  413. CHARACTER(LEN=12), PARAMETER :: cpname = 'obs_wri_sst'
  414. INTEGER :: jo
  415. INTEGER :: ja
  416. INTEGER :: je
  417. INTEGER :: nadd
  418. INTEGER :: next
  419. IF ( PRESENT( padd ) ) THEN
  420. nadd = padd%inum
  421. ELSE
  422. nadd = 0
  423. ENDIF
  424. IF ( PRESENT( pext ) ) THEN
  425. next = pext%inum
  426. ELSE
  427. next = 0
  428. ENDIF
  429. CALL init_obfbdata( fbdata )
  430. CALL alloc_obfbdata( fbdata, 1, sstdata%nsurf, 1, &
  431. & 1 + nadd, next, .TRUE. )
  432. fbdata%cname(1) = 'SST'
  433. fbdata%coblong(1) = 'Sea surface temperature'
  434. fbdata%cobunit(1) = 'Degree centigrade'
  435. DO je = 1, next
  436. fbdata%cextname(je) = pext%cdname(je)
  437. fbdata%cextlong(je) = pext%cdlong(je,1)
  438. fbdata%cextunit(je) = pext%cdunit(je,1)
  439. END DO
  440. fbdata%caddname(1) = 'Hx'
  441. fbdata%caddlong(1,1) = 'Model interpolated SST'
  442. fbdata%caddunit(1,1) = 'Degree centigrade'
  443. fbdata%cgrid(1) = 'T'
  444. DO ja = 1, nadd
  445. fbdata%caddname(1+ja) = padd%cdname(ja)
  446. fbdata%caddlong(1+ja,1) = padd%cdlong(ja,1)
  447. fbdata%caddunit(1+ja,1) = padd%cdunit(ja,1)
  448. END DO
  449. WRITE(cfname, FMT="(A,'_fdbk_',I4.4,'.nc')") TRIM(cprefix), nproc
  450. IF(lwp) THEN
  451. WRITE(numout,*)
  452. WRITE(numout,*)'obs_wri_sst :'
  453. WRITE(numout,*)'~~~~~~~~~~~~~'
  454. WRITE(numout,*)'Writing SST feedback file : ',TRIM(cfname)
  455. ENDIF
  456. ! Transform obs_prof data structure into obfbdata structure
  457. fbdata%cdjuldref = '19500101000000'
  458. DO jo = 1, sstdata%nsurf
  459. fbdata%plam(jo) = sstdata%rlam(jo)
  460. fbdata%pphi(jo) = sstdata%rphi(jo)
  461. WRITE(fbdata%cdtyp(jo),'(I4)') sstdata%ntyp(jo)
  462. fbdata%ivqc(jo,:) = 0
  463. fbdata%ivqcf(:,jo,:) = 0
  464. IF ( sstdata%nqc(jo) > 10 ) THEN
  465. fbdata%ioqc(jo) = 4
  466. fbdata%ioqcf(1,jo) = 0
  467. fbdata%ioqcf(2,jo) = sstdata%nqc(jo) - 10
  468. ELSE
  469. fbdata%ioqc(jo) = MAX(sstdata%nqc(jo),1)
  470. fbdata%ioqcf(:,jo) = 0
  471. ENDIF
  472. fbdata%ipqc(jo) = 0
  473. fbdata%ipqcf(:,jo) = 0
  474. fbdata%itqc(jo) = 0
  475. fbdata%itqcf(:,jo) = 0
  476. fbdata%cdwmo(jo) = ''
  477. fbdata%kindex(jo) = sstdata%nsfil(jo)
  478. IF (ln_grid_global) THEN
  479. fbdata%iobsi(jo,1) = sstdata%mi(jo)
  480. fbdata%iobsj(jo,1) = sstdata%mj(jo)
  481. ELSE
  482. fbdata%iobsi(jo,1) = mig(sstdata%mi(jo))
  483. fbdata%iobsj(jo,1) = mjg(sstdata%mj(jo))
  484. ENDIF
  485. CALL greg2jul( 0, &
  486. & sstdata%nmin(jo), &
  487. & sstdata%nhou(jo), &
  488. & sstdata%nday(jo), &
  489. & sstdata%nmon(jo), &
  490. & sstdata%nyea(jo), &
  491. & fbdata%ptim(jo), &
  492. & krefdate = 19500101 )
  493. fbdata%padd(1,jo,1,1) = sstdata%rmod(jo,1)
  494. fbdata%pob(1,jo,1) = sstdata%robs(jo,1)
  495. fbdata%pdep(1,jo) = 0.0
  496. fbdata%idqc(1,jo) = 0
  497. fbdata%idqcf(:,1,jo) = 0
  498. IF ( sstdata%nqc(jo) > 10 ) THEN
  499. fbdata%ivqc(jo,1) = 4
  500. fbdata%ivlqc(1,jo,1) = 4
  501. fbdata%ivlqcf(1,1,jo,1) = 0
  502. fbdata%ivlqcf(2,1,jo,1) = sstdata%nqc(jo) - 10
  503. ELSE
  504. fbdata%ivqc(jo,1) = MAX(sstdata%nqc(jo),1)
  505. fbdata%ivlqc(1,jo,1) = MAX(sstdata%nqc(jo),1)
  506. fbdata%ivlqcf(:,1,jo,1) = 0
  507. ENDIF
  508. fbdata%iobsk(1,jo,1) = 0
  509. DO ja = 1, nadd
  510. fbdata%padd(1,jo,1+ja,1) = &
  511. & sstdata%rext(jo,padd%ipoint(ja))
  512. END DO
  513. DO je = 1, next
  514. fbdata%pext(1,jo,je) = &
  515. & sstdata%rext(jo,pext%ipoint(je))
  516. END DO
  517. END DO
  518. ! Write the obfbdata structure
  519. CALL write_obfbdata( cfname, fbdata )
  520. ! Output some basic statistics
  521. CALL obs_wri_stats( fbdata )
  522. CALL dealloc_obfbdata( fbdata )
  523. END SUBROUTINE obs_wri_sst
  524. SUBROUTINE obs_wri_sss
  525. END SUBROUTINE obs_wri_sss
  526. SUBROUTINE obs_wri_seaice( cprefix, seaicedata, padd, pext )
  527. !!-----------------------------------------------------------------------
  528. !!
  529. !! *** ROUTINE obs_wri_seaice ***
  530. !!
  531. !! ** Purpose : Write sea ice observation diagnostics
  532. !! related
  533. !!
  534. !! ** Method : NetCDF
  535. !!
  536. !! ** Action :
  537. !!
  538. !! ! 07-07 (S. Ricci) Original
  539. !! ! 09-01 (K. Mogensen) New feedback format.
  540. !!-----------------------------------------------------------------------
  541. !! * Modules used
  542. IMPLICIT NONE
  543. !! * Arguments
  544. CHARACTER(LEN=*), INTENT(IN) :: cprefix ! Prefix for output files
  545. TYPE(obs_surf), INTENT(INOUT) :: seaicedata ! Full set of sea ice
  546. TYPE(obswriinfo), OPTIONAL :: padd ! Additional info for each variable
  547. TYPE(obswriinfo), OPTIONAL :: pext ! Extra info
  548. !! * Local declarations
  549. TYPE(obfbdata) :: fbdata
  550. CHARACTER(LEN=40) :: cfname ! netCDF filename
  551. CHARACTER(LEN=12), PARAMETER :: cpname = 'obs_wri_seaice'
  552. INTEGER :: jo
  553. INTEGER :: ja
  554. INTEGER :: je
  555. INTEGER :: nadd
  556. INTEGER :: next
  557. IF ( PRESENT( padd ) ) THEN
  558. nadd = padd%inum
  559. ELSE
  560. nadd = 0
  561. ENDIF
  562. IF ( PRESENT( pext ) ) THEN
  563. next = pext%inum
  564. ELSE
  565. next = 0
  566. ENDIF
  567. CALL init_obfbdata( fbdata )
  568. CALL alloc_obfbdata( fbdata, 1, seaicedata%nsurf, 1, 1, 0, .TRUE. )
  569. fbdata%cname(1) = 'SEAICE'
  570. fbdata%coblong(1) = 'Sea ice'
  571. fbdata%cobunit(1) = 'Fraction'
  572. DO je = 1, next
  573. fbdata%cextname(je) = pext%cdname(je)
  574. fbdata%cextlong(je) = pext%cdlong(je,1)
  575. fbdata%cextunit(je) = pext%cdunit(je,1)
  576. END DO
  577. fbdata%caddname(1) = 'Hx'
  578. fbdata%caddlong(1,1) = 'Model interpolated ICE'
  579. fbdata%caddunit(1,1) = 'Fraction'
  580. fbdata%cgrid(1) = 'T'
  581. DO ja = 1, nadd
  582. fbdata%caddname(1+ja) = padd%cdname(ja)
  583. fbdata%caddlong(1+ja,1) = padd%cdlong(ja,1)
  584. fbdata%caddunit(1+ja,1) = padd%cdunit(ja,1)
  585. END DO
  586. WRITE(cfname, FMT="(A,'_fdbk_',I4.4,'.nc')") TRIM(cprefix), nproc
  587. IF(lwp) THEN
  588. WRITE(numout,*)
  589. WRITE(numout,*)'obs_wri_seaice :'
  590. WRITE(numout,*)'~~~~~~~~~~~~~~~~'
  591. WRITE(numout,*)'Writing SEAICE feedback file : ',TRIM(cfname)
  592. ENDIF
  593. ! Transform obs_prof data structure into obfbdata structure
  594. fbdata%cdjuldref = '19500101000000'
  595. DO jo = 1, seaicedata%nsurf
  596. fbdata%plam(jo) = seaicedata%rlam(jo)
  597. fbdata%pphi(jo) = seaicedata%rphi(jo)
  598. WRITE(fbdata%cdtyp(jo),'(I4)') seaicedata%ntyp(jo)
  599. fbdata%ivqc(jo,:) = 0
  600. fbdata%ivqcf(:,jo,:) = 0
  601. IF ( seaicedata%nqc(jo) > 10 ) THEN
  602. fbdata%ioqc(jo) = 4
  603. fbdata%ioqcf(1,jo) = 0
  604. fbdata%ioqcf(2,jo) = seaicedata%nqc(jo) - 10
  605. ELSE
  606. fbdata%ioqc(jo) = MAX(seaicedata%nqc(jo),1)
  607. fbdata%ioqcf(:,jo) = 0
  608. ENDIF
  609. fbdata%ipqc(jo) = 0
  610. fbdata%ipqcf(:,jo) = 0
  611. fbdata%itqc(jo) = 0
  612. fbdata%itqcf(:,jo) = 0
  613. fbdata%cdwmo(jo) = ''
  614. fbdata%kindex(jo) = seaicedata%nsfil(jo)
  615. IF (ln_grid_global) THEN
  616. fbdata%iobsi(jo,1) = seaicedata%mi(jo)
  617. fbdata%iobsj(jo,1) = seaicedata%mj(jo)
  618. ELSE
  619. fbdata%iobsi(jo,1) = mig(seaicedata%mi(jo))
  620. fbdata%iobsj(jo,1) = mjg(seaicedata%mj(jo))
  621. ENDIF
  622. CALL greg2jul( 0, &
  623. & seaicedata%nmin(jo), &
  624. & seaicedata%nhou(jo), &
  625. & seaicedata%nday(jo), &
  626. & seaicedata%nmon(jo), &
  627. & seaicedata%nyea(jo), &
  628. & fbdata%ptim(jo), &
  629. & krefdate = 19500101 )
  630. fbdata%padd(1,jo,1,1) = seaicedata%rmod(jo,1)
  631. fbdata%pob(1,jo,1) = seaicedata%robs(jo,1)
  632. fbdata%pdep(1,jo) = 0.0
  633. fbdata%idqc(1,jo) = 0
  634. fbdata%idqcf(:,1,jo) = 0
  635. IF ( seaicedata%nqc(jo) > 10 ) THEN
  636. fbdata%ivlqc(1,jo,1) = 4
  637. fbdata%ivlqcf(1,1,jo,1) = 0
  638. fbdata%ivlqcf(2,1,jo,1) = seaicedata%nqc(jo) - 10
  639. ELSE
  640. fbdata%ivlqc(1,jo,1) = MAX(seaicedata%nqc(jo),1)
  641. fbdata%ivlqcf(:,1,jo,1) = 0
  642. ENDIF
  643. fbdata%iobsk(1,jo,1) = 0
  644. DO ja = 1, nadd
  645. fbdata%padd(1,jo,1+ja,1) = &
  646. & seaicedata%rext(jo,padd%ipoint(ja))
  647. END DO
  648. DO je = 1, next
  649. fbdata%pext(1,jo,je) = &
  650. & seaicedata%rext(jo,pext%ipoint(je))
  651. END DO
  652. END DO
  653. ! Write the obfbdata structure
  654. CALL write_obfbdata( cfname, fbdata )
  655. ! Output some basic statistics
  656. CALL obs_wri_stats( fbdata )
  657. CALL dealloc_obfbdata( fbdata )
  658. END SUBROUTINE obs_wri_seaice
  659. SUBROUTINE obs_wri_vel( cprefix, profdata, k2dint, padd, pext )
  660. !!-----------------------------------------------------------------------
  661. !!
  662. !! *** ROUTINE obs_wri_vel ***
  663. !!
  664. !! ** Purpose : Write current (profile) observation
  665. !! related diagnostics
  666. !!
  667. !! ** Method : NetCDF
  668. !!
  669. !! ** Action :
  670. !!
  671. !! History :
  672. !! ! 09-01 (K. Mogensen) New feedback format routine
  673. !!-----------------------------------------------------------------------
  674. !! * Modules used
  675. !! * Arguments
  676. CHARACTER(LEN=*), INTENT(IN) :: cprefix ! Prefix for output files
  677. TYPE(obs_prof), INTENT(INOUT) :: profdata ! Full set of profile data
  678. INTEGER, INTENT(IN) :: k2dint ! Horizontal interpolation method
  679. TYPE(obswriinfo), OPTIONAL :: padd ! Additional info for each variable
  680. TYPE(obswriinfo), OPTIONAL :: pext ! Extra info
  681. !! * Local declarations
  682. TYPE(obfbdata) :: fbdata
  683. CHARACTER(LEN=40) :: cfname
  684. INTEGER :: ilevel
  685. INTEGER :: jvar
  686. INTEGER :: jk
  687. INTEGER :: ik
  688. INTEGER :: jo
  689. INTEGER :: ja
  690. INTEGER :: je
  691. INTEGER :: nadd
  692. INTEGER :: next
  693. REAL(wp) :: zpres
  694. REAL(wp), DIMENSION(:), ALLOCATABLE :: &
  695. & zu, &
  696. & zv
  697. IF ( PRESENT( padd ) ) THEN
  698. nadd = padd%inum
  699. ELSE
  700. nadd = 0
  701. ENDIF
  702. IF ( PRESENT( pext ) ) THEN
  703. next = pext%inum
  704. ELSE
  705. next = 0
  706. ENDIF
  707. CALL init_obfbdata( fbdata )
  708. ! Find maximum level
  709. ilevel = 0
  710. DO jvar = 1, 2
  711. ilevel = MAX( ilevel, MAXVAL( profdata%var(jvar)%nvlidx(:) ) )
  712. END DO
  713. CALL alloc_obfbdata( fbdata, 2, profdata%nprof, ilevel, 2, 0, .TRUE. )
  714. fbdata%cname(1) = 'UVEL'
  715. fbdata%cname(2) = 'VVEL'
  716. fbdata%coblong(1) = 'Zonal velocity'
  717. fbdata%coblong(2) = 'Meridional velocity'
  718. fbdata%cobunit(1) = 'm/s'
  719. fbdata%cobunit(2) = 'm/s'
  720. DO je = 1, next
  721. fbdata%cextname(je) = pext%cdname(je)
  722. fbdata%cextlong(je) = pext%cdlong(je,1)
  723. fbdata%cextunit(je) = pext%cdunit(je,1)
  724. END DO
  725. fbdata%caddname(1) = 'Hx'
  726. fbdata%caddlong(1,1) = 'Model interpolated zonal velocity'
  727. fbdata%caddlong(1,2) = 'Model interpolated meridional velocity'
  728. fbdata%caddunit(1,1) = 'm/s'
  729. fbdata%caddunit(1,2) = 'm/s'
  730. fbdata%caddname(2) = 'HxG'
  731. fbdata%caddlong(2,1) = 'Model interpolated zonal velocity (model grid)'
  732. fbdata%caddlong(2,2) = 'Model interpolated meridional velocity (model grid)'
  733. fbdata%caddunit(2,1) = 'm/s'
  734. fbdata%caddunit(2,2) = 'm/s'
  735. fbdata%cgrid(1) = 'U'
  736. fbdata%cgrid(2) = 'V'
  737. DO ja = 1, nadd
  738. fbdata%caddname(2+ja) = padd%cdname(ja)
  739. fbdata%caddlong(2+ja,1) = padd%cdlong(ja,1)
  740. fbdata%caddunit(2+ja,1) = padd%cdunit(ja,1)
  741. END DO
  742. WRITE(cfname, FMT="(A,'_fdbk_',I4.4,'.nc')") TRIM(cprefix), nproc
  743. IF(lwp) THEN
  744. WRITE(numout,*)
  745. WRITE(numout,*)'obs_wri_vel :'
  746. WRITE(numout,*)'~~~~~~~~~~~~~'
  747. WRITE(numout,*)'Writing velocuty feedback file : ',TRIM(cfname)
  748. ENDIF
  749. ALLOCATE( &
  750. & zu(profdata%nvprot(1)), &
  751. & zv(profdata%nvprot(2)) &
  752. & )
  753. CALL obs_rotvel( profdata, k2dint, zu, zv )
  754. ! Transform obs_prof data structure into obfbdata structure
  755. fbdata%cdjuldref = '19500101000000'
  756. DO jo = 1, profdata%nprof
  757. fbdata%plam(jo) = profdata%rlam(jo)
  758. fbdata%pphi(jo) = profdata%rphi(jo)
  759. WRITE(fbdata%cdtyp(jo),'(I4)') profdata%ntyp(jo)
  760. fbdata%ivqc(jo,:) = profdata%ivqc(jo,:)
  761. fbdata%ivqcf(:,jo,:) = profdata%ivqcf(:,jo,:)
  762. IF ( profdata%nqc(jo) > 10 ) THEN
  763. fbdata%ioqc(jo) = 4
  764. fbdata%ioqcf(1,jo) = profdata%nqcf(1,jo)
  765. fbdata%ioqcf(2,jo) = profdata%nqc(jo) - 10
  766. ELSE
  767. fbdata%ioqc(jo) = profdata%nqc(jo)
  768. fbdata%ioqcf(:,jo) = profdata%nqcf(:,jo)
  769. ENDIF
  770. fbdata%ipqc(jo) = profdata%ipqc(jo)
  771. fbdata%ipqcf(:,jo) = profdata%ipqcf(:,jo)
  772. fbdata%itqc(jo) = profdata%itqc(jo)
  773. fbdata%itqcf(:,jo) = profdata%itqcf(:,jo)
  774. fbdata%cdwmo(jo) = profdata%cwmo(jo)
  775. fbdata%kindex(jo) = profdata%npfil(jo)
  776. DO jvar = 1, profdata%nvar
  777. IF (ln_grid_global) THEN
  778. fbdata%iobsi(jo,jvar) = profdata%mi(jo,jvar)
  779. fbdata%iobsj(jo,jvar) = profdata%mj(jo,jvar)
  780. ELSE
  781. fbdata%iobsi(jo,jvar) = mig(profdata%mi(jo,jvar))
  782. fbdata%iobsj(jo,jvar) = mjg(profdata%mj(jo,jvar))
  783. ENDIF
  784. END DO
  785. CALL greg2jul( 0, &
  786. & profdata%nmin(jo), &
  787. & profdata%nhou(jo), &
  788. & profdata%nday(jo), &
  789. & profdata%nmon(jo), &
  790. & profdata%nyea(jo), &
  791. & fbdata%ptim(jo), &
  792. & krefdate = 19500101 )
  793. ! Reform the profiles arrays for output
  794. DO jvar = 1, 2
  795. DO jk = profdata%npvsta(jo,jvar), profdata%npvend(jo,jvar)
  796. ik = profdata%var(jvar)%nvlidx(jk)
  797. IF ( jvar == 1 ) THEN
  798. fbdata%padd(ik,jo,1,jvar) = zu(jk)
  799. ELSE
  800. fbdata%padd(ik,jo,1,jvar) = zv(jk)
  801. ENDIF
  802. fbdata%padd(ik,jo,2,jvar) = profdata%var(jvar)%vmod(jk)
  803. fbdata%pob(ik,jo,jvar) = profdata%var(jvar)%vobs(jk)
  804. fbdata%pdep(ik,jo) = profdata%var(jvar)%vdep(jk)
  805. fbdata%idqc(ik,jo) = profdata%var(jvar)%idqc(jk)
  806. fbdata%idqcf(:,ik,jo) = profdata%var(jvar)%idqcf(:,jk)
  807. IF ( profdata%var(jvar)%nvqc(jk) > 10 ) THEN
  808. fbdata%ivlqc(ik,jo,jvar) = 4
  809. fbdata%ivlqcf(1,ik,jo,jvar) = profdata%var(jvar)%nvqcf(1,jk)
  810. fbdata%ivlqcf(2,ik,jo,jvar) = profdata%var(jvar)%nvqc(jk) - 10
  811. ELSE
  812. fbdata%ivlqc(ik,jo,jvar) = profdata%var(jvar)%nvqc(jk)
  813. fbdata%ivlqcf(:,ik,jo,jvar) = profdata%var(jvar)%nvqcf(:,jk)
  814. ENDIF
  815. fbdata%iobsk(ik,jo,jvar) = profdata%var(jvar)%mvk(jk)
  816. DO ja = 1, nadd
  817. fbdata%padd(ik,jo,2+ja,jvar) = &
  818. & profdata%var(jvar)%vext(jk,padd%ipoint(ja))
  819. END DO
  820. DO je = 1, next
  821. fbdata%pext(ik,jo,je) = &
  822. & profdata%var(jvar)%vext(jk,pext%ipoint(je))
  823. END DO
  824. END DO
  825. END DO
  826. END DO
  827. ! Write the obfbdata structure
  828. CALL write_obfbdata( cfname, fbdata )
  829. ! Output some basic statistics
  830. CALL obs_wri_stats( fbdata )
  831. CALL dealloc_obfbdata( fbdata )
  832. DEALLOCATE( &
  833. & zu, &
  834. & zv &
  835. & )
  836. END SUBROUTINE obs_wri_vel
  837. SUBROUTINE obs_wri_stats( fbdata )
  838. !!-----------------------------------------------------------------------
  839. !!
  840. !! *** ROUTINE obs_wri_stats ***
  841. !!
  842. !! ** Purpose : Output some basic statistics of the data being written out
  843. !!
  844. !! ** Method :
  845. !!
  846. !! ** Action :
  847. !!
  848. !! ! 2014-08 (D. Lea) Initial version
  849. !!-----------------------------------------------------------------------
  850. !! * Arguments
  851. TYPE(obfbdata) :: fbdata
  852. !! * Local declarations
  853. INTEGER :: jvar
  854. INTEGER :: jo
  855. INTEGER :: jk
  856. ! INTEGER :: nlev
  857. ! INTEGER :: nlevmpp
  858. ! INTEGER :: nobsmpp
  859. INTEGER :: numgoodobs
  860. INTEGER :: numgoodobsmpp
  861. REAL(wp) :: zsumx
  862. REAL(wp) :: zsumx2
  863. REAL(wp) :: zomb
  864. IF (lwp) THEN
  865. WRITE(numout,*) ''
  866. WRITE(numout,*) 'obs_wri_stats :'
  867. WRITE(numout,*) '~~~~~~~~~~~~~~~'
  868. ENDIF
  869. DO jvar = 1, fbdata%nvar
  870. zsumx=0.0_wp
  871. zsumx2=0.0_wp
  872. numgoodobs=0
  873. DO jo = 1, fbdata%nobs
  874. DO jk = 1, fbdata%nlev
  875. IF ( ( fbdata%pob(jk,jo,jvar) < 9999.0 ) .AND. &
  876. & ( fbdata%pdep(jk,jo) < 9999.0 ) .AND. &
  877. & ( fbdata%padd(jk,jo,1,jvar) < 9999.0 ) ) THEN
  878. zomb=fbdata%pob(jk, jo, jvar)-fbdata%padd(jk, jo, 1, jvar)
  879. zsumx=zsumx+zomb
  880. zsumx2=zsumx2+zomb**2
  881. numgoodobs=numgoodobs+1
  882. ENDIF
  883. ENDDO
  884. ENDDO
  885. CALL obs_mpp_sum_integer( numgoodobs, numgoodobsmpp )
  886. CALL mpp_sum(zsumx)
  887. CALL mpp_sum(zsumx2)
  888. IF (lwp) THEN
  889. WRITE(numout,*) 'Type: ',fbdata%cname(jvar),' Total number of good observations: ',numgoodobsmpp
  890. WRITE(numout,*) 'Overall mean obs minus model of the good observations: ',zsumx/numgoodobsmpp
  891. WRITE(numout,*) 'Overall RMS obs minus model of the good observations: ',sqrt( zsumx2/numgoodobsmpp )
  892. WRITE(numout,*) ''
  893. ENDIF
  894. ENDDO
  895. END SUBROUTINE obs_wri_stats
  896. END MODULE obs_write