tmm_mf_ecmwf_tm5.F90 69 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035
  1. !###############################################################################
  2. !
  3. ! Input/output of meteofiles : grib version.
  4. !
  5. !###############################################################################
  6. !
  7. #define TRACEBACK write (gol,'("in ",a," (",a,", line",i5,")")') rname, __FILE__, __LINE__; call goErr
  8. #define IF_NOTOK_RETURN(action) if (status/=0) then; TRACEBACK; action; return; end if
  9. #define IF_ERROR_RETURN(action) if (status> 0) then; TRACEBACK; action; return; end if
  10. !
  11. #include "tmm.inc"
  12. !
  13. !###############################################################################
  14. module tmm_mf_ecmwf_tm5
  15. use GO , only : gol, goErr, goPr
  16. use GO , only : TDate
  17. use dims , only : okdebug
  18. implicit none
  19. private
  20. public :: TMeteoFile_ecmwf_tm5
  21. public :: Init, Done
  22. public :: Get
  23. public :: ReadRecord
  24. ! --- const ------------------------------
  25. character(len=*), parameter :: mname = 'tmm_mf_ecmwf_tm5'
  26. !--- type ---------------------------------
  27. type TMeteoFile_ecmwf_tm5
  28. ! file name:
  29. character(len=256) :: dir
  30. character(len=256) :: fname
  31. ! time range covered by file:
  32. type(TDate) :: trange(2)
  33. ! other time keys for this file:
  34. character(len=16) :: treskey
  35. ! current time range covered by grib record:
  36. type(TDate) :: tref, t1, t2
  37. !
  38. ! file description
  39. !
  40. character(len=16) :: ec_class, ec_type, ec_levs
  41. integer :: ec_sh, ec_gg
  42. character(len=16) :: ec_ll
  43. character(len=256) :: paramkeys
  44. !
  45. end type TMeteoFile_ecmwf_tm5
  46. ! --- interfaces -------------------------
  47. interface Init
  48. module procedure mf_Init
  49. end interface
  50. interface Done
  51. module procedure mf_Done
  52. end interface
  53. interface Get
  54. module procedure mf_Get
  55. end interface
  56. interface ReadRecord
  57. module procedure mf_ReadRecord
  58. end interface
  59. contains
  60. ! ==============================================================
  61. subroutine mf_Init( mf, dir, archivekeys, paramkey, &
  62. tday, t1, t2, status )
  63. use GO, only : TDate
  64. use GO, only : goVarValue
  65. ! --- in/out ----------------------------
  66. type(TMeteoFile_ecmwf_tm5), intent(out) :: mf
  67. character(len=*), intent(in) :: dir
  68. character(len=*), intent(in) :: archivekeys
  69. character(len=*), intent(in) :: paramkey
  70. type(TDate), intent(in) :: tday, t1, t2
  71. integer, intent(out) :: status
  72. ! --- const --------------------------------------
  73. character(len=*), parameter :: rname = mname//'/mf_Init'
  74. ! --- begin --------------------------------
  75. ! store
  76. mf%dir = dir
  77. !
  78. ! extract fields from archivekey :
  79. ! form=tmpp;class=od;type=fg;levs=ml60;sh=159;gg=80;tres=_fg006up4tr3
  80. !
  81. mf%ec_class = 'od'
  82. call goVarValue( archivekeys, ';', 'class', '=', mf%ec_class, status )
  83. IF_ERROR_RETURN(status=1)
  84. !
  85. mf%ec_type = 'fc'
  86. call goVarValue( archivekeys, ';', 'type', '=', mf%ec_type, status )
  87. IF_ERROR_RETURN(status=1)
  88. !
  89. mf%ec_levs = 'ml60'
  90. call goVarValue( archivekeys, ';', 'levs', '=', mf%ec_levs, status )
  91. IF_ERROR_RETURN(status=1)
  92. !
  93. mf%ec_sh = 159
  94. call goVarValue( archivekeys, ';', 'sh', '=', mf%ec_sh, status )
  95. IF_ERROR_RETURN(status=1)
  96. !
  97. mf%ec_gg = 80
  98. call goVarValue( archivekeys, ';', 'gg', '=', mf%ec_gg, status )
  99. IF_ERROR_RETURN(status=1)
  100. !
  101. mf%ec_ll = 'R0.5'
  102. call goVarValue( archivekeys, ';', 'll', '=', mf%ec_ll, status )
  103. IF_ERROR_RETURN(status=1)
  104. !
  105. mf%treskey = '_fc012up2tr3'
  106. call goVarValue( archivekeys, ';', 'tres', '=', mf%treskey, status )
  107. IF_ERROR_RETURN(status=1)
  108. ! specials
  109. select case ( paramkey )
  110. case ( 'oro', 'lsm' )
  111. ! overwrite timeresolutionkey, used later on to set trange
  112. mf%treskey = 'const'
  113. ! tmm_convec tries to read oro using the default sourcekey,
  114. ! which probably contains type=fc ; force to use an for oro ...
  115. mf%ec_type = 'an'
  116. end select
  117. ! single parameter in a file:
  118. mf%paramkeys = '-'//trim(paramkey)//'-'
  119. ! extract time range:
  120. call GetGribTime( mf%treskey, tday, t1, t2, status, trange=mf%trange )
  121. IF_NOTOK_RETURN(status=1)
  122. ! dummy filename, might be used in error diagnose
  123. write (mf%fname,'("ecmwf mars grib file for param ",a)') trim(paramkey)
  124. ! ok
  125. status = 0
  126. end subroutine mf_Init
  127. ! ***
  128. subroutine mf_Done( mf, status )
  129. ! --- in/out ------------------------------------
  130. type(TMeteoFile_ecmwf_tm5), intent(inout) :: mf
  131. integer, intent(out) :: status
  132. ! --- const --------------------------------------
  133. character(len=*), parameter :: rname = mname//'/mf_Done'
  134. ! --- begin -------------------------------------
  135. ! nothing to be done ...
  136. ! ok
  137. status = 0
  138. end subroutine mf_Done
  139. ! ***
  140. subroutine mf_Get( mf, status, trange1, trange2, paramkeys )
  141. use GO, only : TDate
  142. ! --- in/out ----------------------------
  143. type(TMeteoFile_ecmwf_tm5), intent(in) :: mf
  144. integer, intent(out) :: status
  145. type(TDate), intent(out), optional :: trange1, trange2
  146. character(len=*), intent(out), optional :: paramkeys
  147. ! --- const --------------------------------------
  148. character(len=*), parameter :: rname = mname//'/mf_Get'
  149. ! --- local --------------------------------
  150. ! --- begin --------------------------------
  151. ! time range:
  152. if ( present(trange1) ) trange1 = mf%trange(1)
  153. if ( present(trange2) ) trange2 = mf%trange(2)
  154. ! contents:
  155. if ( present(paramkeys) ) paramkeys = trim(mf%paramkeys)
  156. ! ok
  157. status = 0
  158. end subroutine mf_Get
  159. ! ***
  160. ! Wrapper around read routine (mf_ReadRecord_1) that discriminate between
  161. ! combined fields (surface stress, vegetation types) and others.
  162. !
  163. subroutine mf_ReadRecord( mf, paramkey, tday, t1, t2, nuv, nw, &
  164. gridtype, levi, &
  165. lli, ll, sp_ll, &
  166. ggi, gg, sp_gg, &
  167. shi, sh, lnsp_sh, &
  168. tmi, status )
  169. use parray , only : pa_Init, pa_Done
  170. use GO , only : TDate
  171. use Grid , only : TLevelInfo
  172. use Grid , only : TllGridInfo, TggGridInfo, TshGridInfo
  173. use tmm_info , only : TMeteoInfo
  174. ! --- in/out -------------------------------
  175. type(TMeteoFile_ecmwf_tm5), intent(inout) :: mf
  176. character(len=*), intent(in) :: paramkey
  177. type(TDate), intent(in) :: tday, t1, t2
  178. character(len=1), intent(in) :: nuv
  179. character(len=1), intent(in) :: nw
  180. character(len=2), intent(out) :: gridtype
  181. type(TLevelInfo), intent(out) :: levi
  182. type(TllGridInfo), intent(inout) :: lli
  183. real, pointer :: ll(:,:,:)
  184. real, pointer :: sp_ll(:,:)
  185. type(TggGridInfo), intent(inout) :: ggi
  186. real, pointer :: gg(:,:)
  187. real, pointer :: sp_gg(:)
  188. type(TshGridInfo), intent(inout) :: shi
  189. complex, pointer :: sh(:,:)
  190. complex, pointer :: lnsp_sh(:)
  191. type(TMeteoInfo), intent(out) :: tmi
  192. integer, intent(out) :: status
  193. ! --- local --------------------------------------
  194. character(len=*), parameter :: rname = mname//'/mf_ReadRecord'
  195. real, pointer :: ll2(:,:,:)
  196. real, pointer :: gg2(:,:)
  197. complex, pointer :: sh2(:,:)
  198. integer :: iveg
  199. logical :: unit_change
  200. real :: unit_fac
  201. ! --- begin ---------------------------------
  202. ! combined field ?
  203. select case ( paramkey )
  204. ! *** surface stress
  205. case ( 'sstr' )
  206. ! read first field:
  207. call mf_ReadRecord_1( mf, 'ewss', tday, t1, t2, nuv, nw, &
  208. gridtype, levi, &
  209. lli, ll, sp_ll, &
  210. ggi, gg, sp_gg, &
  211. shi, sh, lnsp_sh, &
  212. tmi, status )
  213. IF_NOTOK_RETURN(status=1)
  214. ! init pointer:
  215. call pa_Init( ll2 )
  216. call pa_Init( gg2 )
  217. call pa_Init( sh2 )
  218. ! read second field:
  219. call mf_ReadRecord_1( mf, 'nsss', tday, t1, t2, nuv, nw, &
  220. gridtype, levi, &
  221. lli, ll2, sp_ll, &
  222. ggi, gg2, sp_gg, &
  223. shi, sh2, lnsp_sh, &
  224. tmi, status )
  225. IF_NOTOK_RETURN(status=1)
  226. ! process:
  227. select case ( gridtype )
  228. case ( 'll' ) ; ll = sqrt( ll**2 + ll2**2 )
  229. case ( 'gg' ) ; gg = sqrt( gg**2 + gg2**2 )
  230. case ( 'sh' ) ; sh = sqrt( sh**2 + sh2**2 )
  231. case default
  232. write (gol,'("unsupported gridtype for surface stress :",a)') gridtype; call goErr
  233. TRACEBACK; status=1; return
  234. end select
  235. ! clear pointers:
  236. call pa_Done( ll2 )
  237. call pa_Done( gg2 )
  238. call pa_Done( sh2 )
  239. ! *** vegetation types
  240. case ( 'tv01', 'tv02', 'tv03', 'tv04', 'tv05', 'tv06', 'tv07', 'tv08', 'tv09', 'tv10', &
  241. 'tv11', 'tv12', 'tv13', 'tv14', 'tv15', 'tv16', 'tv17', 'tv18', 'tv19', 'tv20' )
  242. ! extract number from name
  243. read (paramkey(3:4),'(i2)') iveg
  244. ! low vegetation types:
  245. call mf_ReadRecord_1( mf, 'tvl', tday, t1, t2, nuv, nw, &
  246. gridtype, levi, &
  247. lli, ll, sp_ll, &
  248. ggi, gg, sp_gg, &
  249. shi, sh, lnsp_sh, &
  250. tmi, status )
  251. IF_NOTOK_RETURN(status=1)
  252. ! set elements that match requested vegetation type to 100%, zero elsewhere
  253. select case ( gridtype )
  254. case ( 'gg' )
  255. where ( nint(gg(:,1)) == iveg )
  256. gg(:,1) = 100.0 ! %
  257. elsewhere
  258. gg(:,1) = 0.0
  259. end where
  260. case default
  261. write (gol,'("unsupported gridtype for vegetation fractions :",a)') gridtype; call goErr
  262. TRACEBACK; status=1; return
  263. end select
  264. ! init pointer:
  265. call pa_Init( ll2 )
  266. call pa_Init( gg2 )
  267. call pa_Init( sh2 )
  268. ! high vegetation types:
  269. call mf_ReadRecord_1( mf, 'tvh', tday, t1, t2, nuv, nw, &
  270. gridtype, levi, &
  271. lli, ll2, sp_ll, &
  272. ggi, gg2, sp_gg, &
  273. shi, sh2, lnsp_sh, &
  274. tmi, status )
  275. IF_NOTOK_RETURN(status=1)
  276. ! set elements that match requested vegetation type to 100%:
  277. select case ( gridtype )
  278. case ( 'gg' )
  279. where ( nint(gg2(:,1)) == iveg )
  280. gg(:,1) = 100.0 ! %
  281. end where
  282. case default
  283. write (gol,'("unsupported gridtype for vegetation fractions :",a)') gridtype; call goErr
  284. TRACEBACK; status=1; return
  285. end select
  286. ! clear pointers:
  287. call pa_Done( ll2 )
  288. call pa_Done( gg2 )
  289. call pa_Done( sh2 )
  290. ! *** default
  291. case default
  292. call mf_ReadRecord_1( mf, paramkey, tday, t1, t2, nuv, nw, &
  293. gridtype, levi, &
  294. lli, ll, sp_ll, &
  295. ggi, gg, sp_gg, &
  296. shi, sh, lnsp_sh, &
  297. tmi, status )
  298. IF_NOTOK_RETURN(status=1)
  299. end select
  300. ! unit change ?
  301. unit_change = .true.
  302. select case ( paramkey )
  303. case ( 'lsm' ) ; unit_fac = 100.0 ! 0-1 -> 0-100%
  304. case default ; unit_change = .false.
  305. end select
  306. ! apply ?
  307. if ( unit_change ) then
  308. select case ( gridtype )
  309. case ( 'll' ) ; ll = ll * unit_fac
  310. case ( 'gg' ) ; gg = gg * unit_fac
  311. !case ( 'sh' ) ; sh = sh * unit_fac
  312. case default
  313. write (gol,'("unsupported gridtype for unit change :",a)') gridtype; call goErr
  314. TRACEBACK; status=1; return
  315. end select
  316. end if
  317. ! ok
  318. status = 0
  319. end subroutine mf_ReadRecord
  320. ! ***
  321. ! Wrapper around read routine (mf_ReadRecord_2), to call it with correct time arguments.
  322. !
  323. subroutine mf_ReadRecord_1( mf, paramkey, tday, t1, t2, nuv, nw, &
  324. gridtype, levi, &
  325. lli, ll, sp_ll, &
  326. ggi, gg, sp_gg, &
  327. shi, sh, lnsp_sh, &
  328. tmi, status )
  329. use parray , only : pa_Init, pa_Done
  330. use GO , only : TDate, TIncrDate, operator(<), operator(-), rTotal, wrtgol
  331. use Grid , only : TLevelInfo
  332. use Grid , only : TllGridInfo, TggGridInfo, TshGridInfo
  333. use tmm_info , only : TMeteoInfo
  334. ! --- in/out -------------------------------
  335. type(TMeteoFile_ecmwf_tm5), intent(inout) :: mf
  336. character(len=*), intent(in) :: paramkey
  337. type(TDate), intent(in) :: tday, t1, t2
  338. character(len=1), intent(in) :: nuv
  339. character(len=1), intent(in) :: nw
  340. character(len=2), intent(out) :: gridtype
  341. type(TLevelInfo), intent(out) :: levi
  342. type(TllGridInfo), intent(inout) :: lli
  343. real, pointer :: ll(:,:,:)
  344. real, pointer :: sp_ll(:,:)
  345. type(TggGridInfo), intent(inout) :: ggi
  346. real, pointer :: gg(:,:)
  347. real, pointer :: sp_gg(:)
  348. type(TshGridInfo), intent(inout) :: shi
  349. complex, pointer :: sh(:,:)
  350. complex, pointer :: lnsp_sh(:)
  351. type(TMeteoInfo), intent(out) :: tmi
  352. integer, intent(out) :: status
  353. ! --- const --------------------------------------
  354. character(len=*), parameter :: rname = mname//'/mf_ReadRecord_1'
  355. ! --- local -------------------------------
  356. type(TDate) :: tref
  357. type(TIncrDate) :: tshift
  358. type(TDate) :: trefs, t1s, t2s
  359. real, pointer :: ll1(:,:,:), sp_ll1(:,:)
  360. real, pointer :: gg1(:,:) , sp_gg1(:)
  361. complex, pointer :: sh1(:,:) , lnsp_sh1(:)
  362. real :: dt_sec
  363. ! --- begin ---------------------------------
  364. ! accumulated field ?
  365. select case ( paramkey )
  366. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  367. ! accumulated fields
  368. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  369. case ( 'lsp', 'cp', 'sf', 'sshf', 'slhf', &
  370. 'ssr', 'ssrd', 'str', 'strd', &
  371. 'ewss', 'nsss', &
  372. 'UDMF', 'UDDR', 'DDMF', 'DDDR', 'K' )
  373. ! get reference time for requested time interval:
  374. call GetGribTime( mf%treskey, tday, t1, t2, status, tref=tref )
  375. IF_NOTOK_RETURN(status=1)
  376. ! should be a time interval ...
  377. if ( .not. (t1 < t2) ) then
  378. write (gol,'("accumulated fields requires time interval:")'); call goErr
  379. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  380. call wrtgol( ' t1 : ', t1 ); call goErr
  381. call wrtgol( ' t2 : ', t2 ); call goErr
  382. TRACEBACK; status=1; return
  383. end if
  384. ! read field accumulated over [tref,t2] :
  385. call wrtgol( ' accum ', tref, ' - ', t2 ); call goPr
  386. call mf_ReadRecord_2( mf, paramkey, tref, t2, t2, nuv, nw, &
  387. gridtype, levi, &
  388. lli, ll, sp_ll, &
  389. ggi, gg, sp_gg, &
  390. shi, sh, lnsp_sh, &
  391. tmi, status )
  392. IF_NOTOK_RETURN(status=1)
  393. ! substract [tref,t1] if necessary:
  394. if ( tref < t1 ) then
  395. ! init pointer:
  396. call pa_Init( ll1 ); call pa_Init( sp_ll1 )
  397. call pa_Init( gg1 ); call pa_Init( sp_gg1 )
  398. call pa_Init( sh1 ); call pa_Init( lnsp_sh1 )
  399. ! read field accumulated over [tref,t1] :
  400. call wrtgol( ' accum ', tref, ' - ', t1 ); call goPr
  401. call mf_ReadRecord_2( mf, paramkey, tref, t1, t1, nuv, nw, &
  402. gridtype, levi, &
  403. lli, ll1, sp_ll1, &
  404. ggi, gg1, sp_gg1, &
  405. shi, sh1, lnsp_sh1, &
  406. tmi, status )
  407. IF_NOTOK_RETURN(status=1)
  408. ! substract, fill surface pressure with average:
  409. select case ( gridtype )
  410. case ( 'll' )
  411. ll = ll - ll1
  412. if (associated(sp_ll1)) sp_ll = 0.5 * ( sp_ll + sp_ll1 )
  413. case ( 'gg' )
  414. gg = gg - gg1
  415. if (associated(sp_gg1)) sp_gg = 0.5 * ( sp_gg + sp_gg1 )
  416. case ( 'sh' )
  417. sh = sh - sh1
  418. if (associated(lnsp_sh1)) lnsp_sh = 0.5 * ( lnsp_sh + lnsp_sh1 )
  419. case default
  420. write (gol,'("unsupported gridtype for substract :",a)') gridtype; call goErr
  421. TRACEBACK; status=1; return
  422. end select
  423. ! clear pointers:
  424. call pa_Done( ll1 ); call pa_Done( sp_ll1 )
  425. call pa_Done( gg1 ); call pa_Done( sp_gg1 )
  426. call pa_Done( sh1 ); call pa_Done( lnsp_sh1 )
  427. end if
  428. ! return time averages only:
  429. dt_sec = rTotal( t2 - t1, 'sec' )
  430. select case ( gridtype )
  431. case ( 'll' ) ; ll = ll / dt_sec
  432. case ( 'gg' ) ; gg = gg / dt_sec
  433. case ( 'sh' ) ; sh = sh / dt_sec
  434. case default
  435. write (gol,'("unsupported gridtype for time average :",a)') gridtype; call goErr
  436. TRACEBACK; status=1; return
  437. end select
  438. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  439. ! emission fields
  440. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  441. case ( 'ch4fire' )
  442. ! get reference time for requested time interval:
  443. call GetGribTime( mf%treskey, tday, t1, t2, status, tref=tref )
  444. IF_NOTOK_RETURN(status=1)
  445. ! times in gribfile: 00:30+[0,0], ...
  446. trefs = tref
  447. t1s = tref
  448. t2s = tref
  449. ! just read ..
  450. call mf_ReadRecord_2( mf, paramkey, trefs, t1s, t2s, nuv, nw, &
  451. gridtype, levi, &
  452. lli, ll, sp_ll, &
  453. ggi, gg, sp_gg, &
  454. shi, sh, lnsp_sh, &
  455. tmi, status )
  456. IF_NOTOK_RETURN(status=1)
  457. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  458. ! instantaneous fields
  459. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  460. case default
  461. ! get reference time for requested time interval;
  462. ! eventually shift for analysed fields in case of forecasts:
  463. call GetGribTime( mf%treskey, tday, t1, t2, status, tref=tref, tshift=tshift )
  464. IF_NOTOK_RETURN(status=1)
  465. ! shift times (might be zero):
  466. trefs = tref - tshift
  467. t1s = t1 - tshift
  468. t2s = t2 - tshift
  469. ! just read ..
  470. call mf_ReadRecord_2( mf, paramkey, trefs, t1s, t2s, nuv, nw, &
  471. gridtype, levi, &
  472. lli, ll, sp_ll, &
  473. ggi, gg, sp_gg, &
  474. shi, sh, lnsp_sh, &
  475. tmi, status )
  476. IF_NOTOK_RETURN(status=1)
  477. end select
  478. status = 0
  479. end subroutine mf_ReadRecord_1
  480. ! ***
  481. ! Loop through grib messages, find one matching the requested input and decode it.
  482. !
  483. subroutine mf_ReadRecord_2( mf, paramkey, tref, t1, t2, nuv, nw, &
  484. gridtype, levi, &
  485. lli, ll, sp_ll, &
  486. ggi, gg, sp_gg, &
  487. shi, sh, lnsp_sh, &
  488. tmi, status )
  489. use GO , only : TDate, wrtgol, Get, NewDate, operator(>=)
  490. use GO , only : goWriteKeyNum
  491. use Grid , only : Init, Done
  492. use Grid , only : TLevelInfo
  493. use Grid , only : TllGridInfo, TggGridInfo, TshGridInfo
  494. use Grid , only : Interpol
  495. use file_grib , only : TGribFile
  496. use file_grib , only : Init, Done, ReadRecord, Get, Check
  497. use file_grib , only : levtype_sfc, levtype_hyb, levtype_land
  498. use file_grib , only : gridtype_ll, gridtype_gg, gridtype_red_gg, gridtype_sh
  499. use grib_table, only : GetPid
  500. use PArray , only : pa_Init, pa_Done, pa_SetShape
  501. use tmm_info , only : TMeteoInfo, Init, AddHistory
  502. ! --- in/out -------------------------------
  503. type(TMeteoFile_ecmwf_tm5), intent(inout) :: mf
  504. character(len=*), intent(in) :: paramkey
  505. type(TDate), intent(in) :: tref, t1, t2
  506. character(len=1), intent(in) :: nuv
  507. character(len=1), intent(in) :: nw
  508. character(len=2), intent(out) :: gridtype
  509. type(TLevelInfo), intent(out) :: levi
  510. type(TllGridInfo), intent(inout) :: lli
  511. real, pointer :: ll(:,:,:)
  512. real, pointer :: sp_ll(:,:)
  513. type(TggGridInfo), intent(inout) :: ggi
  514. real, pointer :: gg(:,:)
  515. real, pointer :: sp_gg(:)
  516. type(TshGridInfo), intent(inout) :: shi
  517. complex, pointer :: sh(:,:)
  518. complex, pointer :: lnsp_sh(:)
  519. type(TMeteoInfo), intent(out) :: tmi
  520. integer, intent(out) :: status
  521. ! --- const --------------------------------------
  522. character(len=*), parameter :: rname = mname//'/mf_ReadRecord_2'
  523. ! --- local -------------------------------
  524. character(len=16) :: ec_class, ec_type
  525. character(len=16) :: ec_grid, gridN, gridT
  526. character(len=16) :: levs
  527. character(len=16) :: treskey
  528. logical :: constant
  529. type(TGribFile) :: grib
  530. logical :: do_spm
  531. character(len=256) :: spm_fname
  532. type(TGribFile) :: spm_grib
  533. logical :: spm_lnsp
  534. logical :: spm_lnsp2sp
  535. integer :: pid, tabid
  536. character(len=7) :: gribcode
  537. character(len=3) :: gribcode2
  538. character(len=4) :: timekey
  539. character(len=16) :: spm_levs, spm_paramkey, ec_paramkey
  540. type(TDate) :: tfile
  541. integer :: ccyy, mm, dd, hh, min
  542. type(TDate) :: t37r3 ! time when cycle 37r3 became operational
  543. logical :: exist
  544. logical :: isfirst
  545. logical :: reopened
  546. integer :: nlev, glevtype, glevel
  547. integer :: level
  548. integer :: nlev_out, level_out
  549. integer :: ggridtype
  550. real :: lon_first, lon_inc
  551. integer :: lon_n
  552. real :: lat_first, lat_inc
  553. logical :: ll_ew_to_we
  554. integer :: lat_n
  555. integer :: ggN
  556. integer :: shT
  557. integer :: greftime(5), gtimerange(4)
  558. character(len=64) :: key
  559. integer :: ilon, ilat, nrec
  560. real, pointer :: pat(:,:)
  561. type(TshGridInfo) :: tmp_shi
  562. complex, pointer :: tmp_sh(:)
  563. ! --- begin ---------------------------------
  564. ! write (gol,'("mf_ReadRecord_2: paramkey : ",a)') trim(paramkey); call goPr
  565. ! call wrtgol( 'mf_ReadRecord_2: tref : ', tref ); call goPr
  566. ! call wrtgol( 'mf_ReadRecord_2: t1 : ', t1 ); call goPr
  567. ! call wrtgol( 'mf_ReadRecord_2: t2 : ', t2 ); call goPr
  568. ! no fluxes through boundaries ...
  569. if ( nuv /= 'n' ) then
  570. write (gol,'("unsupported nuv key : ",a)') nuv; call goErr
  571. TRACEBACK; status=1; return
  572. end if
  573. ! limitted support of fluxes ..
  574. !if ( nw /= 'n' ) then
  575. ! write (gol,'("unsupported nw key : ",a)') nw; call goErr
  576. ! TRACEBACK; status=1; return
  577. !end if
  578. ! init pointer arrays:
  579. call pa_Init( pat )
  580. !
  581. ! ~~~ 3d field or 2d stored in 3d array
  582. !
  583. ! grid : T159, N80, etc
  584. call goWriteKeyNum( gridT, 'T', mf%ec_sh )
  585. call goWriteKeyNum( gridN, 'N', mf%ec_gg )
  586. ! defaults
  587. ec_paramkey = paramkey
  588. ec_class = mf%ec_class
  589. ec_type = mf%ec_type
  590. levs = mf%ec_levs
  591. ec_grid = gridN
  592. treskey = mf%treskey
  593. constant = .false.
  594. do_spm = .false.
  595. spm_lnsp = .false.
  596. spm_lnsp2sp = .false.
  597. ! specials
  598. select case ( paramkey )
  599. case ( 'LNSP' )
  600. ec_grid = gridT
  601. case ( 'VO', 'D' )
  602. ec_grid = gridT
  603. do_spm = .true.
  604. spm_lnsp = .true.
  605. case ( 'T', 'W', 'Q', 'CLWC', 'CIWC', 'CC', 'UDMF', 'UDDR', 'DDMF', 'DDDR', 'K' )
  606. do_spm = .true.
  607. spm_lnsp2sp = (ec_class == 'e4') .or. (ec_class == 'ei') .or. (ec_class == 'ee')
  608. case ( 'oro', 'lsm' )
  609. levs = 'sfc'
  610. constant = .true.
  611. treskey = 'const'
  612. ! tmm_convec tries to read oro using the default sourcekey,
  613. ! which probably contains type=fc ; force to use an for oro ...
  614. ec_type = 'an'
  615. ! case ( 'cvl', 'cvh', 'tvl', 'tvh', 'sr', 'albedo', 'lsrh' )
  616. ! ec_type = 'an'
  617. ! levs = 'sfc'
  618. case ( 'ci', 'sst', 'swvl1', 'swvl2', 'swvl3', 'swvl4', '10fg', '10fg3', 'sd', 'lsp', &
  619. 'cp', 'sf', 'sshf', 'slhf', 'blh', 'u10m', 'v10m', 't2m', 'd2m', &
  620. 'ssr', 'ewss', 'nsss', 'sstr' ,'src', 'skt' )
  621. levs = 'sfc'
  622. case ( 'sp' )
  623. spm_lnsp2sp = (ec_class == 'e4') .or. (ec_class == 'ei') .or. (ec_class == 'ee')
  624. if ( spm_lnsp2sp ) then
  625. ec_paramkey = 'LNSP'
  626. else
  627. levs = 'sfc'
  628. end if
  629. case ( 'g10m' )
  630. ! g10m is retrieved as 10fg, or 10fg3 after cycle 37r3 (november 15th
  631. ! , 2011) for od data.
  632. ! 10fg has the same grib code as g10m, but 10fg3 has different code
  633. ! and table:
  634. t37r3 = NewDate( 2011, 11, 15, 12, 00, 00 )
  635. if (( ec_class == 'od').and.( tref >= t37r3)) then
  636. ec_paramkey = '10fg3'
  637. end if
  638. case ( 'ch4fire' )
  639. ec_grid = trim(mf%ec_ll)
  640. end select
  641. ! write gribcode
  642. call GetPid( 'ec', ec_paramkey, pid, tabid, status )
  643. IF_NOTOK_RETURN(status=1)
  644. write (gribcode,'(i3,".",i3.3)') pid, tabid
  645. write (gribcode2,'(i3)') pid
  646. gribcode = adjustl(gribcode)
  647. gribcode2 = adjustl(gribcode2)
  648. ! convert input times to file name times:
  649. call GetGribTime( treskey, tref, t1, t2, status, tfile=tfile )
  650. IF_NOTOK_RETURN(status=1)
  651. ! call wrtgol( 'mf_ReadRecord_2: tfile : ', tfile ); call goPr
  652. ! extract time values:
  653. call Get( tfile, year=ccyy, month=mm, day=dd, hour=hh, min=min )
  654. ! Timestamp in file name: 0000, 0600, 1200, 1800.. or 0030, 0130
  655. write (timekey,'(i4.4)') hh*100+min
  656. timekey = adjustl(timekey)
  657. ! create file name:
  658. ! dir/od-fc-20000101-1200-ml60-138-T159.gb
  659. !
  660. ! filename includes date:
  661. write (mf%fname,'(a,"/",a,"-",a,"-",i4.4,2i2.2,"-",a,"-",a,"-",a,"-",a,".gb")') &
  662. trim(mf%dir), &
  663. trim(ec_class), trim(ec_type), ccyy, mm, dd, trim(timekey), &
  664. trim(levs), trim(gribcode), trim(ec_grid)
  665. ! exist ?
  666. inquire( file=mf%fname, exist=exist )
  667. if ( .not. exist ) then
  668. ! Here we look for filename without table id. This seems to be ok: the
  669. ! table id is only missing in the OD-FC-ML grib files retrieved from MARS.
  670. write (gol,'("grib file does not exist:")'); call goPr
  671. write (gol,'(" ",a)') trim(mf%fname); call goPr
  672. write (gol,'("...will try another name:")'); call goPr
  673. write (mf%fname,'(a,"/",a,"-",a,"-",i4.4,2i2.2,"-",a,"-",a,"-",a,"-",a,".gb")') &
  674. trim(mf%dir), &
  675. trim(ec_class), trim(ec_type), ccyy, mm, dd, trim(timekey), &
  676. trim(levs), trim(gribcode2), trim(ec_grid)
  677. write (gol,'(" ",a)') trim(mf%fname); call goPr
  678. inquire( file=mf%fname, exist=exist )
  679. if (.not. exist) then
  680. write (gol,'("grib file w/o tableid does not exist either!")'); call goErr
  681. TRACEBACK; status=1; return
  682. endif
  683. end if
  684. ! open grib file
  685. call Init( grib, mf%fname, 'r', status )
  686. IF_NOTOK_RETURN(status=1)
  687. ! arrays and grids not defined yet
  688. isfirst = .true.
  689. reopened = .false.
  690. nrec = 0
  691. ! loop over grib messages
  692. level = 0
  693. do
  694. !
  695. ! read gribsection in file buffer
  696. !
  697. call ReadRecord( grib, status )
  698. select case ( status )
  699. case ( 0 )
  700. ! no error
  701. if (okdebug) then
  702. nrec=nrec+1
  703. write (gol,'("grib file - read message #:",a,x,i5)') trim(grib%fname),nrec; call goPr
  704. end if
  705. case ( 1 )
  706. ! eof
  707. if ( .not. reopened ) then
  708. write (gol,'("grib read record: re-open ...")'); call goPr
  709. ! close:
  710. call Done( grib, status )
  711. IF_NOTOK_RETURN(status=1)
  712. ! reopen:
  713. call Init( grib, mf%fname, 'r', status )
  714. IF_NOTOK_RETURN(status=1)
  715. nrec=0
  716. reopened = .true.
  717. cycle
  718. else
  719. write (gol,'("reached eof before requested record was found")'); call goErr
  720. write (gol,'(" file : ",a)') trim(mf%fname); call goErr
  721. write (gol,'(" paramkey : ",a)') trim(paramkey); call goErr
  722. call wrtgol( ' tref : ', tref ); call goErr
  723. call wrtgol( ' t1 : ', t1 ); call goErr
  724. call wrtgol( ' t2 : ', t2 ); call goErr
  725. write (gol,'("tips:")'); call goErr
  726. write (gol,'(" o grib file corrupted or zero ?")'); call goErr
  727. write (gol,'(" o if accumulatd field,")'); call goErr
  728. write (gol,'(" check list of accumulated fields in mf_ReadRecord_1")'); call goErr
  729. TRACEBACK; status=1; return
  730. end if
  731. case default
  732. write (gol,'("error from grib_ReadRecord")') ; call goErr
  733. TRACEBACK; status=1; return
  734. end select
  735. !
  736. ! checks ...
  737. !
  738. ! expected paramId for the requested field (from grib_table.F90)
  739. select case ( paramkey )
  740. case ( 'spm' ) ; call GetPid( 'ec', 'SP' , pid, tabid, status )
  741. case default ; call GetPid( 'ec', ec_paramkey, pid, tabid, status )
  742. end select
  743. IF_NOTOK_RETURN(status=1)
  744. ! check paramId (two possibilities)
  745. call Check( grib, pid=pid, debug=0, status=status )
  746. if (status/=0) then
  747. if (okdebug) then
  748. write(gol,*)"wrong pid:",pid; call goPr
  749. endif
  750. pid=tabid*1000+pid ! new code to try
  751. call Check( grib, pid=pid, debug=0, status=status )
  752. if (status/=0) then
  753. if (okdebug) then
  754. write(gol,*)"wrong pid:",pid; call goPr
  755. endif
  756. cycle
  757. endif
  758. endif
  759. ! fill times ?
  760. if ( .not. constant ) then
  761. ! extract time fields from grib, store in mf%tref/mf%t1/mf%t2
  762. call SetTime( mf, grib, status )
  763. IF_NOTOK_RETURN(status=1)
  764. ! check time:
  765. call CheckTime( mf, tref, t1, t2, status )
  766. if (status/=0) then
  767. !write (gol,'("grib read record: wrong time; skip ...")'); call goPr
  768. !write (gol,'(" paramkey : ",a)') paramkey; call goPr
  769. !call wrtgol( ' req. tref : ', tref ); call goPr
  770. !call wrtgol( ' t1 : ', t1 ); call goPr
  771. !call wrtgol( ' t2 : ', t2 ); call goPr
  772. !call wrtgol( ' grib tref : ', mf%tref ); call goPr
  773. !call wrtgol( ' t1 : ', mf%t1 ); call goPr
  774. !call wrtgol( ' t2 : ', mf%t2 ); call goPr
  775. !write (gol,'(" grib file : ",a)') trim(mf%fname); call goPr
  776. cycle
  777. end if
  778. end if ! time checking
  779. ! extract level stuff:
  780. call Get( grib, nlev=nlev, levtype=glevtype, level=glevel, status=status )
  781. IF_NOTOK_RETURN(status=1)
  782. ! check level type:
  783. select case ( glevtype )
  784. case ( levtype_sfc, levtype_land )
  785. ! surface field
  786. nlev = 1
  787. glevel = 1
  788. case ( levtype_hyb )
  789. select case ( paramkey )
  790. case ( 'LNSP', 'sp' )
  791. nlev = 1
  792. case default
  793. ! level in 3d field
  794. end select
  795. case default
  796. write (gol,'("found unexpected level type: ")'); call goErr
  797. write (gol,'(" leveltype : ",i3)') glevtype; call goErr
  798. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  799. write (gol,'(" grib file : ",a)') trim(mf%fname); call goErr
  800. TRACEBACK; status=1; return
  801. end select
  802. ! check level:
  803. level = level + 1
  804. if ( glevel /= level ) then
  805. write (gol,'("found unexpected level: ")'); call goErr
  806. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  807. write (gol,'(" req. level : ",i6)') level; call goErr
  808. write (gol,'(" grib level : ",i6)') glevel; call goErr
  809. write (gol,'(" grib nlev : ",i6)') nlev; call goErr
  810. write (gol,'(" grib file : ",a)') trim(mf%fname); call goErr
  811. TRACEBACK; status=1; return
  812. end if
  813. ! number of output levels:
  814. nlev_out = nlev
  815. if ( nw == 'w' ) nlev_out = nlev_out + 1
  816. !
  817. ! define grids and arrays
  818. !
  819. if ( isfirst ) then
  820. !
  821. ! * info
  822. !
  823. ! example of history:
  824. ! model=ecmwf;class=od;type=fc;tref=2000,12,31,12,00; ...
  825. ! trange=001,234,240,001;sh=159;nlev=60
  826. !
  827. call Init( tmi, paramkey, 'unknown', status )
  828. call AddHistory( tmi, 'model==ecmwf', status )
  829. call AddHistory( tmi, 'class=='//trim(mf%ec_class), status )
  830. call AddHistory( tmi, 'type=='//trim(mf%ec_type) , status )
  831. !
  832. call Get( grib, status, reftime=greftime, timerange=gtimerange )
  833. IF_NOTOK_RETURN(status=1)
  834. write (key,'("tref==",i4.4,4(",",i2.2))') greftime
  835. call AddHistory( tmi, trim(key), status )
  836. write (key,'("trange==",i3.3,3(",",i3.3))') gtimerange
  837. call AddHistory( tmi, trim(key), status )
  838. !
  839. write (key,'("nlev==",i3.3)') nlev
  840. call AddHistory( tmi, trim(key), status )
  841. !
  842. ! * define horizontal grid:
  843. !
  844. ! extract grid type:
  845. call Get( grib, status, gridtype=ggridtype )
  846. IF_NOTOK_RETURN(status=1)
  847. ! setup:
  848. select case ( ggridtype )
  849. ! o lat/lon
  850. case ( gridtype_ll )
  851. ! routine returns lat/lon grid:
  852. gridtype = 'll'
  853. ! grib storage is north pole to south pole:
  854. call Get( grib, status, &
  855. lon_first=lon_first, lon_inc=lon_inc, lon_n=lon_n, &
  856. lat_last =lat_first, lat_inc=lat_inc, lat_n=lat_n )
  857. IF_NOTOK_RETURN(status=1)
  858. ! change from [0,360] (east-west) to [-180,180] (west-east) ?
  859. ! only if global coverage and first point less than half a grid cell from lon==0 :
  860. ll_ew_to_we = (abs(lon_n*lon_inc - 360.0) < 0.01) .and. &
  861. (abs(lon_first - 0.5*lon_inc) < 0.01 )
  862. ! apply ?
  863. if ( ll_ew_to_we ) then
  864. ! shift west bound:
  865. lon_first = lon_first - 180.0
  866. end if
  867. ! define grid structure:
  868. call Init( lli, lon_first, lon_inc, lon_n, &
  869. lat_first, lat_inc, lat_n, status )
  870. IF_NOTOK_RETURN(status=1)
  871. ! init array to store 2d field from grib file (north-south order):
  872. call pa_SetShape( pat, lon_n, lat_n )
  873. ! allocate output:
  874. call pa_SetShape( ll, lon_n, lat_n, nlev_out )
  875. ll = 0.0
  876. ! add to history:
  877. write (key,'("longrid==",f7.2,",",f6.2,",",i4)') lon_first, lon_inc, lon_n
  878. call AddHistory( tmi, trim(key), status )
  879. write (key,'("latgrid==",f7.2,",",f6.2,",",i4)') lat_first, lat_inc, lat_n
  880. call AddHistory( tmi, trim(key), status )
  881. ! o gaussian grid (NOTE: it is assumed that 'ecmwf_tm5' met field
  882. ! are **ALWAYS** on the reduced grid. --> to avoid potential
  883. ! problem we probably need to get rid of GRIBEX (where
  884. ! gridtype_gg implied reduced!). With grib_api we get the 'gridtype_red_gg'.
  885. case ( gridtype_gg, gridtype_red_gg )
  886. ! routine returns gg grid:
  887. gridtype = 'gg'
  888. ! extract grid number:
  889. call Get( grib, status, N=ggN )
  890. IF_NOTOK_RETURN(status=1)
  891. ! define grid structure:
  892. call Init( ggi, ggN, .true., status )
  893. IF_NOTOK_RETURN(status=1)
  894. ! allocate output:
  895. call pa_SetShape( gg, ggi%np, nlev_out )
  896. gg = 0.0
  897. ! add to history:
  898. write (key,'("gg==",i4.4)') ggN
  899. call AddHistory( tmi, trim(key), status )
  900. ! o spectral field:
  901. case ( gridtype_sh )
  902. ! routine returns sh grid:
  903. gridtype = 'sh'
  904. ! extract spectral truncation:
  905. call Get( grib, status, T=shT )
  906. IF_NOTOK_RETURN(status=1)
  907. ! intialize spherical harmonic field info:
  908. call Init( shi, shT, status )
  909. IF_NOTOK_RETURN(status=1)
  910. ! allocate output:
  911. call pa_SetShape( sh, shi%np, nlev_out )
  912. sh = cmplx(0.0,0.0)
  913. ! add to history:
  914. write (key,'("sh==",i4.4)') shT
  915. call AddHistory( tmi, trim(key), status )
  916. case default
  917. write (gol,'("unsupported gridtype for setup : ",i6)') ggridtype; call goErr
  918. TRACEBACK; status=1; return
  919. end select
  920. !
  921. ! * levels
  922. !
  923. select case ( nlev )
  924. case ( 1 )
  925. call Init( levi, nlev, (/0.0,0.0/), (/0.0,0.0/), status )
  926. IF_NOTOK_RETURN(status=1)
  927. case ( 60 )
  928. call Init( levi, 'ec60', status )
  929. IF_NOTOK_RETURN(status=1)
  930. case ( 62 )
  931. call Init( levi, 'ec62', status )
  932. IF_NOTOK_RETURN(status=1)
  933. case ( 91 )
  934. call Init( levi, 'ec91', status )
  935. IF_NOTOK_RETURN(status=1)
  936. case ( 137 )
  937. call Init( levi, 'ec137', status )
  938. IF_NOTOK_RETURN(status=1)
  939. case default
  940. write (gol,'("do not how to init levi for nlev = ",i6)') nlev; call goErr
  941. TRACEBACK; status=1; return
  942. end select
  943. ! not again ...
  944. isfirst = .false.
  945. end if ! isfirst (grid definition and allocation)
  946. !
  947. ! store
  948. !
  949. ! layers numbered 1..nlev, half levels numberd 1..nlev+1
  950. ! top-down, thus 1 is space and nlev+1 is surface
  951. if ( nw == 'w' ) then
  952. ! store half levels
  953. select case ( paramkey )
  954. ! store in upper half level of a layer:
  955. case ( 'UDMF', 'DDMF' )
  956. level_out = level
  957. !! store in lower half level of a layer:
  958. !case ( 'dummy' )
  959. ! level_out = level + 1
  960. ! to be implemented ...
  961. case default
  962. write (gol,'("do not if data is on upper or lower half level ...")'); call goErr
  963. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  964. TRACEBACK; status=1; return
  965. end select
  966. else
  967. ! store full levels
  968. level_out = level
  969. end if
  970. select case ( ggridtype )
  971. case ( gridtype_ll )
  972. ! read 2d pat from grib; storred from north to south
  973. call Get( grib, status, ll=pat )
  974. IF_NOTOK_RETURN(status=1)
  975. ! store from south to north:
  976. do ilat = 1, lat_n
  977. ! reshuffle ?
  978. if ( ll_ew_to_we ) then
  979. ! fill west part:
  980. do ilon = 1, lon_n/2
  981. ll(ilon,ilat,level_out) = pat(lon_n/2+ilon,lat_n+1-ilat)
  982. end do
  983. ! fill east part:
  984. do ilon = lon_n/2+1, lon_n
  985. ll(ilon,ilat,level_out) = pat(ilon-lon_n/2,lat_n+1-ilat)
  986. end do
  987. else
  988. ! copy longitudes:
  989. ll(:,ilat,level_out) = pat(:,lat_n+1-ilat)
  990. end if
  991. end do
  992. case ( gridtype_gg, gridtype_red_gg )
  993. ! read 2d pat from grib:
  994. call Get( grib, status, gg=gg(:,level_out) )
  995. IF_NOTOK_RETURN(status=1)
  996. ! convert from lnsp to sp ?
  997. if ( paramkey == 'sp' .and. spm_lnsp2sp ) gg(:,level_out) = exp(gg(:,level_out)) ! Pa
  998. case ( gridtype_sh )
  999. ! read 2d pat from grib:
  1000. call Get( grib, status, sh=sh(:,level_out) )
  1001. IF_NOTOK_RETURN(status=1)
  1002. case default
  1003. write (gol,'("unsupported gridtype for 2d pat : ",i6)') gridtype; call goErr
  1004. TRACEBACK; status=1; return
  1005. end select
  1006. ! last record for this field ?
  1007. if ( glevel == nlev ) exit
  1008. end do ! records
  1009. ! close grib file
  1010. call Done( grib, status )
  1011. IF_NOTOK_RETURN(status=1)
  1012. !
  1013. ! ~~~ surface pressure
  1014. !
  1015. SPM: if ( do_spm ) then
  1016. ! read lnsp and covert to sp ?
  1017. if ( spm_lnsp .or. spm_lnsp2sp) then
  1018. spm_levs = levs
  1019. spm_paramkey = 'LNSP'
  1020. else
  1021. spm_levs = 'sfc'
  1022. spm_paramkey = 'SP'
  1023. end if
  1024. ! write gribcode:
  1025. call GetPid( 'ec', spm_paramkey, pid, tabid, status )
  1026. IF_NOTOK_RETURN(status=1)
  1027. write (gribcode,'(i3,".128")') pid
  1028. write (gribcode2,'(i3)') pid
  1029. gribcode = adjustl(gribcode)
  1030. gribcode2 = adjustl(gribcode2)
  1031. ! create file name:
  1032. ! dir/od-fc-2000-01-ml60-T159-T_20000101_fg006up4tr3.gb
  1033. write (spm_fname,'(a,"/",a,"-",a,"-",i4.4,2i2.2,"-",a,"-",a,"-",a,"-",a,".gb")') &
  1034. trim(mf%dir), &
  1035. trim(ec_class), trim(ec_type), ccyy, mm, dd, trim(timekey), &
  1036. trim(spm_levs), trim(gribcode), trim(ec_grid)
  1037. ! exist ?
  1038. inquire( file=spm_fname, exist=exist )
  1039. if ( .not. exist ) then
  1040. write (gol,'("grib file does not exist:")'); call goPr
  1041. write (gol,'(" ",a)') trim(spm_fname); call goPr
  1042. write (gol,'("...will try another name")'); call goPr
  1043. write (spm_fname,'(a,"/",a,"-",a,"-",i4.4,2i2.2,"-",a,"-",a,"-",a,"-",a,".gb")') &
  1044. trim(mf%dir), &
  1045. trim(ec_class), trim(ec_type), ccyy, mm, dd, trim(timekey), &
  1046. trim(spm_levs), trim(gribcode2), trim(ec_grid)
  1047. inquire( file=spm_fname, exist=exist )
  1048. if (.not. exist) then
  1049. write (gol,'("grib file does not exist:")'); call goErr
  1050. write (gol,'(" ",a)') trim(spm_fname); call goErr
  1051. TRACEBACK; status=1; return
  1052. endif
  1053. end if
  1054. ! open grib file
  1055. call Init( spm_grib, spm_fname, 'r', status )
  1056. IF_NOTOK_RETURN(status=1)
  1057. ! loop over time records
  1058. do
  1059. ! read gribsection in file buffer
  1060. call ReadRecord( spm_grib, status )
  1061. IF_NOTOK_RETURN(status=1)
  1062. ! fill times
  1063. call SetTime( mf, spm_grib, status )
  1064. IF_NOTOK_RETURN(status=1)
  1065. ! check time:
  1066. call CheckTime( mf, tref, t1, t2, status )
  1067. if (status/=0) then
  1068. !write (gol,'("grib read record: spm wrong time; skip ...")'); call goPr
  1069. cycle
  1070. !write (gol,'("found unexpected times in grib file:")'); call goErr
  1071. !write (gol,'(" paramkey : ",a)') paramkey; call goErr
  1072. !call wrtgol( ' req. t1 : ', t1 ); call goErr
  1073. !call wrtgol( ' t2 : ', t2 ); call goErr
  1074. !call wrtgol( ' grib t1 : ', mf%t1 ); call goErr
  1075. !call wrtgol( ' t2 : ', mf%t2 ); call goErr
  1076. !write (gol,'(" grib file : ",a)') trim(spm_fname); call goErr
  1077. !TRACEBACK; status=1; return
  1078. end if
  1079. ! time ok
  1080. exit
  1081. end do ! time loop
  1082. ! set param id:
  1083. select case ( ggridtype )
  1084. case ( gridtype_ll )
  1085. call GetPid( 'ec', 'SP', pid, tabid, status )
  1086. IF_NOTOK_RETURN(status=1)
  1087. case ( gridtype_gg, gridtype_red_gg )
  1088. if ( spm_lnsp2sp ) then
  1089. call GetPid( 'ec', 'LNSP', pid, tabid, status )
  1090. IF_NOTOK_RETURN(status=1)
  1091. else
  1092. call GetPid( 'ec', 'SP', pid, tabid, status )
  1093. IF_NOTOK_RETURN(status=1)
  1094. end if
  1095. case ( gridtype_sh )
  1096. call GetPid( 'ec', 'LNSP', pid, tabid, status )
  1097. IF_NOTOK_RETURN(status=1)
  1098. case default
  1099. write (gol,'("unsupported gridtype for setup sp/lnsp : ",i6)') ggridtype; call goErr
  1100. TRACEBACK; status=1; return
  1101. end select
  1102. ! check parameter:
  1103. call Check( spm_grib, pid=pid, debug=1, status=status )
  1104. IF_NOTOK_RETURN(status=1)
  1105. ! check level:
  1106. call Get( spm_grib, levtype=glevtype, level=glevel, status=status )
  1107. IF_NOTOK_RETURN(status=1)
  1108. select case ( ggridtype )
  1109. case ( gridtype_ll )
  1110. if ( glevtype /= levtype_sfc ) then
  1111. write (gol,'("found unexpected level type ")'); call goErr
  1112. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  1113. write (gol,'(" sfc level type : ",i6)') levtype_sfc; call goErr
  1114. write (gol,'(" grib level type : ",i6)') glevtype; call goErr
  1115. write (gol,'(" grib file : ",a)') trim(spm_fname); call goErr
  1116. TRACEBACK; status=1; return
  1117. end if
  1118. case ( gridtype_gg, gridtype_red_gg )
  1119. if ( spm_lnsp2sp ) then
  1120. if ( (glevtype /= levtype_hyb) .or. (glevel /= 1) ) then
  1121. write (gol,'("found unexpected level type (lnsp for 3d gg)")'); call goErr
  1122. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  1123. write (gol,'(" hyb level type : ",i6)') levtype_hyb; call goErr
  1124. write (gol,'(" grib level type : ",i6)') glevtype; call goErr
  1125. write (gol,'(" grib level : ",i6)') glevel; call goErr
  1126. write (gol,'(" grib file : ",a)') trim(spm_fname); call goErr
  1127. TRACEBACK; status=1; return
  1128. end if
  1129. else
  1130. if ( glevtype /= levtype_sfc ) then
  1131. write (gol,'("found unexpected level type ")'); call goErr
  1132. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  1133. write (gol,'(" sfc level type : ",i6)') levtype_sfc; call goErr
  1134. write (gol,'(" grib level type : ",i6)') glevtype; call goErr
  1135. write (gol,'(" grib file : ",a)') trim(spm_fname); call goErr
  1136. TRACEBACK; status=1; return
  1137. end if
  1138. end if
  1139. case ( gridtype_sh )
  1140. if ( (glevtype /= levtype_hyb) .or. (glevel /= 1) ) then
  1141. write (gol,'("found unexpected level type ")'); call goErr
  1142. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  1143. write (gol,'(" hyb level type : ",i6)') levtype_hyb; call goErr
  1144. write (gol,'(" grib level type : ",i6)') glevtype; call goErr
  1145. write (gol,'(" grib level : ",i6)') glevel; call goErr
  1146. write (gol,'(" grib file : ",a)') trim(spm_fname); call goErr
  1147. TRACEBACK; status=1; return
  1148. end if
  1149. case default
  1150. write (gol,'("unsupported gridtype for sp/lnsp levs : ",i6)') ggridtype; call goErr
  1151. TRACEBACK; status=1; return
  1152. end select
  1153. ! read and store surface pressure field:
  1154. select case ( ggridtype )
  1155. case ( gridtype_ll )
  1156. ! allocate storage
  1157. call pa_SetShape( sp_ll, lon_n, lat_n )
  1158. ! read 2d pat from grib; storred from north to south
  1159. call Get( spm_grib, status, ll=pat )
  1160. IF_NOTOK_RETURN(status=1)
  1161. ! store from south to north:
  1162. do ilat = 1, lat_n
  1163. ! reshuffle ?
  1164. if ( ll_ew_to_we ) then
  1165. ! fill west part:
  1166. do ilon = 1, lon_n/2
  1167. sp_ll(ilon,ilat) = pat(lon_n/2+ilon,lat_n+1-ilat)
  1168. end do
  1169. ! fill east part:
  1170. do ilon = lon_n/2+1, lon_n
  1171. sp_ll(ilon,ilat) = pat(ilon-lon_n/2,lat_n+1-ilat)
  1172. end do
  1173. else
  1174. ! copy longitudes:
  1175. sp_ll(:,ilat) = pat(:,lat_n+1-ilat)
  1176. end if
  1177. end do
  1178. case ( gridtype_gg, gridtype_red_gg )
  1179. ! allocate storage
  1180. call pa_SetShape( sp_gg, ggi%np )
  1181. ! read gg field from grib:
  1182. call Get( spm_grib, status, gg=sp_gg )
  1183. IF_NOTOK_RETURN(status=1)
  1184. ! convert from lnsp to sp ?
  1185. if ( spm_lnsp2sp ) sp_gg = exp(sp_gg) ! Pa
  1186. case ( gridtype_sh )
  1187. ! allocate storage
  1188. call pa_SetShape( lnsp_sh, shi%np )
  1189. ! read spectral coeff:
  1190. call Get( spm_grib, status, sh=lnsp_sh )
  1191. IF_NOTOK_RETURN(status=1)
  1192. case default
  1193. write (gol,'("unsupported gridtype for reading sp/lnsp : ",i6)') ggridtype; call goErr
  1194. TRACEBACK; status=1; return
  1195. end select
  1196. ! close grib file
  1197. call Done( spm_grib, status )
  1198. IF_NOTOK_RETURN(status=1)
  1199. end if SPM
  1200. !
  1201. ! ~~~ done
  1202. !
  1203. call pa_Done( pat ) ! deallocate arrays
  1204. status = 0
  1205. end subroutine mf_ReadRecord_2
  1206. ! ****************************************************************************
  1207. !
  1208. ! In gribfile:
  1209. ! reftime : for example time at which forecast is made
  1210. ! timerange: increment or interval
  1211. !
  1212. ! arguments: ok if:
  1213. !
  1214. ! time1 == time2 time1==time2 == reftime+timerange
  1215. !
  1216. ! time1 == 0 time2 == reftime+timerange
  1217. !
  1218. ! time2 == 0 time1 == reftime
  1219. !
  1220. ! time1 < time2 time1 == refitme, time2 == reftime+timerange
  1221. !
  1222. !
  1223. ! grib [t1-----------t2]
  1224. ! status
  1225. ! o time1/2 record too old 1
  1226. ! o time1/2 ok 0
  1227. ! o time1/2 record too new 2
  1228. !
  1229. !
  1230. ! SetTime( mf, status )
  1231. !
  1232. ! Extracts time values from current grib record,
  1233. ! store in mf%t1, mf%t2
  1234. !
  1235. ! return status:
  1236. ! 0 : ok
  1237. ! other : some error
  1238. !
  1239. ! CheckTime( mf, time1, time2, status )
  1240. !
  1241. ! return status:
  1242. ! 0 : times match
  1243. ! 1 : times do not match, try next record
  1244. ! 2 : current record is newer than requested (reopen ?)
  1245. ! 3 : some error
  1246. !
  1247. ! ***
  1248. !
  1249. ! Return time parameters for grib files:
  1250. ! o tfile : date in filename
  1251. ! o trange : time interval covered by fields in file
  1252. ! o tref : reference time (forecast start?) for tday,[t1,t2]
  1253. !
  1254. ! Called as:
  1255. ! call GetGribTime( treskey, tday, t1, t2, status, tref=tref )
  1256. ! call GetGribTime( treskey, tref, t1, t2, status, tfile=tfile )
  1257. !
  1258. subroutine GetGribTime( treskey, t0, t1, t2, status, tfile, trange, tref, tshift )
  1259. use GO, only : TDate, TIncrDate, Get, Set, wrtgol, NewDate, IncrDate
  1260. use GO, only : operator(+), operator(-), operator(<), rTotal, iTotal
  1261. use GO, only : AnyDate, IsAnyDate
  1262. use GO, only : wrtgol
  1263. ! --- in/out --------------------------------
  1264. character(len=*), intent(in) :: treskey
  1265. type(TDate), intent(in) :: t0, t1, t2
  1266. integer, intent(out) :: status
  1267. type(TDate), intent(out), optional :: tfile
  1268. type(TDate), intent(out), optional :: trange(2)
  1269. type(TDate), intent(out), optional :: tref
  1270. type(TIncrDate), intent(out), optional :: tshift
  1271. ! --- const --------------------------------------
  1272. character(len=*), parameter :: rname = mname//'/GetGribTime'
  1273. ! --- local --------------------------------
  1274. integer :: hour1, hour2, time6(6)
  1275. integer :: dd, hh, step
  1276. integer :: anhh
  1277. real :: ddr
  1278. ! --- begin --------------------------------
  1279. !write (gol,'(" GetGribTime: treskey : ",a)') trim(treskey); call goPr
  1280. !call wrtgol( ' GetGribTime: t0 : ', t0 ); call goPr
  1281. !call wrtgol( ' GetGribTime: t1 : ', t1 ); call goPr
  1282. !call wrtgol( ' GetGribTime: t2 : ', t2 ); call goPr
  1283. ! files opened upon reading, thus no particular time range for which file is valid:
  1284. if ( present(trange) ) then
  1285. trange(1) = AnyDate()
  1286. trange(2) = AnyDate()
  1287. end if
  1288. ! zero shift by default
  1289. if ( present(tshift) ) tshift = IncrDate(hour=0)
  1290. ! set day shift, start hour, and step
  1291. select case ( treskey )
  1292. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1293. ! constant field
  1294. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1295. case ( 'const' )
  1296. ! only t0 is usefull ...
  1297. if ( present(tfile ) ) tfile = t0
  1298. !if ( present(trange) ) trange = (/t1,t2/) ! any, any
  1299. if ( present(tref ) ) tref = t0 ! dummy ...
  1300. ! take analysed fields always at least 24 hour old,
  1301. ! since these are the only analysed fields available in forecast mode
  1302. if ( present(tshift) ) then
  1303. !tshift = IncrDate(hour=24)
  1304. ! FIX for start of ml91 test suite; try if 12 is ok too ...
  1305. tshift = IncrDate(hour=12)
  1306. end if
  1307. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1308. ! fc, 3/6 hourly
  1309. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1310. case ( '_03p03', '_06p06' )
  1311. ! extract end hour:
  1312. call Get( t2, hour=hour2 )
  1313. ! set forecast start time and step given hour:
  1314. select case ( hour2 )
  1315. case ( 00 ) ; dd = 0 ; hh = 00 ; step = 24
  1316. case ( 03 ) ; dd = 0 ; hh = 00 ; step = 3
  1317. case ( 06 ) ; dd = 0 ; hh = 00 ; step = 6
  1318. case ( 09 ) ; dd = 0 ; hh = 00 ; step = 9
  1319. case ( 12 ) ; dd = 0 ; hh = 00 ; step = 12
  1320. case ( 15 ) ; dd = 0 ; hh = 00 ; step = 15
  1321. case ( 18 ) ; dd = 0 ; hh = 00 ; step = 18
  1322. case ( 21 ) ; dd = 0 ; hh = 00 ; step = 21
  1323. case default
  1324. write (gol,'("unsupported hour :")'); call goErr
  1325. write (gol,'(" hour2 : ",i2)') hour2; call goErr
  1326. write (gol,'(" timesteps : ",a )') treskey; call goErr
  1327. call wrtgol( ' time1 : ', t1 ); call goErr
  1328. write (gol,'("in ",a)') rname; call goErr; status=1; return
  1329. end select
  1330. ! file ccyymmdd contains fields for (00,24] :
  1331. if ( present(tfile) ) then
  1332. ! current day by default:
  1333. tfile = t2
  1334. call Set( tfile, hour=0, min=0, sec=0, mili=0 ) ! 00:00
  1335. ! trap (..,00:00], this should be previous day:
  1336. call Get( t2, time6=time6 )
  1337. if ( all(time6(4:6)==0) ) tfile = tfile - IncrDate(day=1)
  1338. end if
  1339. ! fields valid for (00,24] :
  1340. if ( present(trange) ) then
  1341. trange(1) = t2
  1342. call Set( trange(1), hour=0, min=0, sec=0, mili=0 ) ! 00:00
  1343. ! trap 00:00, this should be previous day:
  1344. call Get( t2, time6=time6 )
  1345. if ( all(time6(4:6)==0) ) trange(1) = trange(1) - IncrDate(day=1)
  1346. ! complete (00,24]
  1347. trange(2) = trange(1) + IncrDate(day=1) ! 24:00
  1348. call Set( trange(1), mili=1 ) ! > 00:00
  1349. end if
  1350. ! reference time = start of forecast
  1351. if ( present(tref) ) then
  1352. call Get( t2, time6=time6 )
  1353. tref = NewDate( time6=time6 )
  1354. ! time6(4:6) = 0
  1355. ! tref = NewDate( time6=time6 ) + IncrDate( day=dd, hour=hh )
  1356. end if
  1357. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1358. ! fc, 3 hourly
  1359. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1360. case ( '_fc012up2tr3' )
  1361. ! end hour counted from t0 00:00
  1362. hour2 = iTotal( t2 - t0, 'hour' )
  1363. ! set forecast start time and step given hour:
  1364. if ( hour2 == 0 ) then
  1365. ! 00:00 fc day 0
  1366. dd = -1 ; hh = 12 ; step = 12
  1367. else if ( (hour2 <= 12) .and. (modulo(hour2,3) == 0) ) then
  1368. ! (00,12] fc day 0
  1369. dd = 0
  1370. hh = 00
  1371. step = hour2
  1372. else if ( ( (t0 < NewDate(year=2006,month=03,day=14) ) .and. &
  1373. ( ((hour2 <= 12+ 72) .and. (modulo(hour2,3) == 0)) .or. &
  1374. ((hour2 <= 12+240) .and. (modulo(hour2,6) == 0)) ) ) &
  1375. .or. ( ( ((hour2 <= 12+ 96) .and. (modulo(hour2,3) == 0)) .or. &
  1376. ((hour2 <= 12+240) .and. (modulo(hour2,6) == 0)) ) ) ) then
  1377. ! (12,240] fc days 1-10
  1378. dd = 0
  1379. hh = 12
  1380. step = hour2 - 12
  1381. else
  1382. write (gol,'("unsupported hour :")'); call goErr
  1383. write (gol,'(" hour2 : ",i3)') hour2; call goErr
  1384. write (gol,'(" treskey : ",a )') treskey; call goErr
  1385. call wrtgol( ' time1 : ', t1 ); call goErr
  1386. write (gol,'("in ",a)') rname; call goErr; status=1; return
  1387. end if
  1388. !! fields valid for hh+(00,12] :
  1389. !if ( present(trange) ) then
  1390. ! trange(1) = t2
  1391. ! call Set( trange(1), hour=hh, min=0, sec=0, mili=0 ) ! hh:00
  1392. ! ! trap 00:00, this should be previous day:
  1393. ! call Get( t2, time6=time6 )
  1394. ! if ( all(time6(4:6)==0) ) trange(1) = trange(1) - IncrDate(day=1)
  1395. ! ! complete (00,12]
  1396. ! trange(2) = trange(1) + IncrDate(hour=12) ! 24:00
  1397. ! call Set( trange(1), mili=1 ) ! > 00:00
  1398. !end if
  1399. ! reference time = start of forecast
  1400. if ( present(tref) ) then
  1401. tref = t0 + IncrDate(day=dd,hour=hh)
  1402. end if
  1403. ! adhoc: if tfile is requested, probably the 'tref' returned before
  1404. ! is now in input 't0' ...
  1405. if ( present(tfile) ) then
  1406. tfile = t0 ! .. is tref !
  1407. end if
  1408. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1409. ! analysis, files for hours 0, 6, 12, and 18
  1410. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1411. case ( '_an0tr6' )
  1412. ! reference time = analysis time
  1413. if ( present(tref) ) then
  1414. tref = t1
  1415. end if
  1416. ! t0 t1,t2 ->
  1417. ! -+-----------------------+-----------------------+--->
  1418. ! 00 06 12 18 00 06 12 18 00
  1419. ! a
  1420. ! a a
  1421. ! a a(-----------] 00 analysis/forecast
  1422. ! a a(--------------> 12 forecast
  1423. !
  1424. ! -24 -24 -24 -24 -48 shift
  1425. ! take analysed fields always at least 24 hour old,
  1426. ! since these are the only analysed fields available in forecast mode,
  1427. ! and to obtain a contineous time line
  1428. ! t0 is always 00:00
  1429. if ( present(tshift) ) then
  1430. ! difference between t1 and t0 00:00 in fraction of days:
  1431. ddr = rTotal( t1 - t0, 'day' )
  1432. ! set time shift in days:
  1433. tshift = IncrDate(day=floor(ddr)+1)
  1434. !! FIX for start of ml91 test suite; try if 12 is ok too ...
  1435. !tshift = IncrDate(day=floor(ddr),hour=12)
  1436. end if
  1437. ! one file for each time:
  1438. if ( present(tfile) ) then
  1439. tfile = t1
  1440. end if
  1441. !! fields in file valid for instant time:
  1442. !if ( present(trange) ) then
  1443. ! trange(1) = t1
  1444. ! trange(2) = t1
  1445. !end if
  1446. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1447. ! fc, 1 hourly emissions
  1448. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1449. case ( '_fc000up24tr1' )
  1450. ! macc emisisons
  1451. ! fields in grib file have time stamps 00:30, 01:30, etc
  1452. ! reference time = start of forecast
  1453. if ( present(tref) ) then
  1454. ! end hour counted from t0 00:00
  1455. hour2 = iTotal( t2 - t0, 'hour' )
  1456. ! field from current day, 'forecast time' 00:30 etc:
  1457. tref = t0 + IncrDate(day=0,hour=hour2-1,min=30)
  1458. ! no steps in this timing convention:
  1459. step = 0
  1460. !! debug ...
  1461. !write (gol,*) ' GetGribTime: dd, hh, step : ', dd, hh, step; call goPr
  1462. !call wrtgol( ' GetGribTime: set tref to : ', tref ); call goPr
  1463. end if
  1464. ! adhoc: if tfile is requested, probably the 'tref' returned before
  1465. ! is now in input 't0' ...
  1466. if ( present(tfile) ) then
  1467. tfile = t0 ! .. is tref !
  1468. !! debug ...
  1469. !call wrtgol( ' GetGribTime: set tfile to : ', tfile ); call goPr
  1470. end if
  1471. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1472. ! fc, daily emissions
  1473. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1474. case ( '_fc000up1tr24' )
  1475. ! macc emisisons
  1476. ! fields in grib file have time stamp 12:00
  1477. ! reference time = start of forecast ;
  1478. ! her always 12:00 of current day:
  1479. if ( present(tref) ) then
  1480. ! reference time is 12:00 on day including [t1,t2],
  1481. ! thus simply use t1 and reset some values:
  1482. tref = t1
  1483. call Set( tref, hour=12, min=0, sec=0 )
  1484. end if
  1485. ! time in file is the day including [t1,t2] too:
  1486. if ( present(tfile) ) then
  1487. tfile = t1
  1488. call Set( tfile, hour=12, min=0, sec=0 )
  1489. end if
  1490. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1491. ! ???
  1492. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1493. case default
  1494. write (gol,'("unsupported time resolution key:")'); call goErr
  1495. write (gol,'(" `",a,"`")') trim(treskey); call goErr
  1496. TRACEBACK; status=1; return
  1497. end select
  1498. ! ok
  1499. status = 0
  1500. end subroutine GetGribTime
  1501. ! ***
  1502. !
  1503. ! Extract time fields of current grib record,
  1504. ! and store them in mf%tref, mf%t1, mf%t2
  1505. !
  1506. subroutine SetTime( mf, grib, status )
  1507. use GO, only : TDate, NewDate, IncrDate, operator(+), wrtgol
  1508. use file_grib, only : TGribFile, Get
  1509. ! --- const -------------------------------------
  1510. character(len=*), parameter :: rname = mname//'/SetTime'
  1511. ! --- in/out -------------------------------
  1512. type(TMeteoFile_ecmwf_tm5), intent(inout) :: mf
  1513. type(TGribFile), intent(inout) :: grib
  1514. integer, intent(out) :: status
  1515. ! --- local -------------------------------
  1516. integer :: reftime(5), timerange(4)
  1517. ! --- begin -------------------------------
  1518. ! extract time fields from grib record:
  1519. call Get( grib, status, reftime=reftime, timerange=timerange )
  1520. IF_NOTOK_RETURN(status=1)
  1521. ! Fill t1 and t2 with the time information; might be equal.
  1522. ! Check time range indicator (WMO code table 5):
  1523. select case ( timerange(4) )
  1524. case ( 0, 1 )
  1525. !
  1526. ! 0 = Forecast product valid for reference time + P1 (P1>0),
  1527. ! or uninitialized analysis product for reference time (P1=0)
  1528. !
  1529. ! 1 = Initialized analysis product for reference time (P1=0).
  1530. !
  1531. ! fill reference time:
  1532. mf%tref = NewDate( time5=reftime )
  1533. ! fill t1 with reftime+timerange;
  1534. ! add P1 in hours; check time unit (WMO code table 4)
  1535. mf%t1 = NewDate( time5=reftime )
  1536. select case ( timerange(1) )
  1537. case ( 1 ) ! hours
  1538. mf%t1 = mf%t1 + IncrDate( hour=timerange(2) )
  1539. case default
  1540. write (gol,'("grib timerange units other than hours not supported yet")'); call goErr
  1541. write (gol,'(" reftime : ",i4,4i3)') reftime; call goErr
  1542. write (gol,'(" timerange : ",4i3)') timerange; call goErr
  1543. write (gol,'(" file : ",a)') trim(grib%fname); call goErr
  1544. TRACEBACK; status=1; return
  1545. end select
  1546. ! instant time:
  1547. mf%t2 = mf%t1
  1548. case ( 2 )
  1549. !
  1550. ! 2 = Product with a valid time ranging between
  1551. ! reference time + P1 and reference time + P2
  1552. !
  1553. ! fill reftime:
  1554. mf%tref = NewDate( time5=reftime )
  1555. ! fill t1 with reftime+P1;
  1556. ! add P1 in hours; check time unit (WMO code table 4)
  1557. mf%t1 = mf%tref
  1558. select case ( timerange(1) )
  1559. case ( 1 ) ! hours
  1560. mf%t1 = mf%t1 + IncrDate( hour=timerange(2) )
  1561. case default
  1562. write (gol,'("grib timerange units other than hours not supported yet")'); call goErr
  1563. write (gol,'(" file : ",a)') trim(grib%fname); call goErr
  1564. TRACEBACK; status=1; return
  1565. end select
  1566. ! fill t2 with reftime+P2;
  1567. ! add P2 in hours; check time unit (WMO code table 4)
  1568. mf%t2 = mf%tref
  1569. select case ( timerange(1) )
  1570. case ( 1 ) ! hours
  1571. mf%t2 = mf%t2 + IncrDate( hour=timerange(3) )
  1572. case default
  1573. write (gol,'("grib timerange units other than hours not supported yet")'); call goErr
  1574. write (gol,'(" file : ",a)') trim(grib%fname); call goErr
  1575. TRACEBACK; status=1; return
  1576. end select
  1577. case default
  1578. write (gol,'("unsupported time range indicator:")'); call goErr
  1579. write (gol,'(" indicator : ",i6)') timerange(4); call goErr
  1580. write (gol,'(" file : ",a)') trim(grib%fname); call goErr
  1581. TRACEBACK; status=1; return
  1582. end select
  1583. ! ok
  1584. status = 0
  1585. end subroutine SetTime
  1586. ! ***
  1587. subroutine CheckTime( mf, tref, t1, t2, status )
  1588. use GO
  1589. use file_grib, only : Get
  1590. ! --- const -------------------------------------
  1591. character(len=*), parameter :: rname = mname//'/CheckTime'
  1592. ! --- in/out -------------------------------
  1593. type(TMeteoFile_ecmwf_tm5), intent(in) :: mf
  1594. type(TDate), intent(in) :: tref, t1, t2
  1595. integer, intent(out) :: status
  1596. ! --- local -------------------------------
  1597. integer :: year1, year2
  1598. ! --- begin -------------------------------
  1599. !call wrtgol( 'CheckTime: (', tref, ') ', t1, ' - ', t2 ); call goPr
  1600. !call wrtgol( 'CheckTime: (', mf%tref, ') ', mf%t1, ' - ', mf%t2 ); call goPr
  1601. ! requested year zero ? always ok
  1602. call Get( t1, year=year1 )
  1603. call Get( t2, year=year2 )
  1604. if ( (year1 == 0) .and. (year2 == 0) ) then
  1605. ! requested constant field, always ok
  1606. status = 0; return ! ok
  1607. end if
  1608. if ( year1 == 0 ) then
  1609. ! do not test t1, only t2
  1610. if ( t2 == mf%t2 ) then
  1611. status = 0; return ! ok
  1612. else
  1613. status = 1; return ! not ok, try next
  1614. end if
  1615. else if ( year2 == 0 ) then
  1616. ! do not test t2, only t1
  1617. if ( t1 == mf%t1 ) then
  1618. status = 0; return ! ok
  1619. else
  1620. status = 1; return ! not ok, try next
  1621. end if
  1622. end if
  1623. ! ! interval or instant time
  1624. ! if ( t1 < t2 ) then
  1625. !
  1626. ! !! time interval: [t1,t2] should be inside [t1,t2]
  1627. ! !if ( (t1 >= mf%t1) .and. (t2 <= mf%t2) ) then
  1628. ! ! status = 0; return ! ok
  1629. ! !else
  1630. ! ! status = 1; return ! try next
  1631. ! !end if
  1632. !
  1633. ! ! time interval: [t1,t2] should be equal to [t1,t2]
  1634. ! if ( (t1 == mf%t1) .and. (t2 == mf%t2) ) then
  1635. ! status = 0; return ! ok
  1636. ! else
  1637. ! status = 1; return ! try next
  1638. ! end if
  1639. !
  1640. ! else if ( t1 == t2 ) then
  1641. !
  1642. ! ! instant time: t2 should match t2
  1643. ! if ( t2 == mf%t2 ) then
  1644. ! status = 0; return ! ok
  1645. ! else
  1646. ! status = 1; return ! try next
  1647. ! end if
  1648. !
  1649. ! else
  1650. !
  1651. ! write (gol,'("t1 should not exceed t2:")'); call goErr
  1652. ! call wrtgol( ' t1 : ', t1 ); call goErr
  1653. ! call wrtgol( ' t2 : ', t2 ); call goErr
  1654. ! TRACEBACK; status=3; return
  1655. !
  1656. ! end if
  1657. ! compare all:
  1658. if ( (tref == mf%tref) .and. (t1 == mf%t1) .and. (t2 == mf%t2) ) then
  1659. status = 0; return ! ok
  1660. else
  1661. status = 1; return ! try next
  1662. end if
  1663. ! some error ...
  1664. status = 1
  1665. end subroutine CheckTime
  1666. end module tmm_mf_ecmwf_tm5