obs_fbm.F90 89 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261
  1. MODULE obs_fbm
  2. !!======================================================================
  3. !! *** MODULE obs_fbm ***
  4. !! Observation operators : I/O + tools for feedback files
  5. !!======================================================================
  6. !! History :
  7. !! ! 08-11 (K. Mogensen) Initial version
  8. !!----------------------------------------------------------------------
  9. !!----------------------------------------------------------------------
  10. !! init_obfbdata : Initialize sizes in obfbdata structure
  11. !! alloc_obfbdata : Allocate data in an obfbdata structure
  12. !! dealloc_obfbdata : Dellocate data in an obfbdata structure
  13. !! copy_obfbdata : Copy an obfbdata structure
  14. !! subsamp_obfbdata : Sumsample an obfbdata structure
  15. !! merge_obfbdata : Merge multiple obfbdata structures into an one.
  16. !! write_obfbdata : Write an obfbdata structure into a netCDF file.
  17. !! read_obfbdata : Read an obfbdata structure from a netCDF file.
  18. !!----------------------------------------------------------------------
  19. USE netcdf
  20. USE obs_utils ! Various utilities for observation operators
  21. IMPLICIT NONE
  22. PUBLIC
  23. ! Type kinds for feedback data.
  24. INTEGER, PARAMETER :: fbsp = SELECTED_REAL_KIND( 6, 37) !: single precision
  25. INTEGER, PARAMETER :: fbdp = SELECTED_REAL_KIND(12,307) !: double precision
  26. ! Parameters for string lengths.
  27. INTEGER, PARAMETER :: ilenwmo = 8 !: Length of station identifier
  28. INTEGER, PARAMETER :: ilentyp = 4 !: Length of type
  29. INTEGER, PARAMETER :: ilenname = 8 !: Length of variable names
  30. INTEGER, PARAMETER :: ilengrid = 1 !: Grid (e.g. 'T') length
  31. INTEGER, PARAMETER :: ilenjuld = 14 !: Lenght of reference julian date
  32. INTEGER, PARAMETER :: idefnqcf = 2 !: Default number of words in QC
  33. ! flags
  34. INTEGER, PARAMETER :: ilenlong = 128 !: Length of long name
  35. INTEGER, PARAMETER :: ilenunit = 32 !: Length of units
  36. ! Missinge data indicators
  37. INTEGER, PARAMETER :: fbimdi = -99999 !: Integers
  38. REAL(fbsp), PARAMETER :: fbrmdi = 99999 !: Reals
  39. ! Output stream choice
  40. LOGICAL :: ln_cl4 = .FALSE. !: Logical switch for
  41. !: class 4 file outputs
  42. ! Main data structure for observation feedback data.
  43. TYPE obfbdata
  44. LOGICAL :: lalloc !: Allocation status for data
  45. LOGICAL :: lgrid !: Include grid search info
  46. INTEGER :: nvar !: Number of variables
  47. INTEGER :: nobs !: Number of observations
  48. INTEGER :: nlev !: Number of levels
  49. INTEGER :: nadd !: Number of additional entries
  50. INTEGER :: next !: Number of extra variables
  51. INTEGER :: nqcf !: Number of words per qc flag
  52. CHARACTER(LEN=ilenwmo), DIMENSION(:), POINTER :: &
  53. & cdwmo !: Identifier
  54. CHARACTER(LEN=ilentyp), DIMENSION(:), POINTER :: &
  55. & cdtyp !: Instrument type
  56. CHARACTER(LEN=ilenjuld) :: &
  57. & cdjuldref !: Julian date reference
  58. INTEGER, DIMENSION(:), POINTER :: &
  59. & kindex !: Index of observations in the original file
  60. INTEGER, DIMENSION(:), POINTER :: &
  61. & ioqc, & !: Observation QC
  62. & ipqc, & !: Position QC
  63. & itqc !: Time QC
  64. INTEGER, DIMENSION(:,:), POINTER :: &
  65. & ioqcf, & !: Observation QC flags
  66. & ipqcf, & !: Position QC flags
  67. & itqcf !: Time QC flags
  68. INTEGER, DIMENSION(:,:), POINTER :: &
  69. & idqc !: Depth QC
  70. INTEGER, DIMENSION(:,:,:), POINTER :: &
  71. & idqcf !: Depth QC flags
  72. REAL(KIND=fbdp), DIMENSION(:), POINTER :: &
  73. & plam, & !: Longitude
  74. & pphi, & !: Latitude
  75. & ptim !: Time
  76. REAL(KIND=fbsp), DIMENSION(:,:), POINTER :: &
  77. & pdep !: Depth
  78. CHARACTER(LEN=ilenname), DIMENSION(:), POINTER :: &
  79. & cname !: Name of variable
  80. REAL(fbsp), DIMENSION(:,:,:), POINTER :: &
  81. & pob !: Observation
  82. CHARACTER(LEN=ilenlong), DIMENSION(:), POINTER :: &
  83. & coblong !: Observation long name (for output)
  84. CHARACTER(LEN=ilenunit), DIMENSION(:), POINTER :: &
  85. & cobunit !: Observation units (for output)
  86. INTEGER, DIMENSION(:,:), POINTER :: &
  87. & ivqc !: Variable QC
  88. INTEGER, DIMENSION(:,:,:), POINTER :: &
  89. & ivqcf !: Variable QC flags
  90. INTEGER, DIMENSION(:,:,:), POINTER :: &
  91. & ivlqc !: Variable level QC
  92. INTEGER, DIMENSION(:,:,:,:), POINTER :: &
  93. & ivlqcf !: Variable level QC flags
  94. INTEGER, DIMENSION(:,:), POINTER :: &
  95. & iproc, & !: Processor of obs (no I/O for this variable).
  96. & iobsi, & !: Global i index
  97. & iobsj !: Global j index
  98. INTEGER, DIMENSION(:,:,:), POINTER :: &
  99. & iobsk !: k index
  100. CHARACTER(LEN=ilengrid), DIMENSION(:), POINTER :: &
  101. & cgrid !: Grid for this variable
  102. CHARACTER(LEN=ilenname), DIMENSION(:), POINTER :: &
  103. & caddname !: Additional entries names
  104. CHARACTER(LEN=ilenlong), DIMENSION(:,:), POINTER :: &
  105. & caddlong !: Additional entries long name (for output)
  106. CHARACTER(LEN=ilenunit), DIMENSION(:,:), POINTER :: &
  107. & caddunit !: Additional entries units (for output)
  108. REAL(fbsp), DIMENSION(:,:,:,:) , POINTER :: &
  109. & padd !: Additional entries
  110. CHARACTER(LEN=ilenname), DIMENSION(:), POINTER :: &
  111. & cextname !: Extra variables names
  112. CHARACTER(LEN=ilenlong), DIMENSION(:), POINTER :: &
  113. & cextlong !: Extra variables long name (for output)
  114. CHARACTER(LEN=ilenunit), DIMENSION(:), POINTER :: &
  115. & cextunit !: Extra variables units (for output)
  116. REAL(fbsp), DIMENSION(:,:,:) , POINTER :: &
  117. & pext !: Extra variables
  118. END TYPE obfbdata
  119. PRIVATE putvaratt_obfbdata
  120. !!----------------------------------------------------------------------
  121. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  122. !! $Id: obs_fbm.F90 4245 2013-11-19 11:19:21Z cetlod $
  123. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  124. !!----------------------------------------------------------------------
  125. CONTAINS
  126. SUBROUTINE init_obfbdata( fbdata )
  127. !!----------------------------------------------------------------------
  128. !! *** ROUTINE init_obfbdata ***
  129. !!
  130. !! ** Purpose : Initialize sizes in obfbdata structure
  131. !!
  132. !! ** Method :
  133. !!
  134. !! ** Action :
  135. !!
  136. !!----------------------------------------------------------------------
  137. !! * Arguments
  138. TYPE(obfbdata) :: fbdata ! obsfbdata structure
  139. fbdata%nvar = 0
  140. fbdata%nobs = 0
  141. fbdata%nlev = 0
  142. fbdata%nadd = 0
  143. fbdata%next = 0
  144. fbdata%nqcf = idefnqcf
  145. fbdata%lalloc = .FALSE.
  146. fbdata%lgrid = .FALSE.
  147. END SUBROUTINE init_obfbdata
  148. SUBROUTINE alloc_obfbdata( fbdata, kvar, kobs, klev, kadd, kext, lgrid, &
  149. & kqcf)
  150. !!----------------------------------------------------------------------
  151. !! *** ROUTINE alloc_obfbdata ***
  152. !!
  153. !! ** Purpose : Allocate data in an obfbdata structure
  154. !!
  155. !! ** Method :
  156. !!
  157. !! ** Action :
  158. !!
  159. !!----------------------------------------------------------------------
  160. !! * Arguments
  161. TYPE(obfbdata) :: fbdata ! obsfbdata structure to be allocated
  162. INTEGER, INTENT(IN) :: kvar ! Number of variables
  163. INTEGER, INTENT(IN) :: kobs ! Number of observations
  164. INTEGER, INTENT(IN) :: klev ! Number of levels
  165. INTEGER, INTENT(IN) :: kadd ! Number of additional entries
  166. INTEGER, INTENT(IN) :: kext ! Number of extra variables
  167. LOGICAL, INTENT(IN) :: lgrid ! Include grid search information
  168. INTEGER, OPTIONAL :: kqcf ! Number of words for QC flags
  169. !! * Local variables
  170. INTEGER :: ji
  171. INTEGER :: jv
  172. ! Check allocation status and deallocate previous allocated structures
  173. IF ( fbdata%lalloc ) THEN
  174. CALL dealloc_obfbdata( fbdata )
  175. ENDIF
  176. ! Set dimensions
  177. fbdata%lalloc = .TRUE.
  178. fbdata%nvar = kvar
  179. fbdata%nobs = kobs
  180. fbdata%nlev = MAX( klev, 1 )
  181. fbdata%nadd = kadd
  182. fbdata%next = kext
  183. IF ( PRESENT(kqcf) ) THEN
  184. fbdata%nqcf = kqcf
  185. ELSE
  186. fbdata%nqcf = idefnqcf
  187. ENDIF
  188. ! Set data not depending on number of observations
  189. fbdata%cdjuldref = REPEAT( 'X', ilenjuld )
  190. ! Allocate and initialize standard data
  191. ALLOCATE( &
  192. & fbdata%cname(fbdata%nvar), &
  193. & fbdata%coblong(fbdata%nvar), &
  194. & fbdata%cobunit(fbdata%nvar) &
  195. & )
  196. DO ji = 1, fbdata%nvar
  197. WRITE(fbdata%cname(ji),'(A,I2.2)')'V_',ji
  198. fbdata%coblong(ji) = REPEAT( ' ', ilenlong )
  199. fbdata%cobunit(ji) = REPEAT( ' ', ilenunit )
  200. END DO
  201. ! Optionally also store grid search information
  202. IF ( lgrid ) THEN
  203. ALLOCATE ( &
  204. & fbdata%cgrid(fbdata%nvar) &
  205. & )
  206. fbdata%cgrid(:) = REPEAT( 'X', ilengrid )
  207. fbdata%lgrid = .TRUE.
  208. ENDIF
  209. ! Allocate and initialize additional entries if present
  210. IF ( fbdata%nadd > 0 ) THEN
  211. ALLOCATE( &
  212. & fbdata%caddname(fbdata%nadd), &
  213. & fbdata%caddlong(fbdata%nadd, fbdata%nvar), &
  214. & fbdata%caddunit(fbdata%nadd, fbdata%nvar) &
  215. & )
  216. DO ji = 1, fbdata%nadd
  217. WRITE(fbdata%caddname(ji),'(A,I2.2)')'A',ji
  218. END DO
  219. DO jv = 1, fbdata%nvar
  220. DO ji = 1, fbdata%nadd
  221. fbdata%caddlong(ji,jv) = REPEAT( ' ', ilenlong )
  222. fbdata%caddunit(ji,jv) = REPEAT( ' ', ilenunit )
  223. END DO
  224. END DO
  225. ENDIF
  226. ! Allocate and initialize additional variables if present
  227. IF ( fbdata%next > 0 ) THEN
  228. ALLOCATE( &
  229. & fbdata%cextname(fbdata%next), &
  230. & fbdata%cextlong(fbdata%next), &
  231. & fbdata%cextunit(fbdata%next) &
  232. & )
  233. DO ji = 1, fbdata%next
  234. WRITE(fbdata%cextname(ji),'(A,I2.2)')'E_',ji
  235. fbdata%cextlong(ji) = REPEAT( ' ', ilenlong )
  236. fbdata%cextunit(ji) = REPEAT( ' ', ilenunit )
  237. END DO
  238. ENDIF
  239. ! Data depending on number of observations is only allocated if nobs>0
  240. IF ( fbdata%nobs > 0 ) THEN
  241. ALLOCATE( &
  242. & fbdata%cdwmo(fbdata%nobs), &
  243. & fbdata%cdtyp(fbdata%nobs), &
  244. & fbdata%ioqc(fbdata%nobs), &
  245. & fbdata%ioqcf(fbdata%nqcf,fbdata%nobs), &
  246. & fbdata%ipqc(fbdata%nobs), &
  247. & fbdata%ipqcf(fbdata%nqcf,fbdata%nobs), &
  248. & fbdata%itqc(fbdata%nobs), &
  249. & fbdata%itqcf(fbdata%nqcf,fbdata%nobs), &
  250. & fbdata%idqc(fbdata%nlev,fbdata%nobs), &
  251. & fbdata%idqcf(fbdata%nqcf,fbdata%nlev,fbdata%nobs), &
  252. & fbdata%plam(fbdata%nobs), &
  253. & fbdata%pphi(fbdata%nobs), &
  254. & fbdata%pdep(fbdata%nlev,fbdata%nobs), &
  255. & fbdata%ptim(fbdata%nobs), &
  256. & fbdata%kindex(fbdata%nobs), &
  257. & fbdata%ivqc(fbdata%nobs,fbdata%nvar), &
  258. & fbdata%ivqcf(fbdata%nqcf,fbdata%nobs,fbdata%nvar), &
  259. & fbdata%ivlqc(fbdata%nlev,fbdata%nobs,fbdata%nvar), &
  260. & fbdata%ivlqcf(fbdata%nqcf,fbdata%nlev,fbdata%nobs,fbdata%nvar), &
  261. & fbdata%pob(fbdata%nlev,fbdata%nobs,fbdata%nvar) &
  262. & )
  263. fbdata%kindex(:) = fbimdi
  264. fbdata%cdwmo(:) = REPEAT( 'X', ilenwmo )
  265. fbdata%cdtyp(:) = REPEAT( 'X', ilentyp )
  266. fbdata%ioqc(:) = fbimdi
  267. fbdata%ioqcf(:,:) = fbimdi
  268. fbdata%ipqc(:) = fbimdi
  269. fbdata%ipqcf(:,:) = fbimdi
  270. fbdata%itqc(:) = fbimdi
  271. fbdata%itqcf(:,:) = fbimdi
  272. fbdata%idqc(:,:) = fbimdi
  273. fbdata%idqcf(:,:,:) = fbimdi
  274. fbdata%plam(:) = fbrmdi
  275. fbdata%pphi(:) = fbrmdi
  276. fbdata%pdep(:,:) = fbrmdi
  277. fbdata%ptim(:) = fbrmdi
  278. fbdata%ivqc(:,:) = fbimdi
  279. fbdata%ivqcf(:,:,:) = fbimdi
  280. fbdata%ivlqc(:,:,:) = fbimdi
  281. fbdata%ivlqcf(:,:,:,:) = fbimdi
  282. fbdata%pob(:,:,:) = fbrmdi
  283. ! Optionally also store grid search information
  284. IF ( lgrid ) THEN
  285. ALLOCATE ( &
  286. & fbdata%iproc(fbdata%nobs,fbdata%nvar), &
  287. & fbdata%iobsi(fbdata%nobs,fbdata%nvar), &
  288. & fbdata%iobsj(fbdata%nobs,fbdata%nvar), &
  289. & fbdata%iobsk(fbdata%nlev,fbdata%nobs,fbdata%nvar) &
  290. & )
  291. fbdata%iproc(:,:) = fbimdi
  292. fbdata%iobsi(:,:) = fbimdi
  293. fbdata%iobsj(:,:) = fbimdi
  294. fbdata%iobsk(:,:,:) = fbimdi
  295. fbdata%lgrid = .TRUE.
  296. ENDIF
  297. ! Allocate and initialize additional entries if present
  298. IF ( fbdata%nadd > 0 ) THEN
  299. ALLOCATE( &
  300. & fbdata%padd(fbdata%nlev,fbdata%nobs,fbdata%nadd,fbdata%nvar) &
  301. & )
  302. fbdata%padd(:,:,:,:) = fbrmdi
  303. ENDIF
  304. ! Allocate and initialize additional variables if present
  305. IF ( fbdata%next > 0 ) THEN
  306. ALLOCATE( &
  307. & fbdata%pext(fbdata%nlev,fbdata%nobs,fbdata%next) &
  308. & )
  309. fbdata%pext(:,:,:) = fbrmdi
  310. ENDIF
  311. ENDIF
  312. END SUBROUTINE alloc_obfbdata
  313. SUBROUTINE dealloc_obfbdata( fbdata )
  314. !!----------------------------------------------------------------------
  315. !! *** ROUTINE dealloc_obfbdata ***
  316. !!
  317. !! ** Purpose : Deallocate data in an obfbdata strucure
  318. !!
  319. !! ** Method :
  320. !!
  321. !! ** Action :
  322. !!
  323. !!----------------------------------------------------------------------
  324. !! * Arguments
  325. TYPE(obfbdata) :: fbdata ! obsfbdata structure
  326. ! Deallocate data
  327. DEALLOCATE( &
  328. & fbdata%cname, &
  329. & fbdata%coblong,&
  330. & fbdata%cobunit &
  331. & )
  332. ! Deallocate optional grid search information
  333. IF ( fbdata%lgrid ) THEN
  334. DEALLOCATE ( &
  335. & fbdata%cgrid &
  336. & )
  337. ENDIF
  338. ! Deallocate additional entries
  339. IF ( fbdata%nadd > 0 ) THEN
  340. DEALLOCATE( &
  341. & fbdata%caddname, &
  342. & fbdata%caddlong, &
  343. & fbdata%caddunit &
  344. & )
  345. ENDIF
  346. ! Deallocate extra variables
  347. IF ( fbdata%next > 0 ) THEN
  348. DEALLOCATE( &
  349. & fbdata%cextname, &
  350. & fbdata%cextlong, &
  351. & fbdata%cextunit &
  352. & )
  353. ENDIF
  354. ! Deallocate arrays depending on number of obs (if nobs>0 only).
  355. IF ( fbdata%nobs > 0 ) THEN
  356. DEALLOCATE( &
  357. & fbdata%cdwmo, &
  358. & fbdata%cdtyp, &
  359. & fbdata%ioqc, &
  360. & fbdata%ioqcf, &
  361. & fbdata%ipqc, &
  362. & fbdata%ipqcf, &
  363. & fbdata%itqc, &
  364. & fbdata%itqcf, &
  365. & fbdata%idqc, &
  366. & fbdata%idqcf, &
  367. & fbdata%plam, &
  368. & fbdata%pphi, &
  369. & fbdata%pdep, &
  370. & fbdata%ptim, &
  371. & fbdata%kindex, &
  372. & fbdata%ivqc, &
  373. & fbdata%ivqcf, &
  374. & fbdata%ivlqc, &
  375. & fbdata%ivlqcf, &
  376. & fbdata%pob &
  377. & )
  378. ! Deallocate optional grid search information
  379. IF ( fbdata%lgrid ) THEN
  380. DEALLOCATE ( &
  381. & fbdata%iproc, &
  382. & fbdata%iobsi, &
  383. & fbdata%iobsj, &
  384. & fbdata%iobsk &
  385. & )
  386. ENDIF
  387. ! Deallocate additional entries
  388. IF ( fbdata%nadd > 0 ) THEN
  389. DEALLOCATE( &
  390. & fbdata%padd &
  391. & )
  392. ENDIF
  393. ! Deallocate extra variables
  394. IF ( fbdata%next > 0 ) THEN
  395. DEALLOCATE( &
  396. & fbdata%pext &
  397. & )
  398. ENDIF
  399. ENDIF
  400. ! Reset arrays sizes
  401. fbdata%lalloc = .FALSE.
  402. fbdata%lgrid = .FALSE.
  403. fbdata%nvar = 0
  404. fbdata%nobs = 0
  405. fbdata%nlev = 0
  406. fbdata%nadd = 0
  407. fbdata%next = 0
  408. END SUBROUTINE dealloc_obfbdata
  409. SUBROUTINE copy_obfbdata( fbdata1, fbdata2, kadd, kext, lgrid, kqcf )
  410. !!----------------------------------------------------------------------
  411. !! *** ROUTINE copy_obfbdata ***
  412. !!
  413. !! ** Purpose : Copy an obfbdata structure
  414. !!
  415. !! ** Method : Copy all data from fbdata1 to fbdata2
  416. !! If fbdata2 is allocated it needs to be compliant
  417. !! with fbdata1.
  418. !! Additional entries can be added by setting nadd
  419. !! Additional extra fields can be added by setting next
  420. !! Grid information can be included with lgrid=.true.
  421. !!
  422. !! ** Action :
  423. !!
  424. !!----------------------------------------------------------------------
  425. !! * Arguments
  426. TYPE(obfbdata) :: fbdata1 ! Input obsfbdata structure
  427. TYPE(obfbdata) :: fbdata2 ! Output obsfbdata structure
  428. INTEGER, INTENT(IN), OPTIONAL :: kadd ! Number of additional entries
  429. INTEGER, INTENT(IN), OPTIONAL :: kext ! Number of extra variables
  430. INTEGER, INTENT(IN), OPTIONAL :: kqcf ! Number of words per qc flags
  431. LOGICAL, OPTIONAL :: lgrid ! Grid info on output file
  432. !! * Local variables
  433. INTEGER :: nadd
  434. INTEGER :: next
  435. INTEGER :: nqcf
  436. LOGICAL :: llgrid
  437. INTEGER :: jv
  438. INTEGER :: je
  439. INTEGER :: ji
  440. INTEGER :: jk
  441. INTEGER :: jq
  442. ! Check allocation status of fbdata1
  443. IF ( .NOT. fbdata1%lalloc ) THEN
  444. CALL fatal_error( 'copy_obfbdata: input data not allocated', &
  445. & __LINE__ )
  446. ENDIF
  447. ! If nadd,next not specified use the ones from fbdata1
  448. ! Otherwise check that they have large than the original ones
  449. IF ( PRESENT(kadd) ) THEN
  450. nadd = kadd
  451. IF ( nadd < fbdata1%nadd ) THEN
  452. CALL warning ( 'copy_obfbdata: ' // &
  453. & 'nadd smaller than input nadd', __LINE__ )
  454. ENDIF
  455. ELSE
  456. nadd = fbdata1%nadd
  457. ENDIF
  458. IF ( PRESENT(kext) ) THEN
  459. next = kext
  460. IF ( next < fbdata1%next ) THEN
  461. CALL fatal_error( 'copy_obfbdata: ' // &
  462. & 'next smaller than input next', __LINE__ )
  463. ENDIF
  464. ELSE
  465. next = fbdata1%next
  466. ENDIF
  467. IF ( PRESENT(lgrid) ) THEN
  468. llgrid = lgrid
  469. IF ( fbdata1%lgrid .AND. (.NOT. llgrid) ) THEN
  470. CALL fatal_error( 'copy_obfbdata: ' // &
  471. & 'switching off grid info not possible', &
  472. & __LINE__ )
  473. ENDIF
  474. ELSE
  475. llgrid = fbdata1%lgrid
  476. ENDIF
  477. IF ( PRESENT(kqcf) ) THEN
  478. nqcf = kqcf
  479. IF ( nqcf < fbdata1%nqcf ) THEN
  480. CALL fatal_error( 'copy_obfbdata: ' // &
  481. & 'nqcf smaller than input nqcf', __LINE__ )
  482. ENDIF
  483. ELSE
  484. nqcf = fbdata1%nqcf
  485. ENDIF
  486. ! Check allocation status of fbdata2 and
  487. ! a) check that it conforms in size if already allocated
  488. ! b) allocate it if not already allocated
  489. IF ( fbdata2%lalloc ) THEN
  490. IF ( fbdata1%nvar > fbdata2%nvar ) THEN
  491. CALL fatal_error( 'copy_obfbdata: ' // &
  492. & 'output kvar smaller than input kvar', __LINE__ )
  493. ENDIF
  494. IF ( fbdata1%nobs > fbdata2%nobs ) THEN
  495. CALL fatal_error( 'copy_obfbdata: ' // &
  496. & 'output kobs smaller than input kobs', __LINE__ )
  497. ENDIF
  498. IF ( fbdata1%nlev > fbdata2%nlev ) THEN
  499. CALL fatal_error( 'copy_obfbdata: ' // &
  500. & 'output klev smaller than input klev', __LINE__ )
  501. ENDIF
  502. IF ( fbdata1%nadd > fbdata2%nadd ) THEN
  503. CALL warning ( 'copy_obfbdata: ' // &
  504. & 'output nadd smaller than input nadd', __LINE__ )
  505. ENDIF
  506. IF ( fbdata1%next > fbdata2%next ) THEN
  507. CALL fatal_error( 'copy_obfbdata: ' // &
  508. & 'output next smaller than input next', __LINE__ )
  509. ENDIF
  510. IF ( fbdata1%lgrid .NEQV. fbdata2%lgrid ) THEN
  511. CALL fatal_error( 'copy_obfbdata: ' // &
  512. & 'lgrid inconsistent', __LINE__ )
  513. ENDIF
  514. IF ( fbdata1%next > fbdata2%next ) THEN
  515. CALL fatal_error( 'copy_obfbdata: ' // &
  516. & 'output next smaller than input next', __LINE__ )
  517. ENDIF
  518. IF ( fbdata1%nqcf > fbdata2%nqcf ) THEN
  519. CALL fatal_error( 'copy_obfbdata: ' // &
  520. & 'output smaller than input kext', __LINE__ )
  521. ENDIF
  522. ELSE
  523. CALL alloc_obfbdata( fbdata2, fbdata1%nvar, fbdata1%nobs, &
  524. & fbdata1%nlev, nadd, next, llgrid, kqcf = nqcf )
  525. ENDIF
  526. ! Copy the header data
  527. fbdata2%cdjuldref = fbdata1%cdjuldref
  528. DO ji = 1, fbdata1%nobs
  529. fbdata2%cdwmo(ji) = fbdata1%cdwmo(ji)
  530. fbdata2%cdtyp(ji) = fbdata1%cdtyp(ji)
  531. fbdata2%ioqc(ji) = fbdata1%ioqc(ji)
  532. fbdata2%ipqc(ji) = fbdata1%ipqc(ji)
  533. fbdata2%itqc(ji) = fbdata1%itqc(ji)
  534. fbdata2%plam(ji) = fbdata1%plam(ji)
  535. fbdata2%pphi(ji) = fbdata1%pphi(ji)
  536. fbdata2%ptim(ji) = fbdata1%ptim(ji)
  537. fbdata2%kindex(ji) = fbdata1%kindex(ji)
  538. DO jq = 1, fbdata1%nqcf
  539. fbdata2%ioqcf(jq,ji) = fbdata1%ioqcf(jq,ji)
  540. fbdata2%ipqcf(jq,ji) = fbdata1%ipqcf(jq,ji)
  541. fbdata2%itqcf(jq,ji) = fbdata1%itqcf(jq,ji)
  542. END DO
  543. DO jk = 1, fbdata1%nlev
  544. fbdata2%idqc(jk,ji) = fbdata1%idqc(jk,ji)
  545. fbdata2%pdep(jk,ji) = fbdata1%pdep(jk,ji)
  546. DO jq = 1, fbdata1%nqcf
  547. fbdata2%idqcf(jq,jk,ji) = fbdata1%idqcf(jq,jk,ji)
  548. END DO
  549. END DO
  550. END DO
  551. ! Copy the variable data
  552. DO jv = 1, fbdata1%nvar
  553. fbdata2%cname(jv) = fbdata1%cname(jv)
  554. fbdata2%coblong(jv) = fbdata1%coblong(jv)
  555. fbdata2%cobunit(jv) = fbdata1%cobunit(jv)
  556. DO ji = 1, fbdata1%nobs
  557. fbdata2%ivqc(ji,jv) = fbdata1%ivqc(ji,jv)
  558. DO jq = 1, fbdata1%nqcf
  559. fbdata2%ivqcf(jq,ji,jv) = fbdata1%ivqcf(jq,ji,jv)
  560. END DO
  561. DO jk = 1, fbdata1%nlev
  562. fbdata2%ivlqc(jk,ji,jv) = fbdata1%ivlqc(jk,ji,jv)
  563. fbdata2%pob(jk,ji,jv) = fbdata1%pob(jk,ji,jv)
  564. DO jq = 1, fbdata1%nqcf
  565. fbdata2%ivlqcf(jq,jk,ji,jv) = fbdata1%ivlqcf(jq,jk,ji,jv)
  566. END DO
  567. END DO
  568. END DO
  569. END DO
  570. ! Copy grid information
  571. IF ( fbdata1%lgrid ) THEN
  572. DO jv = 1, fbdata1%nvar
  573. fbdata2%cgrid(jv) = fbdata1%cgrid(jv)
  574. DO ji = 1, fbdata1%nobs
  575. fbdata2%iproc(ji,jv) = fbdata1%iproc(ji,jv)
  576. fbdata2%iobsi(ji,jv) = fbdata1%iobsi(ji,jv)
  577. fbdata2%iobsj(ji,jv) = fbdata1%iobsj(ji,jv)
  578. DO jk = 1, fbdata1%nlev
  579. fbdata2%iobsk(jk,ji,jv) = fbdata1%iobsk(jk,ji,jv)
  580. END DO
  581. END DO
  582. END DO
  583. ENDIF
  584. ! Copy additional information
  585. DO je = 1, MIN( fbdata1%nadd, fbdata2%nadd )
  586. fbdata2%caddname(je) = fbdata1%caddname(je)
  587. END DO
  588. DO jv = 1, fbdata1%nvar
  589. DO je = 1, MIN( fbdata1%nadd, fbdata2%nadd )
  590. fbdata2%caddlong(je,jv) = fbdata1%caddlong(je,jv)
  591. fbdata2%caddunit(je,jv) = fbdata1%caddunit(je,jv)
  592. DO ji = 1, fbdata1%nobs
  593. DO jk = 1, fbdata1%nlev
  594. fbdata2%padd(jk,ji,je,jv) = fbdata1%padd(jk,ji,je,jv)
  595. END DO
  596. END DO
  597. END DO
  598. END DO
  599. ! Copy extra information
  600. DO je = 1, fbdata1%next
  601. fbdata2%cextname(je) = fbdata1%cextname(je)
  602. fbdata2%cextlong(je) = fbdata1%cextlong(je)
  603. fbdata2%cextunit(je) = fbdata1%cextunit(je)
  604. END DO
  605. DO je = 1, fbdata1%next
  606. DO ji = 1, fbdata1%nobs
  607. DO jk = 1, fbdata1%nlev
  608. fbdata2%pext(jk,ji,je) = fbdata1%pext(jk,ji,je)
  609. END DO
  610. END DO
  611. END DO
  612. END SUBROUTINE copy_obfbdata
  613. SUBROUTINE subsamp_obfbdata( fbdata1, fbdata2, llvalid )
  614. !!----------------------------------------------------------------------
  615. !! *** ROUTINE susbamp_obfbdata ***
  616. !!
  617. !! ** Purpose : Subsample an obfbdata structure based on the
  618. !! logical mask.
  619. !!
  620. !! ** Method : Copy all data from fbdata1 to fbdata2 if
  621. !! llvalid(obs)==true
  622. !!
  623. !! ** Action :
  624. !!
  625. !!----------------------------------------------------------------------
  626. !! * Arguments
  627. TYPE(obfbdata) :: fbdata1 ! Input obsfbdata structure
  628. TYPE(obfbdata) :: fbdata2 ! Output obsfbdata structure
  629. LOGICAL, DIMENSION(fbdata1%nobs) :: llvalid ! Grid info on output file
  630. !! * Local variables
  631. INTEGER :: nobs
  632. INTEGER :: jv
  633. INTEGER :: je
  634. INTEGER :: ji
  635. INTEGER :: jk
  636. INTEGER :: jq
  637. INTEGER :: ij
  638. ! Check allocation status of fbdata1
  639. IF ( .NOT. fbdata1%lalloc ) THEN
  640. CALL fatal_error( 'copy_obfbdata: input data not allocated', &
  641. & __LINE__ )
  642. ENDIF
  643. ! Check allocation status of fbdata2 and abort if already allocated
  644. IF ( fbdata2%lalloc ) THEN
  645. CALL fatal_error( 'subsample_obfbdata: ' // &
  646. & 'fbdata2 already allocated', __LINE__ )
  647. ENDIF
  648. ! Count number of subsampled observations
  649. nobs = COUNT(llvalid)
  650. ! Allocate new data structure
  651. CALL alloc_obfbdata( fbdata2, fbdata1%nvar, nobs, &
  652. & fbdata1%nlev, fbdata1%nadd, fbdata1%next, &
  653. & fbdata1%lgrid, kqcf = fbdata1%nqcf )
  654. ! Copy the header data
  655. fbdata2%cdjuldref = fbdata1%cdjuldref
  656. ij = 0
  657. DO ji = 1, fbdata1%nobs
  658. IF ( llvalid(ji) ) THEN
  659. ij = ij +1
  660. fbdata2%cdwmo(ij) = fbdata1%cdwmo(ji)
  661. fbdata2%cdtyp(ij) = fbdata1%cdtyp(ji)
  662. fbdata2%ioqc(ij) = fbdata1%ioqc(ji)
  663. fbdata2%ipqc(ij) = fbdata1%ipqc(ji)
  664. fbdata2%itqc(ij) = fbdata1%itqc(ji)
  665. fbdata2%plam(ij) = fbdata1%plam(ji)
  666. fbdata2%pphi(ij) = fbdata1%pphi(ji)
  667. fbdata2%ptim(ij) = fbdata1%ptim(ji)
  668. fbdata2%kindex(ij) = fbdata1%kindex(ji)
  669. DO jq = 1, fbdata1%nqcf
  670. fbdata2%ioqcf(jq,ij) = fbdata1%ioqcf(jq,ji)
  671. fbdata2%ipqcf(jq,ij) = fbdata1%ipqcf(jq,ji)
  672. fbdata2%itqcf(jq,ij) = fbdata1%itqcf(jq,ji)
  673. END DO
  674. DO jk = 1, fbdata1%nlev
  675. fbdata2%idqc(jk,ij) = fbdata1%idqc(jk,ji)
  676. fbdata2%pdep(jk,ij) = fbdata1%pdep(jk,ji)
  677. DO jq = 1, fbdata1%nqcf
  678. fbdata2%idqcf(jq,jk,ij) = fbdata1%idqcf(jq,jk,ji)
  679. END DO
  680. END DO
  681. ENDIF
  682. END DO
  683. ! Copy the variable data
  684. DO jv = 1, fbdata1%nvar
  685. fbdata2%cname(jv) = fbdata1%cname(jv)
  686. fbdata2%coblong(jv) = fbdata1%coblong(jv)
  687. fbdata2%cobunit(jv) = fbdata1%cobunit(jv)
  688. ij = 0
  689. DO ji = 1, fbdata1%nobs
  690. IF ( llvalid(ji) ) THEN
  691. ij = ij + 1
  692. fbdata2%ivqc(ij,jv) = fbdata1%ivqc(ji,jv)
  693. DO jq = 1, fbdata1%nqcf
  694. fbdata2%ivqcf(jq,ij,jv) = fbdata1%ivqcf(jq,ji,jv)
  695. END DO
  696. DO jk = 1, fbdata1%nlev
  697. fbdata2%ivlqc(jk,ij,jv) = fbdata1%ivlqc(jk,ji,jv)
  698. fbdata2%pob(jk,ij,jv) = fbdata1%pob(jk,ji,jv)
  699. DO jq = 1, fbdata1%nqcf
  700. fbdata2%ivlqcf(jq,jk,ij,jv) = fbdata1%ivlqcf(jq,jk,ji,jv)
  701. END DO
  702. END DO
  703. ENDIF
  704. END DO
  705. END DO
  706. ! Copy grid information
  707. IF ( fbdata1%lgrid ) THEN
  708. DO jv = 1, fbdata1%nvar
  709. fbdata2%cgrid(jv) = fbdata1%cgrid(jv)
  710. ij = 0
  711. DO ji = 1, fbdata1%nobs
  712. IF ( llvalid(ji) ) THEN
  713. ij = ij + 1
  714. fbdata2%iproc(ij,jv) = fbdata1%iproc(ji,jv)
  715. fbdata2%iobsi(ij,jv) = fbdata1%iobsi(ji,jv)
  716. fbdata2%iobsj(ij,jv) = fbdata1%iobsj(ji,jv)
  717. DO jk = 1, fbdata1%nlev
  718. fbdata2%iobsk(jk,ij,jv) = fbdata1%iobsk(jk,ji,jv)
  719. END DO
  720. ENDIF
  721. END DO
  722. END DO
  723. ENDIF
  724. ! Copy additional information
  725. DO je = 1, fbdata1%nadd
  726. fbdata2%caddname(je) = fbdata1%caddname(je)
  727. END DO
  728. DO jv = 1, fbdata1%nvar
  729. DO je = 1, fbdata1%nadd
  730. fbdata2%caddlong(je,jv) = fbdata1%caddlong(je,jv)
  731. fbdata2%caddunit(je,jv) = fbdata1%caddunit(je,jv)
  732. ij = 0
  733. DO ji = 1, fbdata1%nobs
  734. IF ( llvalid(ji) ) THEN
  735. ij = ij + 1
  736. DO jk = 1, fbdata1%nlev
  737. fbdata2%padd(jk,ij,je,jv) = fbdata1%padd(jk,ji,je,jv)
  738. END DO
  739. ENDIF
  740. END DO
  741. END DO
  742. END DO
  743. ! Copy extra information
  744. DO je = 1, fbdata1%next
  745. fbdata2%cextname(je) = fbdata1%cextname(je)
  746. fbdata2%cextlong(je) = fbdata1%cextlong(je)
  747. fbdata2%cextunit(je) = fbdata1%cextunit(je)
  748. END DO
  749. DO je = 1, fbdata1%next
  750. ij = 0
  751. DO ji = 1, fbdata1%nobs
  752. IF ( llvalid(ji) ) THEN
  753. ij = ij + 1
  754. DO jk = 1, fbdata1%nlev
  755. fbdata2%pext(jk,ij,je) = fbdata1%pext(jk,ji,je)
  756. END DO
  757. ENDIF
  758. END DO
  759. END DO
  760. END SUBROUTINE subsamp_obfbdata
  761. SUBROUTINE merge_obfbdata( nsets, fbdatain, fbdataout, iset, inum, iind )
  762. !!----------------------------------------------------------------------
  763. !! *** ROUTINE merge_obfbdata ***
  764. !!
  765. !! ** Purpose : Merge multiple obfbdata structures into an one.
  766. !!
  767. !! ** Method : The order of elements is based on the indices in
  768. !! iind.
  769. !! All input data are assumed to be consistent. This
  770. !! is assumed to be checked before calling this routine.
  771. !! Likewise output data is assume to be consistent as
  772. !! well without error checking.
  773. !!
  774. !! ** Action :
  775. !!
  776. !!----------------------------------------------------------------------
  777. !! * Arguments
  778. INTEGER, INTENT(IN):: nsets ! Number of input data sets
  779. TYPE(obfbdata), DIMENSION(nsets) :: fbdatain ! Input obsfbdata structure
  780. TYPE(obfbdata) :: fbdataout ! Output obsfbdata structure
  781. INTEGER, INTENT(IN), DIMENSION(fbdataout%nobs) :: &
  782. & iset ! Set number for a given obs.
  783. INTEGER, INTENT(IN), DIMENSION(fbdataout%nobs) :: &
  784. & inum ! Number within set for an obs
  785. INTEGER, INTENT(IN), DIMENSION(fbdataout%nobs) :: &
  786. & iind ! Indices for copying.
  787. !! * Local variables
  788. INTEGER :: js
  789. INTEGER :: jo
  790. INTEGER :: jv
  791. INTEGER :: je
  792. INTEGER :: ji
  793. INTEGER :: jk
  794. INTEGER :: jq
  795. ! Check allocation status of fbdatain
  796. DO js = 1, nsets
  797. IF ( .NOT. fbdatain(js)%lalloc ) THEN
  798. CALL fatal_error( 'merge_obfbdata: input data not allocated', &
  799. & __LINE__ )
  800. ENDIF
  801. END DO
  802. ! Check allocation status of fbdataout
  803. IF ( .NOT.fbdataout%lalloc ) THEN
  804. CALL fatal_error( 'merge_obfbdata: output data not allocated', &
  805. & __LINE__ )
  806. ENDIF
  807. ! Merge various names
  808. DO jv = 1, fbdatain(1)%nvar
  809. fbdataout%cname(jv) = fbdatain(1)%cname(jv)
  810. fbdataout%coblong(jv) = fbdatain(1)%coblong(jv)
  811. fbdataout%cobunit(jv) = fbdatain(1)%cobunit(jv)
  812. IF ( fbdatain(1)%lgrid ) THEN
  813. fbdataout%cgrid(jv) = fbdatain(1)%cgrid(jv)
  814. ENDIF
  815. END DO
  816. DO jv = 1, fbdatain(1)%nadd
  817. fbdataout%caddname(jv) = fbdatain(1)%caddname(jv)
  818. END DO
  819. DO jv = 1, fbdatain(1)%nvar
  820. DO je = 1, fbdatain(1)%nadd
  821. fbdataout%caddlong(je,jv) = fbdatain(1)%caddlong(je,jv)
  822. fbdataout%caddunit(je,jv) = fbdatain(1)%caddunit(je,jv)
  823. END DO
  824. END DO
  825. DO jv = 1, fbdatain(1)%next
  826. fbdataout%cextname(jv) = fbdatain(1)%cextname(jv)
  827. fbdataout%cextlong(jv) = fbdatain(1)%cextlong(jv)
  828. fbdataout%cextunit(jv) = fbdatain(1)%cextunit(jv)
  829. END DO
  830. fbdataout%cdjuldref = fbdatain(1)%cdjuldref
  831. ! Loop over total views
  832. DO jo = 1, fbdataout%nobs
  833. js = iset(iind(jo))
  834. ji = inum(iind(jo))
  835. ! Merge the header data
  836. fbdataout%cdwmo(jo) = fbdatain(js)%cdwmo(ji)
  837. fbdataout%cdtyp(jo) = fbdatain(js)%cdtyp(ji)
  838. fbdataout%ioqc(jo) = fbdatain(js)%ioqc(ji)
  839. fbdataout%ipqc(jo) = fbdatain(js)%ipqc(ji)
  840. fbdataout%itqc(jo) = fbdatain(js)%itqc(ji)
  841. fbdataout%plam(jo) = fbdatain(js)%plam(ji)
  842. fbdataout%pphi(jo) = fbdatain(js)%pphi(ji)
  843. fbdataout%ptim(jo) = fbdatain(js)%ptim(ji)
  844. fbdataout%kindex(jo) = fbdatain(js)%kindex(ji)
  845. DO jq = 1, fbdatain(js)%nqcf
  846. fbdataout%ioqcf(jq,jo) = fbdatain(js)%ioqcf(jq,ji)
  847. fbdataout%ipqcf(jq,jo) = fbdatain(js)%ipqcf(jq,ji)
  848. fbdataout%itqcf(jq,jo) = fbdatain(js)%itqcf(jq,ji)
  849. END DO
  850. DO jk = 1, fbdatain(js)%nlev
  851. fbdataout%pdep(jk,jo) = fbdatain(js)%pdep(jk,ji)
  852. fbdataout%idqc(jk,jo) = fbdatain(js)%idqc(jk,ji)
  853. DO jq = 1, fbdatain(js)%nqcf
  854. fbdataout%idqcf(jq,jk,jo) = fbdatain(js)%idqcf(jq,jk,ji)
  855. END DO
  856. END DO
  857. ! Merge the variable data
  858. DO jv = 1, fbdatain(js)%nvar
  859. fbdataout%ivqc(jo,jv) = fbdatain(js)%ivqc(ji,jv)
  860. DO jq = 1, fbdatain(js)%nqcf
  861. fbdataout%ivqcf(jq,jo,jv) = fbdatain(js)%ivqcf(jq,ji,jv)
  862. END DO
  863. DO jk = 1, fbdatain(js)%nlev
  864. fbdataout%ivlqc(jk,jo,jv) = fbdatain(js)%ivlqc(jk,ji,jv)
  865. fbdataout%pob(jk,jo,jv) = fbdatain(js)%pob(jk,ji,jv)
  866. DO jq = 1, fbdatain(js)%nqcf
  867. fbdataout%ivlqcf(jq,jk,jo,jv) = &
  868. & fbdatain(js)%ivlqcf(jq,jk,ji,jv)
  869. END DO
  870. END DO
  871. END DO
  872. ! Merge grid information
  873. IF ( fbdatain(js)%lgrid ) THEN
  874. DO jv = 1, fbdatain(js)%nvar
  875. fbdataout%cgrid(jv) = fbdatain(js)%cgrid(jv)
  876. fbdataout%iproc(jo,jv) = fbdatain(js)%iproc(ji,jv)
  877. fbdataout%iobsi(jo,jv) = fbdatain(js)%iobsi(ji,jv)
  878. fbdataout%iobsj(jo,jv) = fbdatain(js)%iobsj(ji,jv)
  879. DO jk = 1, fbdatain(js)%nlev
  880. fbdataout%iobsk(jk,jo,jv) = fbdatain(js)%iobsk(jk,ji,jv)
  881. END DO
  882. END DO
  883. ENDIF
  884. ! Merge additional information
  885. DO jv = 1, fbdatain(js)%nvar
  886. DO je = 1, fbdatain(js)%nadd
  887. DO jk = 1, fbdatain(js)%nlev
  888. fbdataout%padd(jk,jo,je,jv) = fbdatain(js)%padd(jk,ji,je,jv)
  889. END DO
  890. END DO
  891. END DO
  892. ! Merge extra information
  893. DO je = 1, fbdatain(js)%next
  894. DO jk = 1, fbdatain(js)%nlev
  895. fbdataout%pext(jk,jo,je) = fbdatain(js)%pext(jk,ji,je)
  896. END DO
  897. END DO
  898. END DO
  899. END SUBROUTINE merge_obfbdata
  900. SUBROUTINE write_obfbdata( cdfilename, fbdata )
  901. !!----------------------------------------------------------------------
  902. !! *** ROUTINE write_obfbdata ***
  903. !!
  904. !! ** Purpose : Write an obfbdata structure into a netCDF file.
  905. !!
  906. !! ** Method : Decides which output wrapper to use.
  907. !!
  908. !! ** Action :
  909. !!
  910. !!----------------------------------------------------------------------
  911. !! * Arguments
  912. CHARACTER(len=*) :: cdfilename ! Output filename
  913. TYPE(obfbdata) :: fbdata ! obsfbdata structure
  914. #if defined key_offobsoper
  915. IF (ln_cl4) THEN
  916. ! Class 4 file output stream
  917. CALL write_obfbdata_cl( cdfilename, fbdata )
  918. ELSE
  919. #endif
  920. ! Standard feedback file output stream
  921. CALL write_obfbdata_fb( cdfilename, fbdata )
  922. #if defined key_offobsoper
  923. ENDIF
  924. #endif
  925. END SUBROUTINE write_obfbdata
  926. SUBROUTINE write_obfbdata_fb( cdfilename, fbdata )
  927. !!----------------------------------------------------------------------
  928. !! *** ROUTINE write_obfbdata ***
  929. !!
  930. !! ** Purpose : Write an obfbdata structure into a netCDF file.
  931. !!
  932. !! ** Method :
  933. !!
  934. !! ** Action :
  935. !!
  936. !!----------------------------------------------------------------------
  937. !! * Arguments
  938. CHARACTER(len=*) :: cdfilename ! Output filename
  939. TYPE(obfbdata) :: fbdata ! obsfbdata structure
  940. !! * Local variables
  941. CHARACTER(LEN=14), PARAMETER :: cpname = 'write_obfbdata'
  942. ! Dimension ids
  943. INTEGER :: idfile
  944. INTEGER :: idodim
  945. INTEGER :: idldim
  946. INTEGER :: idvdim
  947. INTEGER :: idadim
  948. INTEGER :: idedim
  949. INTEGER :: idsndim
  950. INTEGER :: idsgdim
  951. INTEGER :: idswdim
  952. INTEGER :: idstdim
  953. INTEGER :: idjddim
  954. INTEGER :: idqcdim
  955. INTEGER :: idvard
  956. INTEGER :: idaddd
  957. INTEGER :: idextd
  958. INTEGER :: idcdwmo
  959. INTEGER :: idcdtyp
  960. INTEGER :: idplam
  961. INTEGER :: idpphi
  962. INTEGER :: idpdep
  963. INTEGER :: idptim
  964. INTEGER :: idptimr
  965. INTEGER :: idioqc
  966. INTEGER :: idioqcf
  967. INTEGER :: idipqc
  968. INTEGER :: idipqcf
  969. INTEGER :: iditqc
  970. INTEGER :: iditqcf
  971. INTEGER :: ididqc
  972. INTEGER :: ididqcf
  973. INTEGER :: idkindex
  974. INTEGER, DIMENSION(fbdata%nvar) :: &
  975. & idpob, &
  976. & idivqc, &
  977. & idivqcf, &
  978. & idivlqc, &
  979. & idivlqcf, &
  980. & idiobsi, &
  981. & idiobsj, &
  982. & idiobsk, &
  983. & idcgrid
  984. INTEGER, DIMENSION(fbdata%nadd,fbdata%nvar) :: idpadd
  985. INTEGER, DIMENSION(fbdata%next) :: idpext
  986. INTEGER, DIMENSION(1) :: incdim1
  987. INTEGER, DIMENSION(2) :: incdim2
  988. INTEGER, DIMENSION(3) :: incdim3
  989. INTEGER, DIMENSION(4) :: incdim4
  990. INTEGER :: jv
  991. INTEGER :: je
  992. INTEGER :: ioldfill
  993. CHARACTER(len=nf90_max_name) :: &
  994. & cdtmp
  995. CHARACTER(len=16), PARAMETER :: &
  996. & cdqcconv = 'q where q =[0,9]'
  997. CHARACTER(len=24), PARAMETER :: &
  998. & cdqcfconv = 'NEMOVAR flag conventions'
  999. CHARACTER(len=ilenlong) :: &
  1000. & cdltmp
  1001. ! Open output filename
  1002. CALL chkerr( nf90_create( TRIM( cdfilename ), nf90_clobber, idfile ), &
  1003. & cpname, __LINE__ )
  1004. CALL chkerr( nf90_set_fill( idfile, nf90_nofill, ioldfill ), &
  1005. & cpname, __LINE__ )
  1006. CALL chkerr( nf90_put_att( idfile, nf90_global, 'title', &
  1007. & 'NEMO observation operator output' ), &
  1008. & cpname, __LINE__ )
  1009. CALL chkerr( nf90_put_att( idfile, nf90_global, 'Convention', &
  1010. & 'NEMO unified observation operator output' ),&
  1011. & cpname,__LINE__ )
  1012. ! Create the dimensions
  1013. CALL chkerr( nf90_def_dim( idfile, 'N_OBS' , fbdata%nobs, idodim ), &
  1014. & cpname,__LINE__ )
  1015. CALL chkerr( nf90_def_dim( idfile, 'N_LEVELS', fbdata%nlev, idldim ), &
  1016. & cpname,__LINE__ )
  1017. CALL chkerr( nf90_def_dim( idfile, 'N_VARS', fbdata%nvar, idvdim ), &
  1018. & cpname,__LINE__ )
  1019. CALL chkerr( nf90_def_dim( idfile, 'N_QCF', fbdata%nqcf, idqcdim ),&
  1020. & cpname,__LINE__ )
  1021. IF ( fbdata%nadd > 0 ) THEN
  1022. CALL chkerr( nf90_def_dim( idfile, 'N_ENTRIES', fbdata%nadd, idadim ), &
  1023. & cpname,__LINE__ )
  1024. ENDIF
  1025. IF ( fbdata%next > 0 ) THEN
  1026. CALL chkerr( nf90_def_dim( idfile, 'N_EXTRA', fbdata%next, idedim ), &
  1027. & cpname,__LINE__ )
  1028. ENDIF
  1029. CALL chkerr( nf90_def_dim( idfile, 'STRINGNAM', ilenname, idsndim ), &
  1030. & cpname,__LINE__ )
  1031. IF (fbdata%lgrid) THEN
  1032. CALL chkerr( nf90_def_dim( idfile, 'STRINGGRID', ilengrid, idsgdim ),&
  1033. & cpname,__LINE__ )
  1034. ENDIF
  1035. CALL chkerr( nf90_def_dim( idfile, 'STRINGWMO', ilenwmo, idswdim ), &
  1036. & cpname,__LINE__ )
  1037. CALL chkerr( nf90_def_dim( idfile, 'STRINGTYP', ilentyp, idstdim ), &
  1038. & cpname,__LINE__ )
  1039. CALL chkerr( nf90_def_dim( idfile, 'STRINGJULD', ilenjuld, idjddim ), &
  1040. & cpname,__LINE__ )
  1041. ! Define netCDF variables for header information
  1042. incdim2(1) = idsndim
  1043. incdim2(2) = idvdim
  1044. CALL chkerr( nf90_def_var( idfile, 'VARIABLES', nf90_char, incdim2, &
  1045. & idvard ), cpname, __LINE__ )
  1046. CALL putvaratt_obfbdata( idfile, idvard, &
  1047. & 'List of variables in feedback files' )
  1048. IF ( fbdata%nadd > 0 ) THEN
  1049. incdim2(1) = idsndim
  1050. incdim2(2) = idadim
  1051. CALL chkerr( nf90_def_var( idfile, 'ENTRIES', nf90_char, incdim2, &
  1052. & idaddd ), cpname, __LINE__ )
  1053. CALL putvaratt_obfbdata( idfile, idaddd, &
  1054. & 'List of additional entries for each '// &
  1055. & 'variable in feedback files' )
  1056. ENDIF
  1057. IF ( fbdata%next > 0 ) THEN
  1058. incdim2(1) = idsndim
  1059. incdim2(2) = idedim
  1060. CALL chkerr( nf90_def_var( idfile, 'EXTRA', nf90_char, incdim2, &
  1061. & idextd ), cpname, __LINE__ )
  1062. CALL putvaratt_obfbdata( idfile, idextd, &
  1063. & 'List of extra variables' )
  1064. ENDIF
  1065. incdim2(1) = idswdim
  1066. incdim2(2) = idodim
  1067. CALL chkerr( nf90_def_var( idfile, 'STATION_IDENTIFIER', &
  1068. & nf90_char, incdim2, &
  1069. & idcdwmo ), cpname, __LINE__ )
  1070. CALL putvaratt_obfbdata( idfile, idcdwmo, &
  1071. & 'Station identifier' )
  1072. incdim2(1) = idstdim
  1073. incdim2(2) = idodim
  1074. CALL chkerr( nf90_def_var( idfile, 'STATION_TYPE', &
  1075. & nf90_char, incdim2, &
  1076. & idcdtyp ), cpname, __LINE__ )
  1077. CALL putvaratt_obfbdata( idfile, idcdtyp, &
  1078. & 'Code instrument type' )
  1079. incdim1(1) = idodim
  1080. CALL chkerr( nf90_def_var( idfile, 'LONGITUDE', &
  1081. & nf90_double, incdim1, &
  1082. & idplam ), cpname, __LINE__ )
  1083. CALL putvaratt_obfbdata( idfile, idplam, &
  1084. & 'Longitude', cdunits = 'degrees_east', &
  1085. & rfillvalue = fbrmdi )
  1086. CALL chkerr( nf90_def_var( idfile, 'LATITUDE', &
  1087. & nf90_double, incdim1, &
  1088. & idpphi ), cpname, __LINE__ )
  1089. CALL putvaratt_obfbdata( idfile, idpphi, &
  1090. & 'Latitude', cdunits = 'degrees_north', &
  1091. & rfillvalue = fbrmdi )
  1092. incdim2(1) = idldim
  1093. incdim2(2) = idodim
  1094. CALL chkerr( nf90_def_var( idfile, 'DEPTH', &
  1095. & nf90_double, incdim2, &
  1096. & idpdep ), cpname, __LINE__ )
  1097. CALL putvaratt_obfbdata( idfile, idpdep, &
  1098. & 'Depth', cdunits = 'metre', &
  1099. & rfillvalue = fbrmdi )
  1100. incdim3(1) = idqcdim
  1101. incdim3(2) = idldim
  1102. incdim3(3) = idodim
  1103. CALL chkerr( nf90_def_var( idfile, 'DEPTH_QC', &
  1104. & nf90_int, incdim2, &
  1105. & ididqc ), cpname, __LINE__ )
  1106. CALL putvaratt_obfbdata( idfile, ididqc, &
  1107. & 'Quality on depth', &
  1108. & conventions = cdqcconv, &
  1109. & ifillvalue = 0 )
  1110. CALL chkerr( nf90_def_var( idfile, 'DEPTH_QC_FLAGS', &
  1111. & nf90_int, incdim3, &
  1112. & ididqcf ), cpname, __LINE__ )
  1113. CALL putvaratt_obfbdata( idfile, ididqcf, &
  1114. & 'Quality flags on depth', &
  1115. & conventions = cdqcfconv )
  1116. CALL chkerr( nf90_def_var( idfile, 'JULD', &
  1117. & nf90_double, incdim1, &
  1118. & idptim ), cpname, __LINE__ )
  1119. CALL putvaratt_obfbdata( idfile, idptim, &
  1120. & 'Julian day', &
  1121. & cdunits = 'days since JULD_REFERENCE', &
  1122. & conventions = 'relative julian days with '// &
  1123. & 'decimal part (as parts of day)', &
  1124. & rfillvalue = fbrmdi )
  1125. incdim1(1) = idjddim
  1126. CALL chkerr( nf90_def_var( idfile, 'JULD_REFERENCE', &
  1127. & nf90_char, incdim1, &
  1128. & idptimr ), cpname, __LINE__ )
  1129. CALL putvaratt_obfbdata( idfile, idptimr, &
  1130. & 'Date of reference for julian days ', &
  1131. & conventions = 'YYYYMMDDHHMMSS' )
  1132. incdim1(1) = idodim
  1133. CALL chkerr( nf90_def_var( idfile, 'OBSERVATION_QC', &
  1134. & nf90_int, incdim1, &
  1135. & idioqc ), cpname, __LINE__ )
  1136. CALL putvaratt_obfbdata( idfile, idioqc, &
  1137. & 'Quality on observation', &
  1138. & conventions = cdqcconv, &
  1139. & ifillvalue = 0 )
  1140. incdim2(1) = idqcdim
  1141. incdim2(2) = idodim
  1142. CALL chkerr( nf90_def_var( idfile, 'OBSERVATION_QC_FLAGS', &
  1143. & nf90_int, incdim2, &
  1144. & idioqcf ), cpname, __LINE__ )
  1145. CALL putvaratt_obfbdata( idfile, idioqcf, &
  1146. & 'Quality flags on observation', &
  1147. & conventions = cdqcfconv, &
  1148. & ifillvalue = 0 )
  1149. CALL chkerr( nf90_def_var( idfile, 'POSITION_QC', &
  1150. & nf90_int, incdim1, &
  1151. & idipqc ), cpname, __LINE__ )
  1152. CALL putvaratt_obfbdata( idfile, idipqc, &
  1153. & 'Quality on position (latitude and longitude)', &
  1154. & conventions = cdqcconv, &
  1155. & ifillvalue = 0 )
  1156. CALL chkerr( nf90_def_var( idfile, 'POSITION_QC_FLAGS', &
  1157. & nf90_int, incdim2, &
  1158. & idipqcf ), cpname, __LINE__ )
  1159. CALL putvaratt_obfbdata( idfile, idipqcf, &
  1160. & 'Quality flags on position', &
  1161. & conventions = cdqcfconv, &
  1162. & ifillvalue = 0 )
  1163. CALL chkerr( nf90_def_var( idfile, 'JULD_QC', &
  1164. & nf90_int, incdim1, &
  1165. & iditqc ), cpname, __LINE__ )
  1166. CALL putvaratt_obfbdata( idfile, iditqc, &
  1167. & 'Quality on date and time', &
  1168. & conventions = cdqcconv, &
  1169. & ifillvalue = 0 )
  1170. CALL chkerr( nf90_def_var( idfile, 'JULD_QC_FLAGS', &
  1171. & nf90_int, incdim2, &
  1172. & iditqcf ), cpname, __LINE__ )
  1173. CALL putvaratt_obfbdata( idfile, iditqcf, &
  1174. & 'Quality flags on date and time', &
  1175. & conventions = cdqcfconv, &
  1176. & ifillvalue = 0 )
  1177. CALL chkerr( nf90_def_var( idfile, 'ORIGINAL_FILE_INDEX', &
  1178. & nf90_int, incdim1, &
  1179. & idkindex ), cpname, __LINE__ )
  1180. CALL putvaratt_obfbdata( idfile, idkindex, &
  1181. & 'Index in original data file', &
  1182. & ifillvalue = fbimdi )
  1183. ! Define netCDF variables for individual variables
  1184. DO jv = 1, fbdata%nvar
  1185. incdim1(1) = idodim
  1186. incdim2(1) = idldim
  1187. incdim2(2) = idodim
  1188. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_OBS'
  1189. CALL chkerr( nf90_def_var( idfile, cdtmp, nf90_float, &
  1190. & incdim2, idpob(jv) ), &
  1191. & cpname, __LINE__ )
  1192. CALL putvaratt_obfbdata( idfile, idpob(jv), &
  1193. & fbdata%coblong(jv), &
  1194. & cdunits = fbdata%cobunit(jv), &
  1195. & rfillvalue = fbrmdi )
  1196. IF ( fbdata%nadd > 0 ) THEN
  1197. DO je = 1, fbdata%nadd
  1198. WRITE(cdtmp,'(3A)') TRIM(fbdata%cname(jv)),'_',&
  1199. & TRIM(fbdata%caddname(je))
  1200. CALL chkerr( nf90_def_var( idfile, cdtmp, nf90_float, &
  1201. & incdim2, idpadd(je,jv) ), &
  1202. & cpname, __LINE__ )
  1203. CALL putvaratt_obfbdata( idfile, idpadd(je,jv), &
  1204. & fbdata%caddlong(je,jv), &
  1205. & cdunits = fbdata%caddunit(je,jv), &
  1206. & rfillvalue = fbrmdi )
  1207. END DO
  1208. ENDIF
  1209. cdltmp = fbdata%coblong(jv)
  1210. IF (( cdltmp(1:1) >= 'A' ).AND.( cdltmp(1:1) <= 'Z' )) &
  1211. & cdltmp(1:1) = ACHAR(IACHAR(cdltmp(1:1)) + 32)
  1212. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_QC'
  1213. CALL chkerr( nf90_def_var( idfile, cdtmp, nf90_int, &
  1214. & incdim1, idivqc(jv) ), &
  1215. & cpname, __LINE__ )
  1216. CALL putvaratt_obfbdata( idfile, idivqc(jv), &
  1217. & 'Quality on '//cdltmp, &
  1218. & conventions = cdqcconv, &
  1219. & ifillvalue = 0 )
  1220. incdim2(1) = idqcdim
  1221. incdim2(2) = idodim
  1222. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_QC_FLAGS'
  1223. CALL chkerr( nf90_def_var( idfile, cdtmp, nf90_int, &
  1224. & incdim2, idivqcf(jv) ), &
  1225. & cpname, __LINE__ )
  1226. CALL putvaratt_obfbdata( idfile, idivqcf(jv), &
  1227. & 'Quality flags on '//cdltmp, &
  1228. & conventions = cdqcfconv, &
  1229. & ifillvalue = 0 )
  1230. incdim2(1) = idldim
  1231. incdim2(2) = idodim
  1232. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_LEVEL_QC'
  1233. CALL chkerr( nf90_def_var( idfile, cdtmp, nf90_int, &
  1234. & incdim2, idivlqc(jv) ), &
  1235. & cpname, __LINE__ )
  1236. CALL putvaratt_obfbdata( idfile, idivlqc(jv), &
  1237. & 'Quality for each level on '//cdltmp, &
  1238. & conventions = cdqcconv, &
  1239. & ifillvalue = 0 )
  1240. incdim3(1) = idqcdim
  1241. incdim3(2) = idldim
  1242. incdim3(3) = idodim
  1243. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_LEVEL_QC_FLAGS'
  1244. CALL chkerr( nf90_def_var( idfile, cdtmp, nf90_int, &
  1245. & incdim3, idivlqcf(jv) ), &
  1246. & cpname, __LINE__ )
  1247. CALL putvaratt_obfbdata( idfile, idivlqcf(jv), &
  1248. & 'Quality flags for each level on '//&
  1249. & cdltmp, &
  1250. & conventions = cdqcfconv, &
  1251. & ifillvalue = 0 )
  1252. IF (fbdata%lgrid) THEN
  1253. incdim2(1) = idldim
  1254. incdim2(2) = idodim
  1255. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_IOBSI'
  1256. CALL chkerr( nf90_def_var( idfile, cdtmp, nf90_int, &
  1257. & incdim1, idiobsi(jv) ), &
  1258. & cpname, __LINE__ )
  1259. CALL putvaratt_obfbdata( idfile, idiobsi(jv), &
  1260. & 'ORCA grid search I coordinate')
  1261. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_IOBSJ'
  1262. CALL chkerr( nf90_def_var( idfile, cdtmp, nf90_int, &
  1263. & incdim1, idiobsj(jv) ), &
  1264. & cpname, __LINE__ )
  1265. CALL putvaratt_obfbdata( idfile, idiobsj(jv), &
  1266. & 'ORCA grid search J coordinate')
  1267. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_IOBSK'
  1268. CALL chkerr( nf90_def_var( idfile, cdtmp, nf90_int, &
  1269. & incdim2, idiobsk(jv) ), &
  1270. & cpname, __LINE__ )
  1271. CALL putvaratt_obfbdata( idfile, idiobsk(jv), &
  1272. & 'ORCA grid search K coordinate')
  1273. incdim1(1) = idsgdim
  1274. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_GRID'
  1275. CALL chkerr( nf90_def_var( idfile, cdtmp, nf90_char, incdim1, &
  1276. & idcgrid(jv) ), cpname, __LINE__ )
  1277. CALL putvaratt_obfbdata( idfile, idcgrid(jv), &
  1278. & 'ORCA grid search grid (T,U,V)')
  1279. ENDIF
  1280. END DO
  1281. IF ( fbdata%next > 0 ) THEN
  1282. DO je = 1, fbdata%next
  1283. incdim2(1) = idldim
  1284. incdim2(2) = idodim
  1285. WRITE(cdtmp,'(A)') TRIM(fbdata%cextname(je))
  1286. CALL chkerr( nf90_def_var( idfile, cdtmp, nf90_float, &
  1287. & incdim2, idpext(je) ), &
  1288. & cpname, __LINE__ )
  1289. CALL putvaratt_obfbdata( idfile, idpext(je), &
  1290. & fbdata%cextlong(je), &
  1291. & cdunits = fbdata%cextunit(je), &
  1292. & rfillvalue = fbrmdi )
  1293. END DO
  1294. ENDIF
  1295. ! Stop definitions
  1296. CALL chkerr( nf90_enddef( idfile ), cpname, __LINE__ )
  1297. ! Write the variables
  1298. CALL chkerr( nf90_put_var( idfile, idvard, fbdata%cname ), &
  1299. & cpname, __LINE__ )
  1300. IF ( fbdata%nadd > 0 ) THEN
  1301. CALL chkerr( nf90_put_var( idfile, idaddd, fbdata%caddname ), &
  1302. & cpname, __LINE__ )
  1303. ENDIF
  1304. IF ( fbdata%next > 0 ) THEN
  1305. CALL chkerr( nf90_put_var( idfile, idextd, fbdata%cextname ), &
  1306. & cpname, __LINE__ )
  1307. ENDIF
  1308. CALL chkerr( nf90_put_var( idfile, idptimr, fbdata%cdjuldref ), &
  1309. & cpname, __LINE__ )
  1310. ! Only write the data if observation is available
  1311. IF ( fbdata%nobs > 0 ) THEN
  1312. CALL chkerr( nf90_put_var( idfile, idcdwmo, fbdata%cdwmo ), &
  1313. & cpname, __LINE__ )
  1314. CALL chkerr( nf90_put_var( idfile, idcdtyp, fbdata%cdtyp ), &
  1315. & cpname, __LINE__ )
  1316. CALL chkerr( nf90_put_var( idfile, idplam, fbdata%plam ), &
  1317. & cpname, __LINE__ )
  1318. CALL chkerr( nf90_put_var( idfile, idpphi, fbdata%pphi ), &
  1319. & cpname, __LINE__ )
  1320. CALL chkerr( nf90_put_var( idfile, idpdep, fbdata%pdep ), &
  1321. & cpname, __LINE__ )
  1322. CALL chkerr( nf90_put_var( idfile, idptim, fbdata%ptim ), &
  1323. & cpname, __LINE__ )
  1324. CALL chkerr( nf90_put_var( idfile, idioqc, fbdata%ioqc ), &
  1325. & cpname, __LINE__ )
  1326. CALL chkerr( nf90_put_var( idfile, idioqcf, fbdata%ioqcf ), &
  1327. & cpname, __LINE__ )
  1328. CALL chkerr( nf90_put_var( idfile, idipqc, fbdata%ipqc ), &
  1329. & cpname, __LINE__ )
  1330. CALL chkerr( nf90_put_var( idfile, idipqcf, fbdata%ipqcf ), &
  1331. & cpname, __LINE__ )
  1332. CALL chkerr( nf90_put_var( idfile, iditqc, fbdata%itqc ), &
  1333. & cpname, __LINE__ )
  1334. CALL chkerr( nf90_put_var( idfile, iditqcf, fbdata%itqcf ), &
  1335. & cpname, __LINE__ )
  1336. CALL chkerr( nf90_put_var( idfile, ididqc, fbdata%idqc ), &
  1337. & cpname, __LINE__ )
  1338. CALL chkerr( nf90_put_var( idfile, ididqcf, fbdata%idqcf ), &
  1339. & cpname, __LINE__ )
  1340. CALL chkerr( nf90_put_var( idfile, idkindex, fbdata%kindex ), &
  1341. & cpname, __LINE__ )
  1342. DO jv = 1, fbdata%nvar
  1343. CALL chkerr( nf90_put_var( idfile, idpob(jv), fbdata%pob(:,:,jv) ), &
  1344. & cpname, __LINE__ )
  1345. IF ( fbdata%nadd > 0 ) THEN
  1346. DO je = 1, fbdata%nadd
  1347. CALL chkerr( nf90_put_var( idfile, idpadd(je,jv), &
  1348. & fbdata%padd(:,:,je,jv) ), &
  1349. & cpname, __LINE__ )
  1350. END DO
  1351. ENDIF
  1352. CALL chkerr( nf90_put_var( idfile, idivqc(jv), &
  1353. & fbdata%ivqc(:,jv) ),&
  1354. & cpname, __LINE__ )
  1355. CALL chkerr( nf90_put_var( idfile, idivqcf(jv), &
  1356. & fbdata%ivqcf(:,:,jv) ),&
  1357. & cpname, __LINE__ )
  1358. CALL chkerr( nf90_put_var( idfile, idivlqc(jv), &
  1359. & fbdata%ivlqc(:,:,jv) ),&
  1360. & cpname, __LINE__ )
  1361. CALL chkerr( nf90_put_var( idfile, idivlqcf(jv), &
  1362. & fbdata%ivlqcf(:,:,:,jv) ),&
  1363. & cpname, __LINE__ )
  1364. IF (fbdata%lgrid) THEN
  1365. CALL chkerr( nf90_put_var( idfile, idiobsi(jv), &
  1366. & fbdata%iobsi(:,jv) ),&
  1367. & cpname, __LINE__ )
  1368. CALL chkerr( nf90_put_var( idfile, idiobsj(jv), &
  1369. & fbdata%iobsj(:,jv) ),&
  1370. & cpname, __LINE__ )
  1371. CALL chkerr( nf90_put_var( idfile, idiobsk(jv), &
  1372. & fbdata%iobsk(:,:,jv) ),&
  1373. & cpname, __LINE__ )
  1374. CALL chkerr( nf90_put_var( idfile, idcgrid(jv), &
  1375. & fbdata%cgrid(jv) ), &
  1376. & cpname, __LINE__ )
  1377. ENDIF
  1378. END DO
  1379. IF ( fbdata%next > 0 ) THEN
  1380. DO je = 1, fbdata%next
  1381. CALL chkerr( nf90_put_var( idfile, idpext(je), &
  1382. & fbdata%pext(:,:,je) ), &
  1383. & cpname, __LINE__ )
  1384. END DO
  1385. ENDIF
  1386. ENDIF
  1387. ! Close the file
  1388. CALL chkerr( nf90_close( idfile ), cpname, __LINE__ )
  1389. END SUBROUTINE write_obfbdata_fb
  1390. #if defined key_offobsoper
  1391. SUBROUTINE write_obfbdata_cl(cdfilename, fbdata)
  1392. !!----------------------------------------------------------------------
  1393. !! *** ROUTINE write_obfbdata_cl ***
  1394. !!
  1395. !! ** Purpose : Write an obfbdata structure into a class 4 file.
  1396. !!
  1397. !! ** Method : 1. Allocate memory needed by ooo_write
  1398. !! 2. Map obfbdata into allocated memory
  1399. !! 3. Pass mapped data to ooo_write
  1400. !! 4. Deallocate memory
  1401. !!----------------------------------------------------------------------
  1402. USE dom_oce, ONLY: narea
  1403. USE ooo_write
  1404. USE ooo_data
  1405. !! * Arguments
  1406. CHARACTER(len=*) :: cdfilename ! Feedback filename
  1407. TYPE(obfbdata) :: fbdata ! obsfbdata structure
  1408. !! * Local variables
  1409. CHARACTER(len=17), PARAMETER :: cpname = 'write_obfbdata_cl'
  1410. CHARACTER(len=64) :: &
  1411. & cdate, & !: class 4 file validity date
  1412. & cconf, & !: model configuration
  1413. & csys, & !: model system
  1414. & ccont, & !: contact email
  1415. & cinst, & !: institution
  1416. & cversion !: model version
  1417. CHARACTER(len=8) :: &
  1418. & ckind !: observation kind
  1419. CHARACTER(len=3) :: cfield
  1420. INTEGER :: kobs, & !: number of observations
  1421. & kvars, & !: number of physical variables
  1422. & kdeps, & !: number of observed depths
  1423. & kfcst, & !: number of forecasts
  1424. & kifcst, & !: current forecast number
  1425. & kproc !: processor number
  1426. INTEGER, DIMENSION(:, :, :), ALLOCATABLE :: &
  1427. & kqc !: quality control counterpart
  1428. INTEGER(KIND=2), DIMENSION(:, :, :), ALLOCATABLE :: &
  1429. & k2qc !: quality control counterpart
  1430. REAL(kind=fbdp) :: &
  1431. & pmodjuld !: model Julian day
  1432. REAL(kind=fbdp), DIMENSION(:), ALLOCATABLE :: &
  1433. & plead, & !: forecast lead time
  1434. & plam, & !: longitude of observation
  1435. & pphi, & !: latitude of observation
  1436. & ptim !: time of observation
  1437. REAL(kind=fbdp), DIMENSION(:, :), ALLOCATABLE :: &
  1438. & pdep !: depths of observations
  1439. REAL(kind=fbdp), DIMENSION(:, :, :), ALLOCATABLE :: &
  1440. & pob, & !: observation counterpart
  1441. & pextra !: extra field counterpart
  1442. REAL(kind=fbdp), DIMENSION(:, :, :), ALLOCATABLE :: &
  1443. & pmod !: model counterpart
  1444. CHARACTER(len=128) :: &
  1445. & clfilename !: class 4 file name
  1446. CHARACTER(len=128), DIMENSION(:), ALLOCATABLE :: &
  1447. & ctype !: Instrument type
  1448. CHARACTER(len=nf90_max_name) :: &
  1449. & cdtmp !: NetCDF variable name
  1450. CHARACTER(len=8), DIMENSION(:), ALLOCATABLE :: &
  1451. & cwmo, & !: Instrument WMO ID
  1452. & cunit, & !: Instrument WMO ID
  1453. & cvarname !: Instrument WMO ID
  1454. INTEGER :: &
  1455. & idep, & !: Loop variable
  1456. & ivar, & !: Loop variable
  1457. & iobs, & !: Loop variable
  1458. & ii, & !: Loop variable
  1459. & ij, & !: Loop variable
  1460. & ik, & !: Loop variable
  1461. & il !: Loop variable
  1462. cconf = TRIM(cl4_cfg)
  1463. csys = TRIM(cl4_sys)
  1464. cversion = TRIM(cl4_vn)
  1465. ccont = TRIM(cl4_contact)
  1466. cinst = TRIM(cl4_inst)
  1467. cdate = TRIM(cl4_date)
  1468. CALL locate_kind(cdfilename, ckind)
  1469. kproc = narea
  1470. kfcst = cl4_fcst_len
  1471. kobs = fbdata%nobs
  1472. kdeps = fbdata%nlev
  1473. kvars = fbdata%nvar
  1474. IF (kobs .GT. 0) THEN
  1475. ALLOCATE(plam(kobs), &
  1476. & pphi(kobs), &
  1477. & ptim(kobs), &
  1478. & plead(kfcst), &
  1479. & pdep(kdeps, kobs), &
  1480. & kqc(kdeps, kvars, kobs), &
  1481. & k2qc(kdeps, kvars, kobs), &
  1482. & pob(kdeps, kvars, kobs), &
  1483. & pmod(kdeps, kvars, kobs), &
  1484. & pextra(kdeps, kvars, kobs), &
  1485. & ctype(kobs), &
  1486. & cwmo(kobs), &
  1487. & cunit(kvars), &
  1488. & cvarname(kvars))
  1489. plam(:) = fbdata%plam(:)
  1490. pphi(:) = fbdata%pphi(:)
  1491. ptim(:) = fbdata%ptim(:)
  1492. pdep(:, :) = fbdata%pdep(:, :)
  1493. kqc(:,:,:) = 1.
  1494. DO ii = 1, kvars
  1495. cvarname(ii) = fbdata%cname(ii)
  1496. cunit(ii) = fbdata%cobunit(ii)
  1497. END DO
  1498. ! Quality control algorithm
  1499. k2qc(:,:,:) = NF90_FILL_SHORT
  1500. DO idep = 1,kdeps
  1501. DO ivar = 1, kvars
  1502. DO iobs = 1, kobs
  1503. ! 1 symbolises good for fbdata
  1504. ! fbimdi symbolises that qc has not been set
  1505. ! Essentially, if any fbdata flag is not an element of {1, fbimdi}
  1506. ! then set the class 4 flag to bad.
  1507. ! Note: fbdata%ioqc is marked good if zero.
  1508. IF (((fbdata%ioqc(iobs) /= 0) .AND. &
  1509. & (fbdata%ioqc(iobs) /= fbimdi)) .OR. &
  1510. & ((fbdata%ipqc(iobs) /= 1) .AND. &
  1511. & (fbdata%ipqc(iobs) /= fbimdi)) .OR. &
  1512. & ((fbdata%idqc(idep,iobs) /= 1) .AND. &
  1513. & (fbdata%idqc(idep,iobs) /= fbimdi)) .OR. &
  1514. & ((fbdata%ivqc(iobs,ivar) /= 1) .AND. &
  1515. & (fbdata%ivqc(iobs,ivar) /= fbimdi)) .OR. &
  1516. & ((fbdata%ivlqc(idep,iobs,ivar) /= 1) .AND. &
  1517. & (fbdata%ivlqc(idep,iobs,ivar) /= fbimdi)) .OR. &
  1518. & ((fbdata%itqc(iobs) /= 1) .AND. &
  1519. & (fbdata%itqc(iobs) /= fbimdi))) THEN
  1520. ! 1 symbolises bad for class 4 file
  1521. k2qc(idep, ivar, iobs) = 1
  1522. ELSE
  1523. ! 0 symbolises good for class 4 file
  1524. k2qc(idep, ivar, iobs) = 0
  1525. END IF
  1526. END DO
  1527. END DO
  1528. END DO
  1529. ! Permute observation dimensions
  1530. pob(:,:,:) = RESHAPE(fbdata%pob, (/kdeps, kvars, kobs/), &
  1531. & ORDER=(/1, 3, 2/))
  1532. ! Explicit model counterpart dimension permutation
  1533. ! 1,2,3,4 --> 1,4,2,3
  1534. pmod(:,:,:) = fbrmdi
  1535. ij = cl4_fcst_idx(jimatch)
  1536. DO ii = 1,kdeps
  1537. DO ik = 1, kvars
  1538. DO il = 1, kobs
  1539. pmod(ii,ik,il) = fbdata%padd(ii,il,1,ik)
  1540. END DO
  1541. END DO
  1542. END DO
  1543. ! Extra fields set to missing for now
  1544. pextra(:,:,:) = fbrmdi
  1545. ! Lead time of class 4 file is a global parameter
  1546. plead = cl4_leadtime(1:cl4_fcst_len)
  1547. ! Model Julian day
  1548. pmodjuld = cl4_modjuld
  1549. ! Observation types
  1550. ctype(:) = 'X'
  1551. DO ii = 1,kobs
  1552. ctype(ii) = fbdata%cdtyp(ii)
  1553. END DO
  1554. ! World Meteorology Organisation codes
  1555. cwmo(:) = fbdata%cdwmo(:)
  1556. ! Initialise class 4 file
  1557. CALL ooo_wri_init(cconf, csys, ckind, cversion, ccont, cinst, cdate, &
  1558. & kproc, kobs, kvars, kdeps, kfcst, &
  1559. & clfilename)
  1560. ! Write standard variables
  1561. CALL ooo_wri_default(clfilename, kobs, kvars, kfcst, kdeps, &
  1562. & ctype, cwmo, cunit, cvarname, &
  1563. & plam, pphi, pdep, ptim, pob, plead, &
  1564. & k2qc, pmodjuld)
  1565. !! Write to optional variables
  1566. cdtmp = cl4_vars(jimatch)
  1567. IF ( (TRIM(cdtmp) == "forecast") .OR. &
  1568. (TRIM(cdtmp) == "persistence") ) THEN
  1569. !! 4D variables
  1570. CALL ooo_wri_extra(clfilename, TRIM(cdtmp), kdeps, kfcst, &
  1571. & kvars, kobs, (/ 1,ij,1,1 /), (/ kdeps,1,kvars,kobs /), pmod)
  1572. ELSE
  1573. !! 3D variables
  1574. CALL ooo_wri_extra(clfilename, TRIM(cdtmp), kdeps, &
  1575. & kvars, kobs, (/ 1,1,1 /), (/ kdeps,kvars,kobs /), pmod)
  1576. ENDIF
  1577. DEALLOCATE(plam, pphi, ptim, pdep, plead, kqc, k2qc, &
  1578. & pob, pmod, pextra, ctype, cwmo, &
  1579. & cunit, cvarname)
  1580. END IF
  1581. END SUBROUTINE write_obfbdata_cl
  1582. #endif
  1583. #if defined key_offobsoper
  1584. SUBROUTINE locate_kind(cdfilename, ckind)
  1585. !!----------------------------------------------------------------------
  1586. !! *** ROUTINE locate_kind ***
  1587. !!
  1588. !! ** Purpose : Detect which kind of class 4 file is being produced.
  1589. !!
  1590. !! ** Method : 1. Inspect cdfilename for observation kind.
  1591. !!----------------------------------------------------------------------
  1592. CHARACTER(len=*) :: cdfilename ! Feedback filename
  1593. CHARACTER(len=8) :: ckind
  1594. IF (cdfilename(1:3) == 'sst') THEN
  1595. ckind = 'SST'
  1596. ELSE IF (cdfilename(1:3) == 'sla') THEN
  1597. ckind = 'SLA'
  1598. ELSE IF (cdfilename(1:3) == 'pro') THEN
  1599. ckind = 'profile'
  1600. ELSE IF (cdfilename(1:3) == 'ena') THEN
  1601. ckind = 'profile'
  1602. ELSE IF (cdfilename(1:3) == 'sea') THEN
  1603. ckind = 'seaice'
  1604. ELSE
  1605. ckind = 'unknown'
  1606. END IF
  1607. END SUBROUTINE locate_kind
  1608. #endif
  1609. SUBROUTINE putvaratt_obfbdata( idfile, idvar, cdlongname, cdunits, &
  1610. & conventions, cfillvalue, &
  1611. & ifillvalue, rfillvalue )
  1612. !!----------------------------------------------------------------------
  1613. !! *** ROUTINE putvaratt_obfbdata ***
  1614. !!
  1615. !! ** Purpose : Write netcdf attributes for variable
  1616. !!
  1617. !! ** Method :
  1618. !!
  1619. !! ** Action :
  1620. !!
  1621. !!----------------------------------------------------------------------
  1622. !! * Arguments
  1623. INTEGER :: idfile ! File netcdf id.
  1624. INTEGER :: idvar ! Variable netcdf id.
  1625. CHARACTER(len=*) :: cdlongname ! Long name for variable
  1626. CHARACTER(len=*), OPTIONAL :: cdunits ! Units for variable
  1627. CHARACTER(len=*), OPTIONAL :: cfillvalue ! Fill value for character variables
  1628. INTEGER, OPTIONAL :: ifillvalue ! Fill value for integer variables
  1629. REAL(kind=fbsp), OPTIONAL :: rfillvalue ! Fill value for real variables
  1630. CHARACTER(len=*), OPTIONAL :: conventions ! Conventions for variable
  1631. !! * Local variables
  1632. CHARACTER(LEN=18), PARAMETER :: &
  1633. & cpname = 'putvaratt_obfbdata'
  1634. CALL chkerr( nf90_put_att( idfile, idvar, 'long_name', &
  1635. & TRIM(cdlongname) ), &
  1636. & cpname, __LINE__ )
  1637. IF ( PRESENT(cdunits) ) THEN
  1638. CALL chkerr( nf90_put_att( idfile, idvar, 'units', &
  1639. & TRIM(cdunits) ), &
  1640. & cpname, __LINE__ )
  1641. ENDIF
  1642. IF ( PRESENT(conventions) ) THEN
  1643. CALL chkerr( nf90_put_att( idfile, idvar, 'Conventions', &
  1644. & TRIM(conventions) ), &
  1645. & cpname, __LINE__ )
  1646. ENDIF
  1647. IF ( PRESENT(cfillvalue) ) THEN
  1648. CALL chkerr( nf90_put_att( idfile, idvar, '_Fillvalue', &
  1649. & TRIM(cfillvalue) ), &
  1650. & cpname, __LINE__ )
  1651. ENDIF
  1652. IF ( PRESENT(ifillvalue) ) THEN
  1653. CALL chkerr( nf90_put_att( idfile, idvar, '_Fillvalue', &
  1654. & ifillvalue ), &
  1655. & cpname, __LINE__ )
  1656. ENDIF
  1657. IF ( PRESENT(rfillvalue) ) THEN
  1658. CALL chkerr( nf90_put_att( idfile, idvar, '_Fillvalue', &
  1659. & rfillvalue ), &
  1660. & cpname, __LINE__ )
  1661. ENDIF
  1662. END SUBROUTINE putvaratt_obfbdata
  1663. SUBROUTINE read_obfbdata( cdfilename, fbdata, ldgrid )
  1664. !!----------------------------------------------------------------------
  1665. !! *** ROUTINE read_obfbdata ***
  1666. !!
  1667. !! ** Purpose : Read an obfbdata structure from a netCDF file.
  1668. !!
  1669. !! ** Method :
  1670. !!
  1671. !! ** Action :
  1672. !!
  1673. !!----------------------------------------------------------------------
  1674. !! * Arguments
  1675. CHARACTER(len=*) :: cdfilename ! Input filename
  1676. TYPE(obfbdata) :: fbdata ! obsfbdata structure
  1677. LOGICAL, OPTIONAL :: ldgrid ! Allow forcing of grid info
  1678. !! * Local variables
  1679. CHARACTER(LEN=14), PARAMETER :: cpname = 'read_obfbdata'
  1680. INTEGER :: idfile
  1681. INTEGER :: idodim
  1682. INTEGER :: idldim
  1683. INTEGER :: idvdim
  1684. INTEGER :: idadim
  1685. INTEGER :: idedim
  1686. INTEGER :: idgdim
  1687. INTEGER :: idvard
  1688. INTEGER :: idaddd
  1689. INTEGER :: idextd
  1690. INTEGER :: idcdwmo
  1691. INTEGER :: idcdtyp
  1692. INTEGER :: idplam
  1693. INTEGER :: idpphi
  1694. INTEGER :: idpdep
  1695. INTEGER :: idptim
  1696. INTEGER :: idptimr
  1697. INTEGER :: idioqc
  1698. INTEGER :: idioqcf
  1699. INTEGER :: idipqc
  1700. INTEGER :: idipqcf
  1701. INTEGER :: ididqc
  1702. INTEGER :: ididqcf
  1703. INTEGER :: iditqc
  1704. INTEGER :: iditqcf
  1705. INTEGER :: idkindex
  1706. INTEGER, DIMENSION(:), ALLOCATABLE :: &
  1707. & idpob, &
  1708. & idivqc, &
  1709. & idivqcf, &
  1710. & idivlqc, &
  1711. & idivlqcf, &
  1712. & idiobsi, &
  1713. & idiobsj, &
  1714. & idiobsk, &
  1715. & idcgrid, &
  1716. & idpext
  1717. INTEGER, DIMENSION(:,:), ALLOCATABLE :: &
  1718. & idpadd
  1719. INTEGER :: jv
  1720. INTEGER :: je
  1721. INTEGER :: nvar
  1722. INTEGER :: nobs
  1723. INTEGER :: nlev
  1724. INTEGER :: nadd
  1725. INTEGER :: next
  1726. LOGICAL :: lgrid
  1727. CHARACTER(len=NF90_MAX_NAME) :: cdtmp
  1728. ! Check allocation status and deallocate previous allocated structures
  1729. IF ( fbdata%lalloc ) THEN
  1730. CALL dealloc_obfbdata( fbdata )
  1731. ENDIF
  1732. ! Open input filename
  1733. CALL chkerr( nf90_open( TRIM( cdfilename ), nf90_nowrite, idfile ), &
  1734. & cpname, __LINE__ )
  1735. ! Get input dimensions
  1736. CALL chkerr( nf90_inq_dimid( idfile, 'N_OBS' , idodim ), &
  1737. & cpname,__LINE__ )
  1738. CALL chkerr( nf90_inquire_dimension( idfile, idodim, len=nobs ), &
  1739. & cpname,__LINE__ )
  1740. CALL chkerr( nf90_inq_dimid( idfile, 'N_LEVELS', idldim ), &
  1741. & cpname,__LINE__ )
  1742. CALL chkerr( nf90_inquire_dimension( idfile, idldim, len=nlev ), &
  1743. & cpname,__LINE__ )
  1744. CALL chkerr( nf90_inq_dimid( idfile, 'N_VARS', idvdim ), &
  1745. & cpname,__LINE__ )
  1746. CALL chkerr( nf90_inquire_dimension( idfile, idvdim, len=nvar ), &
  1747. & cpname,__LINE__ )
  1748. IF ( nf90_inq_dimid( idfile, 'N_ENTRIES', idadim ) == 0 ) THEN
  1749. CALL chkerr( nf90_inquire_dimension( idfile, idadim, len=nadd ), &
  1750. & cpname,__LINE__ )
  1751. ELSE
  1752. nadd = 0
  1753. ENDIF
  1754. IF ( nf90_inq_dimid( idfile, 'N_EXTRA', idedim ) == 0 ) THEN
  1755. CALL chkerr( nf90_inquire_dimension( idfile, idedim, len=next ), &
  1756. & cpname,__LINE__ )
  1757. ELSE
  1758. next = 0
  1759. ENDIF
  1760. !
  1761. ! Check if this input file contains grid search informations
  1762. !
  1763. lgrid = ( nf90_inq_dimid( idfile, 'STRINGGRID', idgdim ) == 0 )
  1764. ! Allocate data structure
  1765. IF ( PRESENT(ldgrid) ) THEN
  1766. CALL alloc_obfbdata( fbdata, nvar, nobs, nlev, nadd, next, &
  1767. & lgrid.OR.ldgrid )
  1768. ELSE
  1769. CALL alloc_obfbdata( fbdata, nvar, nobs, nlev, nadd, next, &
  1770. & lgrid )
  1771. ENDIF
  1772. ! Allocate netcdf identifiers
  1773. ALLOCATE( &
  1774. & idpob(fbdata%nvar), &
  1775. & idivqc(fbdata%nvar), &
  1776. & idivqcf(fbdata%nvar), &
  1777. & idivlqc(fbdata%nvar), &
  1778. & idivlqcf(fbdata%nvar), &
  1779. & idiobsi(fbdata%nvar), &
  1780. & idiobsj(fbdata%nvar), &
  1781. & idiobsk(fbdata%nvar), &
  1782. & idcgrid(fbdata%nvar) &
  1783. & )
  1784. IF ( fbdata%nadd > 0 ) THEN
  1785. ALLOCATE( &
  1786. & idpadd(fbdata%nadd,fbdata%nvar) &
  1787. & )
  1788. ENDIF
  1789. IF ( fbdata%next > 0 ) THEN
  1790. ALLOCATE( &
  1791. & idpext(fbdata%next) &
  1792. & )
  1793. ENDIF
  1794. ! Read variables for header information
  1795. CALL chkerr( nf90_inq_varid( idfile, 'VARIABLES',idvard ), &
  1796. & cpname, __LINE__ )
  1797. CALL chkerr( nf90_get_var( idfile, idvard, fbdata%cname ), &
  1798. & cpname, __LINE__ )
  1799. IF ( fbdata%nadd > 0 ) THEN
  1800. CALL chkerr( nf90_inq_varid( idfile, 'ENTRIES', idaddd ), &
  1801. & cpname, __LINE__ )
  1802. CALL chkerr( nf90_get_var( idfile, idaddd, fbdata%caddname ), &
  1803. & cpname, __LINE__ )
  1804. ENDIF
  1805. IF ( fbdata%next > 0 ) THEN
  1806. CALL chkerr( nf90_inq_varid( idfile, 'EXTRA', idextd ), &
  1807. & cpname, __LINE__ )
  1808. CALL chkerr( nf90_get_var( idfile, idextd, fbdata%cextname ), &
  1809. & cpname, __LINE__ )
  1810. ENDIF
  1811. CALL chkerr( nf90_inq_varid( idfile, 'JULD_REFERENCE', idptimr ), &
  1812. & cpname, __LINE__ )
  1813. CALL chkerr( nf90_get_var( idfile, idptimr, fbdata%cdjuldref ), &
  1814. & cpname, __LINE__ )
  1815. IF ( fbdata%nobs > 0 ) THEN
  1816. CALL chkerr( nf90_inq_varid( idfile, 'STATION_IDENTIFIER', idcdwmo ),&
  1817. & cpname, __LINE__ )
  1818. CALL chkerr( nf90_get_var( idfile, idcdwmo, fbdata%cdwmo ), &
  1819. & cpname, __LINE__ )
  1820. CALL chkerr( nf90_inq_varid( idfile, 'STATION_TYPE', idcdtyp ), &
  1821. & cpname, __LINE__ )
  1822. CALL chkerr( nf90_get_var( idfile, idcdtyp, fbdata%cdtyp), &
  1823. & cpname, __LINE__ )
  1824. CALL chkerr( nf90_inq_varid( idfile, 'LONGITUDE', idplam ), &
  1825. & cpname, __LINE__ )
  1826. CALL chkerr( nf90_get_var( idfile, idplam, fbdata%plam ), &
  1827. & cpname, __LINE__ )
  1828. CALL chkerr( nf90_inq_varid( idfile, 'LATITUDE', idpphi ), &
  1829. & cpname, __LINE__ )
  1830. CALL chkerr( nf90_get_var( idfile, idpphi, fbdata%pphi ), &
  1831. & cpname, __LINE__ )
  1832. CALL chkerr( nf90_inq_varid( idfile, 'DEPTH', idpdep ), &
  1833. & cpname, __LINE__ )
  1834. CALL chkerr( nf90_get_var( idfile, idpdep, fbdata%pdep ), &
  1835. & cpname, __LINE__ )
  1836. CALL chkerr( nf90_inq_varid( idfile, 'JULD', idptim ), &
  1837. & cpname, __LINE__ )
  1838. CALL chkerr( nf90_get_var( idfile, idptim, fbdata%ptim ), &
  1839. & cpname, __LINE__ )
  1840. CALL chkerr( nf90_inq_varid( idfile, 'OBSERVATION_QC', idioqc ), &
  1841. & cpname, __LINE__ )
  1842. CALL chkerr( nf90_get_var( idfile, idioqc, fbdata%ioqc ), &
  1843. & cpname, __LINE__ )
  1844. CALL chkerr( nf90_inq_varid( idfile, 'OBSERVATION_QC_FLAGS', idioqcf ), &
  1845. & cpname, __LINE__ )
  1846. CALL chkerr( nf90_get_var( idfile, idioqcf, fbdata%ioqcf ), &
  1847. & cpname, __LINE__ )
  1848. CALL chkerr( nf90_inq_varid( idfile, 'POSITION_QC', idipqc ), &
  1849. & cpname, __LINE__ )
  1850. CALL chkerr( nf90_get_var( idfile, idipqc, fbdata%ipqc ), &
  1851. & cpname, __LINE__ )
  1852. CALL chkerr( nf90_inq_varid( idfile, 'POSITION_QC_FLAGS', idipqcf ), &
  1853. & cpname, __LINE__ )
  1854. CALL chkerr( nf90_get_var( idfile, idipqcf, fbdata%ipqcf ), &
  1855. & cpname, __LINE__ )
  1856. CALL chkerr( nf90_inq_varid( idfile, 'DEPTH_QC', ididqc ), &
  1857. & cpname, __LINE__ )
  1858. CALL chkerr( nf90_get_var( idfile, ididqc, fbdata%idqc ), &
  1859. & cpname, __LINE__ )
  1860. CALL chkerr( nf90_inq_varid( idfile, 'DEPTH_QC_FLAGS', ididqcf ), &
  1861. & cpname, __LINE__ )
  1862. CALL chkerr( nf90_get_var( idfile, ididqcf, fbdata%idqcf ), &
  1863. & cpname, __LINE__ )
  1864. CALL chkerr( nf90_inq_varid( idfile, 'JULD_QC', iditqc ), &
  1865. & cpname, __LINE__ )
  1866. CALL chkerr( nf90_get_var( idfile, iditqc, fbdata%itqc ), &
  1867. & cpname, __LINE__ )
  1868. CALL chkerr( nf90_inq_varid( idfile, 'JULD_QC_FLAGS', iditqcf ), &
  1869. & cpname, __LINE__ )
  1870. CALL chkerr( nf90_get_var( idfile, iditqcf, fbdata%itqcf ), &
  1871. & cpname, __LINE__ )
  1872. CALL chkerr( nf90_inq_varid( idfile, 'ORIGINAL_FILE_INDEX', idkindex ), &
  1873. & cpname, __LINE__ )
  1874. CALL chkerr( nf90_get_var( idfile, idkindex, fbdata%kindex ), &
  1875. & cpname, __LINE__ )
  1876. ! Read netCDF variables for individual variables
  1877. DO jv = 1, fbdata%nvar
  1878. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_OBS'
  1879. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idpob(jv) ), &
  1880. & cpname, __LINE__ )
  1881. CALL chkerr( nf90_get_var( idfile, idpob(jv), &
  1882. & fbdata%pob(:,:,jv) ), &
  1883. & cpname, __LINE__ )
  1884. CALL getvaratt_obfbdata( idfile, idpob(jv), &
  1885. & fbdata%coblong(jv), &
  1886. & fbdata%cobunit(jv) )
  1887. IF ( fbdata%nadd > 0 ) THEN
  1888. DO je = 1, fbdata%nadd
  1889. WRITE(cdtmp,'(3A)') TRIM(fbdata%cname(jv)),'_',&
  1890. & TRIM(fbdata%caddname(je))
  1891. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idpadd(je,jv) ), &
  1892. & cpname, __LINE__ )
  1893. CALL chkerr( nf90_get_var( idfile, idpadd(je,jv), &
  1894. & fbdata%padd(:,:,je,jv) ), &
  1895. & cpname, __LINE__ )
  1896. CALL getvaratt_obfbdata( idfile, idpadd(je,jv), &
  1897. & fbdata%caddlong(je,jv), &
  1898. & fbdata%caddunit(je,jv) )
  1899. END DO
  1900. ENDIF
  1901. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_QC'
  1902. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idivqc(jv) ), &
  1903. & cpname, __LINE__ )
  1904. CALL chkerr( nf90_get_var( idfile, idivqc(jv), &
  1905. & fbdata%ivqc(:,jv) ), &
  1906. & cpname, __LINE__ )
  1907. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_QC_FLAGS'
  1908. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idivqcf(jv) ), &
  1909. & cpname, __LINE__ )
  1910. CALL chkerr( nf90_get_var( idfile, idivqcf(jv), &
  1911. & fbdata%ivqcf(:,:,jv) ), &
  1912. & cpname, __LINE__ )
  1913. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_LEVEL_QC'
  1914. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idivlqc(jv) ), &
  1915. & cpname, __LINE__ )
  1916. CALL chkerr( nf90_get_var( idfile, idivlqc(jv), &
  1917. & fbdata%ivlqc(:,:,jv) ), &
  1918. & cpname, __LINE__ )
  1919. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_LEVEL_QC_FLAGS'
  1920. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idivlqcf(jv) ), &
  1921. & cpname, __LINE__ )
  1922. CALL chkerr( nf90_get_var( idfile, idivlqcf(jv), &
  1923. & fbdata%ivlqcf(:,:,:,jv) ), &
  1924. & cpname, __LINE__ )
  1925. IF ( lgrid ) THEN
  1926. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_IOBSI'
  1927. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idiobsi(jv) ), &
  1928. & cpname, __LINE__ )
  1929. CALL chkerr( nf90_get_var( idfile, idiobsi(jv), &
  1930. & fbdata%iobsi(:,jv) ), &
  1931. & cpname, __LINE__ )
  1932. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_IOBSJ'
  1933. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idiobsj(jv) ), &
  1934. & cpname, __LINE__ )
  1935. CALL chkerr( nf90_get_var( idfile, idiobsj(jv), &
  1936. & fbdata%iobsj(:,jv) ), &
  1937. & cpname, __LINE__ )
  1938. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_IOBSK'
  1939. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idiobsk(jv) ), &
  1940. & cpname, __LINE__ )
  1941. CALL chkerr( nf90_get_var( idfile, idiobsk(jv), &
  1942. & fbdata%iobsk(:,:,jv) ), &
  1943. & cpname, __LINE__ )
  1944. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_GRID'
  1945. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idcgrid(jv) ), &
  1946. & cpname, __LINE__ )
  1947. CALL chkerr( nf90_get_var( idfile, idcgrid(jv), &
  1948. & fbdata%cgrid(jv) ), &
  1949. & cpname, __LINE__ )
  1950. ENDIF
  1951. END DO
  1952. IF ( fbdata%next > 0 ) THEN
  1953. DO je = 1, fbdata%next
  1954. WRITE(cdtmp,'(A)') TRIM(fbdata%cextname(je))
  1955. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idpext(je) ), &
  1956. & cpname, __LINE__ )
  1957. CALL chkerr( nf90_get_var( idfile, idpext(je), &
  1958. & fbdata%pext(:,:,je) ), &
  1959. & cpname, __LINE__ )
  1960. CALL getvaratt_obfbdata( idfile, idpext(je), &
  1961. & fbdata%cextlong(je), &
  1962. & fbdata%cextunit(je) )
  1963. END DO
  1964. ENDIF
  1965. ELSE ! if no observations only get attributes
  1966. DO jv = 1, fbdata%nvar
  1967. WRITE(cdtmp,'(2A)') TRIM(fbdata%cname(jv)),'_OBS'
  1968. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idpob(jv) ), &
  1969. & cpname, __LINE__ )
  1970. CALL getvaratt_obfbdata( idfile, idpob(jv), &
  1971. & fbdata%coblong(jv), &
  1972. & fbdata%cobunit(jv) )
  1973. IF ( fbdata%nadd > 0 ) THEN
  1974. DO je = 1, fbdata%nadd
  1975. WRITE(cdtmp,'(3A)') TRIM(fbdata%cname(jv)),'_',&
  1976. & TRIM(fbdata%caddname(je))
  1977. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idpadd(je,jv) ), &
  1978. & cpname, __LINE__ )
  1979. CALL getvaratt_obfbdata( idfile, idpadd(je,jv), &
  1980. & fbdata%caddlong(je,jv), &
  1981. & fbdata%caddunit(je,jv) )
  1982. END DO
  1983. ENDIF
  1984. END DO
  1985. IF ( fbdata%next > 0 ) THEN
  1986. DO je = 1, fbdata%next
  1987. WRITE(cdtmp,'(A)') TRIM(fbdata%cextname(je))
  1988. CALL chkerr( nf90_inq_varid( idfile, cdtmp, idpext(je) ), &
  1989. & cpname, __LINE__ )
  1990. CALL getvaratt_obfbdata( idfile, idpext(je), &
  1991. & fbdata%cextlong(je), &
  1992. & fbdata%cextunit(je) )
  1993. END DO
  1994. ENDIF
  1995. ENDIF
  1996. ! Close the file
  1997. CALL chkerr( nf90_close( idfile ), cpname, __LINE__ )
  1998. END SUBROUTINE read_obfbdata
  1999. SUBROUTINE getvaratt_obfbdata( idfile, idvar, cdlongname, cdunits )
  2000. !!----------------------------------------------------------------------
  2001. !! *** ROUTINE putvaratt_obfbdata ***
  2002. !!
  2003. !! ** Purpose : Read netcdf attributes for variable
  2004. !!
  2005. !! ** Method :
  2006. !!
  2007. !! ** Action :
  2008. !!
  2009. !!----------------------------------------------------------------------
  2010. !! * Arguments
  2011. INTEGER :: idfile ! File netcdf id.
  2012. INTEGER :: idvar ! Variable netcdf id.
  2013. CHARACTER(len=*) :: cdlongname ! Long name for variable
  2014. CHARACTER(len=*) :: cdunits ! Units for variable
  2015. !! * Local variables
  2016. CHARACTER(LEN=18), PARAMETER :: cpname = 'getvaratt_obfbdata'
  2017. CALL chkerr( nf90_get_att( idfile, idvar, 'long_name', &
  2018. & cdlongname ), &
  2019. & cpname, __LINE__ )
  2020. CALL chkerr( nf90_get_att( idfile, idvar, 'units', &
  2021. & cdunits ), &
  2022. & cpname, __LINE__ )
  2023. END SUBROUTINE getvaratt_obfbdata
  2024. END MODULE obs_fbm