obs_profiles_def.F90 31 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921
  1. MODULE obs_profiles_def
  2. !!=====================================================================
  3. !! *** MODULE obs_profiles_def ***
  4. !! Observation diagnostics: Storage handling for T,S profiles
  5. !! arrays and additional flags etc.
  6. !! This module only defines the data type and
  7. !! operations on the data type. There is no
  8. !! actual data in the module.
  9. !!=====================================================================
  10. !!----------------------------------------------------------------------
  11. !! obs_prof : F90 type containing the profile information
  12. !! obs_prof_var : F90 type containing the variable definition
  13. !! obs_prof_valid : F90 type containing the valid obs. definition
  14. !! obs_prof_alloc : Allocates profile arrays
  15. !! obs_prof_dealloc : Deallocates profile arrays
  16. !! obs_prof_compress : Extract sub-information from a obs_prof type
  17. !! to a new obs_prof type
  18. !! obs_prof_decompress : Reinsert sub-information from a obs_prof type
  19. !! into the original obs_prof type
  20. !! obs_prof_staend : Set npvsta and npvend of a variable within an
  21. !! obs_prof_var type
  22. !!----------------------------------------------------------------------
  23. !! * Modules used
  24. USE par_kind, ONLY : & ! Precision variables
  25. & wp
  26. USE in_out_manager ! I/O manager
  27. USE obs_mpp, ONLY : & ! MPP tools
  28. obs_mpp_sum_integers
  29. USE obs_fbm ! Obs feedback format
  30. USE lib_mpp, ONLY : &
  31. & ctl_warn, ctl_stop
  32. IMPLICIT NONE
  33. !! * Routine/type accessibility
  34. PRIVATE
  35. PUBLIC &
  36. & obs_prof, &
  37. & obs_prof_var, &
  38. & obs_prof_valid, &
  39. & obs_prof_alloc, &
  40. & obs_prof_alloc_var, &
  41. & obs_prof_dealloc, &
  42. & obs_prof_compress, &
  43. & obs_prof_decompress,&
  44. & obs_prof_staend
  45. !! * Type definition for valid observations
  46. TYPE obs_prof_valid
  47. LOGICAL, POINTER, DIMENSION(:) :: luse
  48. END TYPE obs_prof_valid
  49. !! * Type definition for each variable
  50. TYPE obs_prof_var
  51. ! Arrays with size equal to the number of observations
  52. INTEGER, POINTER, DIMENSION(:) :: &
  53. & mvk, & !: k-th grid coord. for interpolating to profile data
  54. & nvpidx,& !: Profile number
  55. & nvlidx,& !: Level number in profile
  56. & nvqc, & !: Variable QC flags
  57. & idqc !: Depth QC flag
  58. REAL(KIND=wp), POINTER, DIMENSION(:) :: &
  59. & vdep, & !: Depth coordinate of profile data
  60. & vobs, & !: Profile data
  61. & vmod !: Model counterpart of the profile data vector
  62. REAL(KIND=wp), POINTER, DIMENSION(:,:) :: &
  63. & vext !: Extra variables
  64. INTEGER, POINTER, DIMENSION(:) :: &
  65. & nvind !: Source indices of temp. data in compressed data
  66. ! Arrays with size equal to idefnqcf times the number of observations
  67. INTEGER, POINTER, DIMENSION(:,:) :: &
  68. & idqcf, & !: Depth QC flags
  69. & nvqcf !: Variable QC flags
  70. END TYPE obs_prof_var
  71. !! * Type definition for profile observation type
  72. TYPE obs_prof
  73. ! Bookkeeping
  74. INTEGER :: nvar !: Number of variables
  75. INTEGER :: next !: Number of extra fields
  76. INTEGER :: nprof !: Total number of profiles within window.
  77. INTEGER :: nstp !: Number of time steps
  78. INTEGER :: npi !: Number of 3D grid points
  79. INTEGER :: npj
  80. INTEGER :: npk
  81. INTEGER :: nprofup !: Observation counter used in obs_oper
  82. ! Bookkeeping arrays with sizes equal to number of variables
  83. INTEGER, POINTER, DIMENSION(:) :: &
  84. & nvprot, & !: Local total number of profile T data
  85. & nvprotmpp !: Global total number of profile T data
  86. ! Arrays with size equal to the number of profiles
  87. INTEGER, POINTER, DIMENSION(:) :: &
  88. & npidx,& !: Profile number
  89. & npfil,& !: Profile number in file
  90. & nyea, & !: Year of profile
  91. & nmon, & !: Month of profile
  92. & nday, & !: Day of profile
  93. & nhou, & !: Hour of profile
  94. & nmin, & !: Minute of profile
  95. & mstp, & !: Time step nearest to profile
  96. & nqc, & !: Profile QC
  97. & ntyp, & !: Type of profile product (WMO table 1770)
  98. & ipqc, & !: Position QC
  99. & itqc !: Time QC
  100. REAL(KIND=wp), POINTER, DIMENSION(:) :: &
  101. & rlam, & !: Longitude coordinate of profile data
  102. & rphi !: Latitude coordinate of profile data
  103. CHARACTER(LEN=8), POINTER, DIMENSION(:) :: &
  104. & cwmo !: Profile WMO indentifier
  105. ! Arrays with size equal to the number of profiles times
  106. ! number of variables
  107. INTEGER, POINTER, DIMENSION(:,:) :: &
  108. & npvsta, & !: Start of each variable profile in full arrays
  109. & npvend, & !: End of each variable profile in full arrays
  110. & mi, & !: i-th grid coord. for interpolating to profile T data
  111. & mj, & !: j-th grid coord. for interpolating to profile T data
  112. & ivqc !: QC flags for all levels for a variable
  113. ! Arrays with size equal to idefnqcf
  114. ! the number of profiles times number of variables
  115. INTEGER, POINTER, DIMENSION(:,:) :: &
  116. & nqcf, & !: Observation QC flags
  117. & ipqcf, & !: Position QC flags
  118. & itqcf !: Time QC flags
  119. ! Arrays with size equal to idefnqcf
  120. ! the number of profiles times number of variables
  121. INTEGER, POINTER, DIMENSION(:,:,:) :: &
  122. & ivqcf
  123. ! Arrays of variables
  124. TYPE(obs_prof_var), POINTER, DIMENSION(:) :: var
  125. ! Arrays with size equal to the number of time steps in the window
  126. INTEGER, POINTER, DIMENSION(:) :: &
  127. & npstp, & !: Total number of profiles
  128. & npstpmpp !: Total number of profiles
  129. ! Arrays with size equal to the number of time steps in the window times
  130. ! number of variables
  131. INTEGER, POINTER, DIMENSION(:,:) :: &
  132. & nvstp, & !: Local total num. of profile data each time step
  133. & nvstpmpp !: Global total num. of profile data each time step
  134. ! Arrays with size equal to the number of grid points times number of
  135. ! variables
  136. REAL(KIND=wp), POINTER, DIMENSION(:,:,:,:) :: &
  137. & vdmean !: Daily averaged model field
  138. ! Arrays used to store source indices when
  139. ! compressing obs_prof derived types
  140. ! Array with size nprof
  141. INTEGER, POINTER, DIMENSION(:) :: &
  142. & npind !: Source indices of profile data in compressed data
  143. END TYPE obs_prof
  144. !!----------------------------------------------------------------------
  145. !! NEMO/OPA 3.3 , NEMO Consortium (2010)
  146. !! $Id: obs_profiles_def.F90 2715 2011-03-30 15:58:35Z rblod $
  147. !! Software governed by the CeCILL licence (NEMOGCM/NEMO_CeCILL.txt)
  148. !!----------------------------------------------------------------------
  149. CONTAINS
  150. SUBROUTINE obs_prof_alloc( prof, kvar, kext, kprof, &
  151. & ko3dt, kstp, kpi, kpj, kpk )
  152. !!----------------------------------------------------------------------
  153. !! *** ROUTINE obs_prof_alloc ***
  154. !!
  155. !! ** Purpose : - Allocate data for profile arrays
  156. !!
  157. !! ** Method : - Fortran-90 dynamic arrays
  158. !!
  159. !! History :
  160. !! ! 07-01 (K. Mogensen) Original code
  161. !! ! 07-03 (K. Mogensen) Generalized profiles
  162. !!----------------------------------------------------------------------
  163. !! * Arguments
  164. TYPE(obs_prof), INTENT(INOUT) :: prof ! Profile data to be allocated
  165. INTEGER, INTENT(IN) :: kprof ! Number of profiles
  166. INTEGER, INTENT(IN) :: kvar ! Number of variables
  167. INTEGER, INTENT(IN) :: kext ! Number of extra fields within each variable
  168. INTEGER, INTENT(IN), DIMENSION(kvar) :: &
  169. & ko3dt ! Number of observations per variables
  170. INTEGER, INTENT(IN) :: kstp ! Number of time steps
  171. INTEGER, INTENT(IN) :: kpi ! Number of 3D grid points
  172. INTEGER, INTENT(IN) :: kpj
  173. INTEGER, INTENT(IN) :: kpk
  174. !!* Local variables
  175. INTEGER :: jvar
  176. INTEGER :: ji
  177. ! Set bookkeeping variables
  178. prof%nvar = kvar
  179. prof%next = kext
  180. prof%nprof = kprof
  181. prof%nstp = kstp
  182. prof%npi = kpi
  183. prof%npj = kpj
  184. prof%npk = kpk
  185. ! Allocate arrays of size number of variables
  186. ALLOCATE( &
  187. & prof%nvprot(kvar), &
  188. & prof%nvprotmpp(kvar) &
  189. )
  190. DO jvar = 1, kvar
  191. prof%nvprot (jvar) = ko3dt(jvar)
  192. prof%nvprotmpp(jvar) = 0
  193. END DO
  194. ! Allocate arrays of size number of profiles
  195. ! times number of variables
  196. ALLOCATE( &
  197. & prof%npvsta(kprof,kvar), &
  198. & prof%npvend(kprof,kvar), &
  199. & prof%mi(kprof,kvar), &
  200. & prof%mj(kprof,kvar), &
  201. & prof%ivqc(kprof,kvar) &
  202. )
  203. ! Allocate arrays of size iqcfdef times number of profiles
  204. ! times number of variables
  205. ALLOCATE( &
  206. & prof%ivqcf(idefnqcf,kprof,kvar) &
  207. & )
  208. ! Allocate arrays of size number of profiles
  209. ALLOCATE( &
  210. & prof%npidx(kprof), &
  211. & prof%npfil(kprof), &
  212. & prof%nyea(kprof), &
  213. & prof%nmon(kprof), &
  214. & prof%nday(kprof), &
  215. & prof%nhou(kprof), &
  216. & prof%nmin(kprof), &
  217. & prof%mstp(kprof), &
  218. & prof%nqc(kprof), &
  219. & prof%ipqc(kprof), &
  220. & prof%itqc(kprof), &
  221. & prof%ntyp(kprof), &
  222. & prof%rlam(kprof), &
  223. & prof%rphi(kprof), &
  224. & prof%cwmo(kprof), &
  225. & prof%npind(kprof) &
  226. & )
  227. ! Allocate arrays of size idefnqcf times number of profiles
  228. ALLOCATE( &
  229. & prof%nqcf(idefnqcf,kprof), &
  230. & prof%ipqcf(idefnqcf,kprof), &
  231. & prof%itqcf(idefnqcf,kprof) &
  232. & )
  233. ! Allocate obs_prof_var type
  234. ALLOCATE( &
  235. & prof%var(kvar) &
  236. & )
  237. ! For each variables allocate arrays of size number of observations
  238. DO jvar = 1, kvar
  239. IF ( ko3dt(jvar) >= 0 ) THEN
  240. CALL obs_prof_alloc_var( prof, jvar, kext, ko3dt(jvar) )
  241. ENDIF
  242. END DO
  243. ! Allocate arrays of size number of time step size
  244. ALLOCATE( &
  245. & prof%npstp(kstp), &
  246. & prof%npstpmpp(kstp) &
  247. & )
  248. ! Allocate arrays of size number of time step size times
  249. ! number of variables
  250. ALLOCATE( &
  251. & prof%nvstp(kstp,kvar), &
  252. & prof%nvstpmpp(kstp,kvar) &
  253. & )
  254. ! Allocate arrays of size number of grid points size times
  255. ! number of variables
  256. ALLOCATE( &
  257. & prof%vdmean(kpi,kpj,kpk,kvar) &
  258. & )
  259. ! Set defaults for compression indices
  260. DO ji = 1, kprof
  261. prof%npind(ji) = ji
  262. END DO
  263. DO jvar = 1, kvar
  264. DO ji = 1, ko3dt(jvar)
  265. prof%var(jvar)%nvind(ji) = ji
  266. END DO
  267. END DO
  268. ! Set defaults for number of observations per time step
  269. prof%npstp(:) = 0
  270. prof%npstpmpp(:) = 0
  271. prof%nvstp(:,:) = 0
  272. prof%nvstpmpp(:,:) = 0
  273. ! Set the observation counter used in obs_oper
  274. prof%nprofup = 0
  275. END SUBROUTINE obs_prof_alloc
  276. SUBROUTINE obs_prof_dealloc( prof )
  277. !!----------------------------------------------------------------------
  278. !! *** ROUTINE obs_prof_dealloc ***
  279. !!
  280. !! ** Purpose : - Deallocate data for profile arrays
  281. !!
  282. !! ** Method : - Fortran-90 dynamic arrays
  283. !!
  284. !! History :
  285. !! ! 07-01 (K. Mogensen) Original code
  286. !!----------------------------------------------------------------------
  287. !! * Arguments
  288. TYPE(obs_prof), INTENT(INOUT) :: &
  289. & prof ! Profile data to be deallocated
  290. !!* Local variables
  291. INTEGER :: &
  292. & jvar
  293. ! Deallocate arrays of size number of profiles
  294. ! times number of variables
  295. DEALLOCATE( &
  296. & prof%npvsta, &
  297. & prof%npvend &
  298. )
  299. ! Dellocate arrays of size number of profiles size
  300. DEALLOCATE( &
  301. & prof%mi, &
  302. & prof%mj, &
  303. & prof%ivqc, &
  304. & prof%ivqcf, &
  305. & prof%npidx, &
  306. & prof%npfil, &
  307. & prof%nyea, &
  308. & prof%nmon, &
  309. & prof%nday, &
  310. & prof%nhou, &
  311. & prof%nmin, &
  312. & prof%mstp, &
  313. & prof%nqc, &
  314. & prof%ipqc, &
  315. & prof%itqc, &
  316. & prof%nqcf, &
  317. & prof%ipqcf, &
  318. & prof%itqcf, &
  319. & prof%ntyp, &
  320. & prof%rlam, &
  321. & prof%rphi, &
  322. & prof%cwmo, &
  323. & prof%npind &
  324. & )
  325. ! For each variables allocate arrays of size number of observations
  326. DO jvar = 1, prof%nvar
  327. IF ( prof%nvprot(jvar) >= 0 ) THEN
  328. CALL obs_prof_dealloc_var( prof, jvar )
  329. ENDIF
  330. END DO
  331. ! Dellocate obs_prof_var type
  332. DEALLOCATE( &
  333. & prof%var &
  334. & )
  335. ! Deallocate arrays of size number of time step size
  336. DEALLOCATE( &
  337. & prof%npstp, &
  338. & prof%npstpmpp &
  339. & )
  340. ! Deallocate arrays of size number of time step size times
  341. ! number of variables
  342. DEALLOCATE( &
  343. & prof%nvstp, &
  344. & prof%nvstpmpp &
  345. & )
  346. ! Deallocate arrays of size number of grid points size times
  347. ! number of variables
  348. DEALLOCATE( &
  349. & prof%vdmean &
  350. & )
  351. ! Dellocate arrays of size number of variables
  352. DEALLOCATE( &
  353. & prof%nvprot, &
  354. & prof%nvprotmpp &
  355. )
  356. END SUBROUTINE obs_prof_dealloc
  357. SUBROUTINE obs_prof_alloc_var( prof, kvar, kext, kobs )
  358. !!----------------------------------------------------------------------
  359. !! *** ROUTINE obs_prof_alloc_var ***
  360. !!
  361. !! ** Purpose : - Allocate data for variable data in profile arrays
  362. !!
  363. !! ** Method : - Fortran-90 dynamic arrays
  364. !!
  365. !! History :
  366. !! ! 07-03 (K. Mogensen) Original code
  367. !! * Arguments
  368. TYPE(obs_prof), INTENT(INOUT) :: prof ! Profile data to be allocated
  369. INTEGER, INTENT(IN) :: kvar ! Variable number
  370. INTEGER, INTENT(IN) :: kext ! Number of extra fields within each variable
  371. INTEGER, INTENT(IN) :: kobs ! Number of observations
  372. ALLOCATE( &
  373. & prof%var(kvar)%mvk(kobs), &
  374. & prof%var(kvar)%nvpidx(kobs), &
  375. & prof%var(kvar)%nvlidx(kobs), &
  376. & prof%var(kvar)%nvqc(kobs), &
  377. & prof%var(kvar)%idqc(kobs), &
  378. & prof%var(kvar)%vdep(kobs), &
  379. & prof%var(kvar)%vobs(kobs), &
  380. & prof%var(kvar)%vmod(kobs), &
  381. & prof%var(kvar)%nvind(kobs) &
  382. & )
  383. ALLOCATE( &
  384. & prof%var(kvar)%idqcf(idefnqcf,kobs), &
  385. & prof%var(kvar)%nvqcf(idefnqcf,kobs) &
  386. & )
  387. IF (kext>0) THEN
  388. ALLOCATE( &
  389. & prof%var(kvar)%vext(kobs,kext) &
  390. & )
  391. ENDIF
  392. END SUBROUTINE obs_prof_alloc_var
  393. SUBROUTINE obs_prof_dealloc_var( prof, kvar )
  394. !!----------------------------------------------------------------------
  395. !! *** ROUTINE obs_prof_alloc_var ***
  396. !!
  397. !! ** Purpose : - Allocate data for variable data in profile arrays
  398. !!
  399. !! ** Method : - Fortran-90 dynamic arrays
  400. !!
  401. !! History :
  402. !! ! 07-03 (K. Mogensen) Original code
  403. !! * Arguments
  404. TYPE(obs_prof), INTENT(INOUT) :: prof ! Profile data to be allocated
  405. INTEGER, INTENT(IN) :: kvar ! Variable number
  406. DEALLOCATE( &
  407. & prof%var(kvar)%mvk, &
  408. & prof%var(kvar)%nvpidx, &
  409. & prof%var(kvar)%nvlidx, &
  410. & prof%var(kvar)%nvqc, &
  411. & prof%var(kvar)%idqc, &
  412. & prof%var(kvar)%vdep, &
  413. & prof%var(kvar)%vobs, &
  414. & prof%var(kvar)%vmod, &
  415. & prof%var(kvar)%nvind, &
  416. & prof%var(kvar)%idqcf, &
  417. & prof%var(kvar)%nvqcf &
  418. & )
  419. IF (prof%next>0) THEN
  420. DEALLOCATE( &
  421. & prof%var(kvar)%vext &
  422. & )
  423. ENDIF
  424. END SUBROUTINE obs_prof_dealloc_var
  425. SUBROUTINE obs_prof_compress( prof, newprof, lallocate, &
  426. & kumout, lvalid, lvvalid )
  427. !!----------------------------------------------------------------------
  428. !! *** ROUTINE obs_prof_compress ***
  429. !!
  430. !! ** Purpose : - Extract sub-information from a obs_prof type
  431. !! into a new obs_prof type
  432. !!
  433. !! ** Method : - The data is copied from prof to new prof.
  434. !! In the case of lvalid and lvvalid both being
  435. !! present only the selected data will be copied.
  436. !! If lallocate is true the data in the newprof is
  437. !! allocated either with the same number of elements
  438. !! as prof or with only the subset of elements defined
  439. !! by the optional selection in lvalid and lvvalid
  440. !!
  441. !! History :
  442. !! ! 07-01 (K. Mogensen) Original code
  443. !!----------------------------------------------------------------------
  444. !! * Arguments
  445. TYPE(obs_prof), INTENT(IN) :: prof ! Original profile
  446. TYPE(obs_prof), INTENT(INOUT) :: newprof ! New profile with the copy of the data
  447. LOGICAL :: lallocate ! Allocate newprof data
  448. INTEGER,INTENT(IN) :: kumout ! Fortran unit for messages
  449. TYPE(obs_prof_valid), OPTIONAL, INTENT(in) :: &
  450. & lvalid ! Valid profiles
  451. TYPE(obs_prof_valid), OPTIONAL, INTENT(in), DIMENSION(prof%nvar) :: &
  452. & lvvalid ! Valid data within the profiles
  453. !!* Local variables
  454. INTEGER :: inprof
  455. INTEGER, DIMENSION(prof%nvar) :: &
  456. & invpro
  457. INTEGER :: jvar
  458. INTEGER :: jext
  459. INTEGER :: ji
  460. INTEGER :: jj
  461. LOGICAL :: lfirst
  462. TYPE(obs_prof_valid) :: &
  463. & llvalid
  464. TYPE(obs_prof_valid), DIMENSION(prof%nvar) :: &
  465. & llvvalid
  466. LOGICAL :: lallpresent
  467. LOGICAL :: lnonepresent
  468. ! Check that either all or none of the masks are persent.
  469. lallpresent = .FALSE.
  470. lnonepresent = .FALSE.
  471. IF ( PRESENT(lvalid) .AND. PRESENT(lvvalid) ) THEN
  472. lallpresent = .TRUE.
  473. ELSEIF ( ( .NOT. PRESENT(lvalid) ) .AND. &
  474. & ( .NOT. PRESENT(lvvalid) ) ) THEN
  475. lnonepresent = .TRUE.
  476. ELSE
  477. CALL ctl_stop('Error in obs_prof_compress:', &
  478. & 'Either all selection variables should be set', &
  479. & 'or no selection variable should be set' )
  480. ENDIF
  481. ! Count how many elements there should be in the new data structure
  482. IF ( lallpresent ) THEN
  483. inprof = 0
  484. invpro(:) = 0
  485. DO ji = 1, prof%nprof
  486. IF ( lvalid%luse(ji) ) THEN
  487. inprof=inprof+1
  488. DO jvar = 1, prof%nvar
  489. DO jj = prof%npvsta(ji,jvar), prof%npvend(ji,jvar)
  490. IF ( lvvalid(jvar)%luse(jj) ) &
  491. & invpro(jvar) = invpro(jvar) +1
  492. END DO
  493. END DO
  494. ENDIF
  495. END DO
  496. ELSE
  497. inprof = prof%nprof
  498. invpro(:) = prof%nvprot(:)
  499. ENDIF
  500. ! Optionally allocate data in the new data structure
  501. IF ( lallocate ) THEN
  502. CALL obs_prof_alloc( newprof, prof%nvar, &
  503. & prof%next, &
  504. & inprof, invpro, &
  505. & prof%nstp, prof%npi, &
  506. & prof%npj, prof%npk )
  507. ENDIF
  508. ! Allocate temporary mask array to unify the code for both cases
  509. ALLOCATE( llvalid%luse(prof%nprof) )
  510. DO jvar = 1, prof%nvar
  511. ALLOCATE( llvvalid(jvar)%luse(prof%nvprot(jvar)) )
  512. END DO
  513. IF ( lallpresent ) THEN
  514. llvalid%luse(:) = lvalid%luse(:)
  515. DO jvar = 1, prof%nvar
  516. llvvalid(jvar)%luse(:) = lvvalid(jvar)%luse(:)
  517. END DO
  518. ELSE
  519. llvalid%luse(:) = .TRUE.
  520. DO jvar = 1, prof%nvar
  521. llvvalid(jvar)%luse(:) = .TRUE.
  522. END DO
  523. ENDIF
  524. ! Setup bookkeeping variables
  525. inprof = 0
  526. invpro(:) = 0
  527. newprof%npvsta(:,:) = 0
  528. newprof%npvend(:,:) = -1
  529. ! Loop over source profiles
  530. DO ji = 1, prof%nprof
  531. IF ( llvalid%luse(ji) ) THEN
  532. ! Copy the header information
  533. inprof = inprof + 1
  534. newprof%mi(inprof,:) = prof%mi(ji,:)
  535. newprof%mj(inprof,:) = prof%mj(ji,:)
  536. newprof%npidx(inprof) = prof%npidx(ji)
  537. newprof%npfil(inprof) = prof%npfil(ji)
  538. newprof%nyea(inprof) = prof%nyea(ji)
  539. newprof%nmon(inprof) = prof%nmon(ji)
  540. newprof%nday(inprof) = prof%nday(ji)
  541. newprof%nhou(inprof) = prof%nhou(ji)
  542. newprof%nmin(inprof) = prof%nmin(ji)
  543. newprof%mstp(inprof) = prof%mstp(ji)
  544. newprof%nqc(inprof) = prof%nqc(ji)
  545. newprof%ipqc(inprof) = prof%ipqc(ji)
  546. newprof%itqc(inprof) = prof%itqc(ji)
  547. newprof%ivqc(inprof,:)= prof%ivqc(ji,:)
  548. newprof%ntyp(inprof) = prof%ntyp(ji)
  549. newprof%rlam(inprof) = prof%rlam(ji)
  550. newprof%rphi(inprof) = prof%rphi(ji)
  551. newprof%cwmo(inprof) = prof%cwmo(ji)
  552. ! QC info
  553. newprof%nqcf(:,inprof) = prof%nqcf(:,ji)
  554. newprof%ipqcf(:,inprof) = prof%ipqcf(:,ji)
  555. newprof%itqcf(:,inprof) = prof%itqcf(:,ji)
  556. newprof%ivqcf(:,inprof,:) = prof%ivqcf(:,ji,:)
  557. ! npind is the index of the original profile
  558. newprof%npind(inprof) = ji
  559. ! Copy the variable information
  560. DO jvar = 1, prof%nvar
  561. lfirst = .TRUE.
  562. DO jj = prof%npvsta(ji,jvar), prof%npvend(ji,jvar)
  563. IF ( llvvalid(jvar)%luse(jj) ) THEN
  564. invpro(jvar) = invpro(jvar) + 1
  565. ! Book keeping information
  566. IF ( lfirst ) THEN
  567. lfirst = .FALSE.
  568. newprof%npvsta(inprof,jvar) = invpro(jvar)
  569. ENDIF
  570. newprof%npvend(inprof,jvar) = invpro(jvar)
  571. ! Variable data
  572. newprof%var(jvar)%mvk(invpro(jvar)) = &
  573. & prof%var(jvar)%mvk(jj)
  574. newprof%var(jvar)%nvpidx(invpro(jvar)) = &
  575. & prof%var(jvar)%nvpidx(jj)
  576. newprof%var(jvar)%nvlidx(invpro(jvar)) = &
  577. & prof%var(jvar)%nvlidx(jj)
  578. newprof%var(jvar)%nvqc(invpro(jvar)) = &
  579. & prof%var(jvar)%nvqc(jj)
  580. newprof%var(jvar)%idqc(invpro(jvar)) = &
  581. & prof%var(jvar)%idqc(jj)
  582. newprof%var(jvar)%idqcf(:,invpro(jvar))= &
  583. & prof%var(jvar)%idqcf(:,jj)
  584. newprof%var(jvar)%nvqcf(:,invpro(jvar))= &
  585. & prof%var(jvar)%nvqcf(:,jj)
  586. newprof%var(jvar)%vdep(invpro(jvar)) = &
  587. & prof%var(jvar)%vdep(jj)
  588. newprof%var(jvar)%vobs(invpro(jvar)) = &
  589. & prof%var(jvar)%vobs(jj)
  590. newprof%var(jvar)%vmod(invpro(jvar)) = &
  591. & prof%var(jvar)%vmod(jj)
  592. DO jext = 1, prof%next
  593. newprof%var(jvar)%vext(invpro(jvar),jext) = &
  594. & prof%var(jvar)%vext(jj,jext)
  595. END DO
  596. ! nvind is the index of the original variable data
  597. newprof%var(jvar)%nvind(invpro(jvar)) = jj
  598. ENDIF
  599. END DO
  600. END DO
  601. ENDIF
  602. END DO
  603. ! Update MPP counters
  604. DO jvar = 1, prof%nvar
  605. newprof%nvprot(jvar) = invpro(jvar)
  606. END DO
  607. CALL obs_mpp_sum_integers ( newprof%nvprot, newprof%nvprotmpp,&
  608. & prof%nvar )
  609. ! Set book keeping variables which do not depend on number of obs.
  610. newprof%nvar = prof%nvar
  611. newprof%next = prof%next
  612. newprof%nstp = prof%nstp
  613. newprof%npi = prof%npi
  614. newprof%npj = prof%npj
  615. newprof%npk = prof%npk
  616. ! Deallocate temporary data
  617. DO jvar = 1, prof%nvar
  618. DEALLOCATE( llvvalid(jvar)%luse )
  619. END DO
  620. DEALLOCATE( llvalid%luse )
  621. END SUBROUTINE obs_prof_compress
  622. SUBROUTINE obs_prof_decompress( prof, oldprof, ldeallocate, kumout )
  623. !!----------------------------------------------------------------------
  624. !! *** ROUTINE obs_prof_decompress ***
  625. !!
  626. !! ** Purpose : - Copy back information to original profile type
  627. !!
  628. !! ** Method : - Reinsert updated information from a previous
  629. !! copied/compressed profile type into the original
  630. !! profile data and optionally deallocate the prof
  631. !! data input
  632. !!
  633. !! History :
  634. !! ! 07-01 (K. Mogensen) Original code
  635. !!----------------------------------------------------------------------
  636. !! * Arguments
  637. TYPE(obs_prof),INTENT(INOUT) :: prof ! Updated profile data
  638. TYPE(obs_prof),INTENT(INOUT) :: oldprof ! Original profile data
  639. LOGICAL :: ldeallocate ! Deallocate the updated data of insertion
  640. INTEGER,INTENT(in) :: kumout ! Output unit
  641. !!* Local variables
  642. INTEGER :: jvar
  643. INTEGER :: jext
  644. INTEGER :: ji
  645. INTEGER :: jj
  646. INTEGER :: jk
  647. INTEGER :: jl
  648. DO ji = 1, prof%nprof
  649. ! Copy header information
  650. jk = prof%npind(ji)
  651. oldprof%mi(jk,:) = prof%mi(ji,:)
  652. oldprof%mj(jk,:) = prof%mj(ji,:)
  653. oldprof%npidx(jk) = prof%npidx(ji)
  654. oldprof%npfil(jk) = prof%npfil(ji)
  655. oldprof%nyea(jk) = prof%nyea(ji)
  656. oldprof%nmon(jk) = prof%nmon(ji)
  657. oldprof%nday(jk) = prof%nday(ji)
  658. oldprof%nhou(jk) = prof%nhou(ji)
  659. oldprof%nmin(jk) = prof%nmin(ji)
  660. oldprof%mstp(jk) = prof%mstp(ji)
  661. oldprof%nqc(jk) = prof%nqc(ji)
  662. oldprof%ipqc(jk) = prof%ipqc(ji)
  663. oldprof%itqc(jk) = prof%itqc(ji)
  664. oldprof%ivqc(jk,:)= prof%ivqc(ji,:)
  665. oldprof%ntyp(jk) = prof%ntyp(ji)
  666. oldprof%rlam(jk) = prof%rlam(ji)
  667. oldprof%rphi(jk) = prof%rphi(ji)
  668. oldprof%cwmo(jk) = prof%cwmo(ji)
  669. ! QC info
  670. oldprof%nqcf(:,jk) = prof%nqcf(:,ji)
  671. oldprof%ipqcf(:,jk) = prof%ipqcf(:,ji)
  672. oldprof%itqcf(:,jk) = prof%itqcf(:,ji)
  673. oldprof%ivqcf(:,jk,:) = prof%ivqcf(:,ji,:)
  674. ! Copy the variable information
  675. DO jvar = 1, prof%nvar
  676. DO jj = prof%npvsta(ji,jvar), prof%npvend(ji,jvar)
  677. jl = prof%var(jvar)%nvind(jj)
  678. oldprof%var(jvar)%mvk(jl) = prof%var(jvar)%mvk(jj)
  679. oldprof%var(jvar)%nvpidx(jl) = prof%var(jvar)%nvpidx(jj)
  680. oldprof%var(jvar)%nvlidx(jl) = prof%var(jvar)%nvlidx(jj)
  681. oldprof%var(jvar)%nvqc(jl) = prof%var(jvar)%nvqc(jj)
  682. oldprof%var(jvar)%idqc(jl) = prof%var(jvar)%idqc(jj)
  683. oldprof%var(jvar)%vdep(jl) = prof%var(jvar)%vdep(jj)
  684. oldprof%var(jvar)%vobs(jl) = prof%var(jvar)%vobs(jj)
  685. oldprof%var(jvar)%vmod(jl) = prof%var(jvar)%vmod(jj)
  686. oldprof%var(jvar)%idqcf(:,jl) = prof%var(jvar)%idqcf(:,jj)
  687. oldprof%var(jvar)%nvqcf(:,jl) = prof%var(jvar)%nvqcf(:,jj)
  688. DO jext = 1, prof%next
  689. oldprof%var(jvar)%vext(jl,jext) = &
  690. & prof%var(jvar)%vext(jj,jext)
  691. END DO
  692. END DO
  693. END DO
  694. END DO
  695. ! Optionally deallocate the updated profile data
  696. IF ( ldeallocate ) CALL obs_prof_dealloc( prof )
  697. END SUBROUTINE obs_prof_decompress
  698. SUBROUTINE obs_prof_staend( prof, kvarno )
  699. !!----------------------------------------------------------------------
  700. !! *** ROUTINE obs_prof_decompress ***
  701. !!
  702. !! ** Purpose : - Set npvsta and npvend of a variable within
  703. !! an obs_prof_var type
  704. !!
  705. !! ** Method : - Find the start and stop of a profile by searching
  706. !! through the data
  707. !!
  708. !! History :
  709. !! ! 07-04 (K. Mogensen) Original code
  710. !!----------------------------------------------------------------------
  711. !! * Arguments
  712. TYPE(obs_prof),INTENT(INOUT) :: prof ! Profile data
  713. INTEGER,INTENT(IN) :: kvarno ! Variable number
  714. !!* Local variables
  715. INTEGER :: ji
  716. INTEGER :: iprofno
  717. !-----------------------------------------------------------------------
  718. ! Compute start and end bookkeeping arrays
  719. !-----------------------------------------------------------------------
  720. prof%npvsta(:,kvarno) = prof%nvprot(kvarno) + 1
  721. prof%npvend(:,kvarno) = -1
  722. DO ji = 1, prof%nvprot(kvarno)
  723. iprofno = prof%var(kvarno)%nvpidx(ji)
  724. prof%npvsta(iprofno,kvarno) = &
  725. & MIN( ji, prof%npvsta(iprofno,kvarno) )
  726. prof%npvend(iprofno,kvarno) = &
  727. & MAX( ji, prof%npvend(iprofno,kvarno) )
  728. END DO
  729. DO ji = 1, prof%nprof
  730. IF ( prof%npvsta(ji,kvarno) == ( prof%nvprot(kvarno) + 1 ) ) &
  731. & prof%npvsta(ji,kvarno) = 0
  732. END DO
  733. END SUBROUTINE obs_prof_staend
  734. END MODULE obs_profiles_def