tmm_mf_ecmwf_tm5.F90 74 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165
  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 Binas , only : rol ! rho (density) liquid water [kg/m3]
  330. use parray , only : pa_Init, pa_Done
  331. use GO , only : TDate, TIncrDate, IncrDate, operator(<), operator(-), rTotal, wrtgol
  332. use Grid , only : TLevelInfo
  333. use Grid , only : TllGridInfo, TggGridInfo, TshGridInfo
  334. use tmm_info , only : TMeteoInfo
  335. ! --- in/out -------------------------------
  336. type(TMeteoFile_ecmwf_tm5), intent(inout) :: mf
  337. character(len=*), intent(in) :: paramkey
  338. type(TDate), intent(in) :: tday, t1, t2
  339. character(len=1), intent(in) :: nuv
  340. character(len=1), intent(in) :: nw
  341. character(len=2), intent(out) :: gridtype
  342. type(TLevelInfo), intent(out) :: levi
  343. type(TllGridInfo), intent(inout) :: lli
  344. real, pointer :: ll(:,:,:)
  345. real, pointer :: sp_ll(:,:)
  346. type(TggGridInfo), intent(inout) :: ggi
  347. real, pointer :: gg(:,:)
  348. real, pointer :: sp_gg(:)
  349. type(TshGridInfo), intent(inout) :: shi
  350. complex, pointer :: sh(:,:)
  351. complex, pointer :: lnsp_sh(:)
  352. type(TMeteoInfo), intent(out) :: tmi
  353. integer, intent(out) :: status
  354. ! --- const --------------------------------------
  355. character(len=*), parameter :: rname = mname//'/mf_ReadRecord_1'
  356. ! --- local -------------------------------
  357. type(TDate) :: tref
  358. type(TIncrDate) :: tshift
  359. type(TDate) :: trefs, t1s, t2s
  360. real, pointer :: ll1(:,:,:), sp_ll1(:,:)
  361. real, pointer :: gg1(:,:) , sp_gg1(:)
  362. complex, pointer :: sh1(:,:) , lnsp_sh1(:)
  363. real :: dt_sec
  364. integer :: i, j, k
  365. ! --- begin ---------------------------------
  366. !! testing ...
  367. !write (gol,'("mf_ReadRecord_1: paramkey : ",a)') trim(paramkey); call goPr
  368. !call wrtgol( 'mf_ReadRecord_1: tday : ', tday ); call goPr
  369. !call wrtgol( 'mf_ReadRecord_1: t1 : ', t1 ); call goPr
  370. !call wrtgol( 'mf_ReadRecord_1: t2 : ', t2 ); call goPr
  371. ! accumulated field ?
  372. select case ( paramkey )
  373. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  374. ! accumulated fields
  375. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  376. case ( 'lsp', 'cp', 'sf', 'sshf', 'slhf', &
  377. 'ssr', 'ssrd', 'str', 'strd', &
  378. 'ewss', 'nsss', &
  379. 'UDMF', 'UDDR', 'DDMF', 'DDDR', 'TDCHA', 'K' )
  380. ! get reference time for requested time interval:
  381. call GetGribTime( mf%treskey, tday, t1, t2, status, tref=tref )
  382. IF_NOTOK_RETURN(status=1)
  383. ! should be a time interval ...
  384. if ( .not. (t1 < t2) ) then
  385. write (gol,'("accumulated fields requires time interval:")'); call goErr
  386. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  387. call wrtgol( ' t1 : ', t1 ); call goErr
  388. call wrtgol( ' t2 : ', t2 ); call goErr
  389. TRACEBACK; status=1; return
  390. end if
  391. !! testing ...
  392. !call wrtgol( ' accum ', tref, ' - ', t2 ); call goPr
  393. ! read field accumulated over [tref,t2] :
  394. call mf_ReadRecord_2( mf, paramkey, tref, t2, t2, nuv, nw, &
  395. gridtype, levi, &
  396. lli, ll, sp_ll, &
  397. ggi, gg, sp_gg, &
  398. shi, sh, lnsp_sh, &
  399. tmi, status )
  400. IF_NOTOK_RETURN(status=1)
  401. ! substract [tref,t1] if necessary:
  402. if ( tref < t1 ) then
  403. ! init pointer:
  404. call pa_Init( ll1 ); call pa_Init( sp_ll1 )
  405. call pa_Init( gg1 ); call pa_Init( sp_gg1 )
  406. call pa_Init( sh1 ); call pa_Init( lnsp_sh1 )
  407. ! read field accumulated over [tref,t1] :
  408. call wrtgol( ' accum ', tref, ' - ', t1 ); call goPr
  409. call mf_ReadRecord_2( mf, paramkey, tref, t1, t1, nuv, nw, &
  410. gridtype, levi, &
  411. lli, ll1, sp_ll1, &
  412. ggi, gg1, sp_gg1, &
  413. shi, sh1, lnsp_sh1, &
  414. tmi, status )
  415. IF_NOTOK_RETURN(status=1)
  416. ! substract, fill surface pressure with average:
  417. select case ( gridtype )
  418. case ( 'll' )
  419. ll = ll - ll1
  420. if (associated(sp_ll1)) sp_ll = 0.5 * ( sp_ll + sp_ll1 )
  421. case ( 'gg' )
  422. gg = gg - gg1
  423. if (associated(sp_gg1)) sp_gg = 0.5 * ( sp_gg + sp_gg1 )
  424. case ( 'sh' )
  425. sh = sh - sh1
  426. if (associated(lnsp_sh1)) lnsp_sh = 0.5 * ( lnsp_sh + lnsp_sh1 )
  427. case default
  428. write (gol,'("unsupported gridtype for substract :",a)') gridtype; call goErr
  429. TRACEBACK; status=1; return
  430. end select
  431. ! clear pointers:
  432. call pa_Done( ll1 ); call pa_Done( sp_ll1 )
  433. call pa_Done( gg1 ); call pa_Done( sp_gg1 )
  434. call pa_Done( sh1 ); call pa_Done( lnsp_sh1 )
  435. end if
  436. ! return time averages only:
  437. dt_sec = rTotal( t2 - t1, 'sec' )
  438. select case ( gridtype )
  439. case ( 'll' ) ; ll = ll / dt_sec
  440. case ( 'gg' ) ; gg = gg / dt_sec
  441. case ( 'sh' ) ; sh = sh / dt_sec
  442. case default
  443. write (gol,'("unsupported gridtype for time average :",a)') gridtype; call goErr
  444. TRACEBACK; status=1; return
  445. end select
  446. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  447. ! averaged fields (over last hour?)
  448. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  449. case ( 'MUMF', 'MDMF', 'MUDR', 'MDDR', 'MTDCH', &
  450. 'mlspr', 'mcpr', 'msr', 'msshf','mslhf', &
  451. 'msdwswrf','msdwlwrf','msnswrf','msnlwrf','metss','mntss' )
  452. ! get reference time for requested time interval:
  453. call GetGribTime( mf%treskey, tday, t1, t2, status, tref=tref )
  454. IF_NOTOK_RETURN(status=1)
  455. ! should be a time interval ...
  456. if ( .not. (t1 < t2) ) then
  457. write (gol,'("accumulated fields requires time interval:")'); call goErr
  458. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  459. call wrtgol( ' t1 : ', t1 ); call goErr
  460. call wrtgol( ' t2 : ', t2 ); call goErr
  461. TRACEBACK; status=1; return
  462. end if
  463. !! testing ...
  464. !call wrtgol( ' read average over ', t2-IncrDate(hour=1), ' - ', t2 ); call goPr
  465. ! read field accumulated over [t2-(1 hour),t2],
  466. ! but only end time t2 seems in file ...
  467. call mf_ReadRecord_2( mf, paramkey, tref, t2, t2, nuv, nw, &
  468. gridtype, levi, &
  469. lli, ll, sp_ll, &
  470. ggi, gg, sp_gg, &
  471. shi, sh, lnsp_sh, &
  472. tmi, status )
  473. IF_NOTOK_RETURN(status=1)
  474. ! unit conversions needed?
  475. select case ( paramkey )
  476. !~ rain/snow fields:
  477. case ( 'mlspr', 'mcpr', 'msr' )
  478. ! safety ...
  479. if ( .not. associated(gg) ) then
  480. write (gol,'("gg field not allocated for paramkey `",a,"`")') trim(paramkey); call goErr
  481. TRACEBACK; status=1; return
  482. end if
  483. ! convert:
  484. ! (kg water (eqv))/m2/s / ((kg water (eqv))/m3)
  485. gg = gg / rol ! (m water)/s
  486. end select
  487. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  488. ! instantaneous fields
  489. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  490. case default
  491. ! get reference time for requested time interval;
  492. ! eventually shift for analysed fields in case of forecasts:
  493. call GetGribTime( mf%treskey, tday, t1, t2, status, tref=tref, tshift=tshift )
  494. IF_NOTOK_RETURN(status=1)
  495. ! shift times (might be zero):
  496. trefs = tref - tshift
  497. t1s = t1 - tshift
  498. t2s = t2 - tshift
  499. ! just read ..
  500. call mf_ReadRecord_2( mf, paramkey, trefs, t1s, t2s, nuv, nw, &
  501. gridtype, levi, &
  502. lli, ll, sp_ll, &
  503. ggi, gg, sp_gg, &
  504. shi, sh, lnsp_sh, &
  505. tmi, status )
  506. IF_NOTOK_RETURN(status=1)
  507. end select
  508. status = 0
  509. end subroutine mf_ReadRecord_1
  510. ! ***
  511. ! Loop through grib messages, find one matching the requested input and decode it.
  512. !
  513. subroutine mf_ReadRecord_2( mf, paramkey, tref, t1, t2, nuv, nw, &
  514. gridtype, levi, &
  515. lli, ll, sp_ll, &
  516. ggi, gg, sp_gg, &
  517. shi, sh, lnsp_sh, &
  518. tmi, status )
  519. use GO , only : TDate, wrtgol, Get, NewDate, operator(>=)
  520. use GO , only : goWriteKeyNum
  521. use Grid , only : Init, Done
  522. use Grid , only : TLevelInfo
  523. use Grid , only : TllGridInfo, TggGridInfo, TshGridInfo
  524. use Grid , only : Interpol
  525. use file_grib , only : TGribFile
  526. use file_grib , only : Init, Done, ReadRecord, Get, Check
  527. use file_grib , only : levtype_sfc, levtype_hyb, levtype_land
  528. use file_grib , only : gridtype_ll, gridtype_gg, gridtype_red_gg, gridtype_sh
  529. use grib_table, only : GetPid
  530. use PArray , only : pa_Init, pa_Done, pa_SetShape
  531. use tmm_info , only : TMeteoInfo, Init, AddHistory
  532. ! --- in/out -------------------------------
  533. type(TMeteoFile_ecmwf_tm5), intent(inout) :: mf
  534. character(len=*), intent(in) :: paramkey
  535. type(TDate), intent(in) :: tref, t1, t2
  536. character(len=1), intent(in) :: nuv
  537. character(len=1), intent(in) :: nw
  538. character(len=2), intent(out) :: gridtype
  539. type(TLevelInfo), intent(out) :: levi
  540. type(TllGridInfo), intent(inout) :: lli
  541. real, pointer :: ll(:,:,:)
  542. real, pointer :: sp_ll(:,:)
  543. type(TggGridInfo), intent(inout) :: ggi
  544. real, pointer :: gg(:,:)
  545. real, pointer :: sp_gg(:)
  546. type(TshGridInfo), intent(inout) :: shi
  547. complex, pointer :: sh(:,:)
  548. complex, pointer :: lnsp_sh(:)
  549. type(TMeteoInfo), intent(out) :: tmi
  550. integer, intent(out) :: status
  551. ! --- const --------------------------------------
  552. character(len=*), parameter :: rname = mname//'/mf_ReadRecord_2'
  553. ! --- local -------------------------------
  554. character(len=16) :: ec_class, ec_type
  555. character(len=16) :: ec_grid, gridN, gridT
  556. character(len=16) :: levs
  557. character(len=16) :: treskey
  558. logical :: constant
  559. type(TGribFile) :: grib
  560. logical :: do_spm
  561. character(len=256) :: spm_fname
  562. type(TGribFile) :: spm_grib
  563. logical :: spm_lnsp
  564. logical :: spm_lnsp2sp
  565. integer :: pid, tabid
  566. character(len=7) :: gribcode
  567. character(len=3) :: gribcode2
  568. character(len=6) :: gribcode3
  569. character(len=4) :: timekey
  570. character(len=16) :: spm_levs, spm_paramkey, ec_paramkey
  571. type(TDate) :: tfile
  572. integer :: ccyy, mm, dd, hh, min
  573. type(TDate) :: t37r3 ! time when cycle 37r3 became operational
  574. logical :: exist
  575. logical :: isfirst
  576. logical :: reopened
  577. integer :: nlev, glevtype, glevel
  578. integer :: level
  579. integer :: nlev_out, level_out
  580. integer :: ggridtype
  581. real :: lon_first, lon_inc
  582. integer :: lon_n
  583. real :: lat_first, lat_inc
  584. logical :: ll_ew_to_we
  585. integer :: lat_n
  586. integer :: ggN
  587. integer :: shT
  588. integer :: greftime(5), gtimerange(4)
  589. character(len=64) :: key
  590. integer :: ilon, ilat, nrec
  591. real, pointer :: pat(:,:)
  592. type(TshGridInfo) :: tmp_shi
  593. complex, pointer :: tmp_sh(:)
  594. ! --- begin ---------------------------------
  595. !! testing ...
  596. !write (gol,'("mf_ReadRecord_2: paramkey : ",a)') trim(paramkey); call goPr
  597. !call wrtgol( 'mf_ReadRecord_2: tref : ', tref ); call goPr
  598. !call wrtgol( 'mf_ReadRecord_2: t1 : ', t1 ); call goPr
  599. !call wrtgol( 'mf_ReadRecord_2: t2 : ', t2 ); call goPr
  600. ! no fluxes through boundaries ...
  601. if ( nuv /= 'n' ) then
  602. write (gol,'("unsupported nuv key : ",a)') nuv; call goErr
  603. TRACEBACK; status=1; return
  604. end if
  605. ! limitted support of fluxes ..
  606. !if ( nw /= 'n' ) then
  607. ! write (gol,'("unsupported nw key : ",a)') nw; call goErr
  608. ! TRACEBACK; status=1; return
  609. !end if
  610. ! init pointer arrays:
  611. call pa_Init( pat )
  612. !
  613. ! ~~~ 3d field or 2d stored in 3d array
  614. !
  615. ! grid : T159, N80, etc
  616. call goWriteKeyNum( gridT, 'T', mf%ec_sh )
  617. call goWriteKeyNum( gridN, 'N', mf%ec_gg )
  618. ! defaults
  619. ec_paramkey = paramkey
  620. ec_class = mf%ec_class
  621. ec_type = mf%ec_type
  622. levs = mf%ec_levs
  623. ec_grid = gridN
  624. treskey = mf%treskey
  625. constant = .false.
  626. do_spm = .false.
  627. spm_lnsp = .false.
  628. spm_lnsp2sp = .false.
  629. ! specials
  630. select case ( paramkey )
  631. case ( 'LNSP' )
  632. ec_grid = gridT
  633. case ( 'VO', 'D' )
  634. ec_grid = gridT
  635. do_spm = .true.
  636. spm_lnsp = .true.
  637. case ( 'T', 'W', 'Q', 'CLWC', 'CIWC', 'CC', &
  638. 'UDMF', 'UDDR', 'DDMF', 'DDDR', 'K', &
  639. 'MUMF', 'MDMF', 'MUDR', 'MDDR', 'MTDCH' )
  640. do_spm = .true.
  641. spm_lnsp2sp = (ec_class == 'e4') .or. (ec_class == 'ei') .or. (ec_class == 'ee') &
  642. .or. (ec_class == 'rd') .or. (ec_class == 'ea')
  643. case ( 'oro', 'lsm' )
  644. levs = 'sfc'
  645. constant = .true.
  646. treskey = 'const'
  647. ! tmm_convec tries to read oro using the default sourcekey,
  648. ! which probably contains type=fc ; force to use an for oro ...
  649. ec_type = 'an'
  650. ! adhoc ...
  651. if ( trim(ec_class) == 'rd' ) ec_class = 'ei'
  652. ! case ( 'cvl', 'cvh', 'tvl', 'tvh', 'sr', 'albedo', 'lsrh' )
  653. ! ec_type = 'an'
  654. ! levs = 'sfc'
  655. case ( 'ci', 'sst', 'swvl1', 'swvl2', 'swvl3', 'swvl4', '10fg', '10fg3', 'sd', 'lsp', &
  656. 'cp', 'sf', 'sshf', 'slhf', 'blh', 'u10m', 'v10m', 't2m', 'd2m', &
  657. 'ssr', 'ewss', 'nsss', 'sstr' ,'src', 'skt', &
  658. 'mlspr', 'mcpr', 'msr', 'msshf','mslhf', &
  659. 'msdwswrf','msdwlwrf','msnswrf','msnlwrf','metss','mntss' )
  660. levs = 'sfc'
  661. case ( 'sp' )
  662. spm_lnsp2sp = (ec_class == 'e4') .or. (ec_class == 'ei') .or. (ec_class == 'ee') &
  663. .or. (ec_class == 'rd') .or. (ec_class == 'ea')
  664. if ( spm_lnsp2sp ) then
  665. ec_paramkey = 'LNSP'
  666. else
  667. levs = 'sfc'
  668. end if
  669. case ( 'g10m' )
  670. ! g10m is retrieved as 10fg, or 10fg3 after cycle 37r3 (november 15th
  671. ! , 2011) for od data.
  672. ! 10fg has the same grib code as g10m, but 10fg3 has different code
  673. ! and table:
  674. t37r3 = NewDate( 2011, 11, 15, 12, 00, 00 )
  675. if (( ec_class == 'od').and.( tref >= t37r3)) then
  676. ec_paramkey = '10fg3'
  677. end if
  678. end select
  679. ! write gribcode
  680. call GetPid( 'ec', ec_paramkey, pid, tabid, status )
  681. IF_NOTOK_RETURN(status=1)
  682. write (gribcode,'(i3,".",i3.3)') pid, tabid
  683. write (gribcode2,'(i3)') pid
  684. write (gribcode3,'(i3.3,i3.3)') tabid, pid
  685. gribcode = adjustl(gribcode)
  686. gribcode2 = adjustl(gribcode2)
  687. ! convert input times to file name times:
  688. call GetGribTime( treskey, tref, t1, t2, status, tfile=tfile )
  689. IF_NOTOK_RETURN(status=1)
  690. !! testing ...
  691. !call wrtgol( 'mf_ReadRecord_2: tfile : ', tfile ); call goPr
  692. ! extract time values:
  693. call Get( tfile, year=ccyy, month=mm, day=dd, hour=hh, min=min )
  694. ! Timestamp in file name: 0000, 0600, 1200, 1800.. or 0030, 0130
  695. write (timekey,'(i4.4)') hh*100+min
  696. timekey = adjustl(timekey)
  697. ! create file name:
  698. ! dir/od-fc-20000101-1200-ml60-138-T159.gb
  699. !
  700. ! filename includes date:
  701. write (mf%fname,'(a,"/",a,"-",a,"-",i4.4,2i2.2,"-",a,"-",a,"-",a,"-",a,".gb")') &
  702. trim(mf%dir), &
  703. trim(ec_class), trim(ec_type), ccyy, mm, dd, trim(timekey), &
  704. trim(levs), trim(gribcode), trim(ec_grid)
  705. ! exist ?
  706. inquire( file=mf%fname, exist=exist )
  707. if ( .not. exist ) then
  708. ! Here we look for filename without table id. This seems to be ok: the
  709. ! table id is only missing in the OD-FC-ML grib files retrieved from MARS.
  710. write (gol,'("grib file does not exist:")'); call goPr
  711. write (gol,'(" ",a)') trim(mf%fname); call goPr
  712. write (gol,'("...will try another name:")'); call goPr
  713. write (mf%fname,'(a,"/",a,"-",a,"-",i4.4,2i2.2,"-",a,"-",a,"-",a,"-",a,".gb")') &
  714. trim(mf%dir), &
  715. trim(ec_class), trim(ec_type), ccyy, mm, dd, trim(timekey), &
  716. trim(levs), trim(gribcode2), trim(ec_grid)
  717. write (gol,'(" ",a)') trim(mf%fname); call goPr
  718. inquire( file=mf%fname, exist=exist )
  719. if (.not. exist) then
  720. write (gol,'("...will try another name:")'); call goPr
  721. write (mf%fname,'(a,"/",a,"-",a,"-",i4.4,2i2.2,"-",a,"-",a,"-",a,"-",a,".gb")') &
  722. trim(mf%dir), &
  723. trim(ec_class), trim(ec_type), ccyy, mm, dd, trim(timekey), &
  724. trim(levs), trim(gribcode3), trim(ec_grid)
  725. write (gol,'(" ",a)') trim(mf%fname); call goPr
  726. inquire( file=mf%fname, exist=exist )
  727. if (.not. exist) then
  728. write (gol,'("grib file w/o tableid does not exist either!")'); call goErr
  729. TRACEBACK; status=1; return
  730. end if ! grib file attempt 3
  731. endif ! grib file attempt 2
  732. end if ! grib file attempt 1
  733. ! open grib file
  734. call Init( grib, mf%fname, 'r', status )
  735. IF_NOTOK_RETURN(status=1)
  736. ! arrays and grids not defined yet
  737. isfirst = .true.
  738. reopened = .false.
  739. nrec = 0
  740. !!AJS: TESTING ...
  741. !okdebug = .true.
  742. ! loop over grib messages
  743. level = 0
  744. do
  745. !
  746. ! read gribsection in file buffer
  747. !
  748. call ReadRecord( grib, status )
  749. select case ( status )
  750. case ( 0 )
  751. ! no error
  752. if (okdebug) then
  753. nrec=nrec+1
  754. write (gol,'("grib file - read message #:",a,x,i5)') trim(grib%fname),nrec; call goPr
  755. end if
  756. case ( 1 )
  757. ! eof
  758. if ( .not. reopened ) then
  759. write (gol,'("grib read record: re-open ...")'); call goPr
  760. ! close:
  761. call Done( grib, status )
  762. IF_NOTOK_RETURN(status=1)
  763. ! reopen:
  764. call Init( grib, mf%fname, 'r', status )
  765. IF_NOTOK_RETURN(status=1)
  766. nrec=0
  767. reopened = .true.
  768. cycle
  769. else
  770. write (gol,'("reached eof before requested record was found")'); call goErr
  771. write (gol,'(" file : ",a)') trim(mf%fname); call goErr
  772. write (gol,'(" paramkey : ",a)') trim(paramkey); call goErr
  773. call wrtgol( ' tref : ', tref ); call goErr
  774. call wrtgol( ' t1 : ', t1 ); call goErr
  775. call wrtgol( ' t2 : ', t2 ); call goErr
  776. write (gol,'("tips:")'); call goErr
  777. write (gol,'(" o grib file corrupted or zero ?")'); call goErr
  778. write (gol,'(" o if accumulatd field,")'); call goErr
  779. write (gol,'(" check list of accumulated fields in mf_ReadRecord_1")'); call goErr
  780. TRACEBACK; status=1; return
  781. end if
  782. case default
  783. write (gol,'("error from grib_ReadRecord")') ; call goErr
  784. TRACEBACK; status=1; return
  785. end select
  786. !
  787. ! checks ...
  788. !
  789. ! expected paramId for the requested field (from grib_table.F90)
  790. select case ( paramkey )
  791. case ( 'spm' ) ; call GetPid( 'ec', 'SP' , pid, tabid, status )
  792. case default ; call GetPid( 'ec', ec_paramkey, pid, tabid, status )
  793. end select
  794. IF_NOTOK_RETURN(status=1)
  795. !AJS: TESTING: debug=1
  796. ! check paramId (two possibilities)
  797. call Check( grib, pid=pid, debug=0, status=status )
  798. if (status/=0) then
  799. if (okdebug) then
  800. write(gol,*) "wrong pid:", pid; call goPr
  801. endif
  802. pid=tabid*1000+pid ! new code to try
  803. call Check( grib, pid=pid, debug=0, status=status )
  804. if (okdebug) then
  805. write (gol,*) " checked pid :", pid, '; status : ', status; call goPr
  806. endif
  807. if (status/=0) then
  808. if (okdebug) then
  809. write(gol,*)"wrong pid:",pid; call goPr
  810. endif
  811. cycle
  812. endif
  813. endif
  814. ! fill times ?
  815. if ( .not. constant ) then
  816. ! extract time fields from grib, store in mf%tref/mf%t1/mf%t2
  817. call SetTime( mf, grib, status )
  818. IF_NOTOK_RETURN(status=1)
  819. ! check time:
  820. call CheckTime( mf, tref, t1, t2, status )
  821. if (status/=0) then
  822. ! testing ...
  823. if ( okdebug ) then
  824. write (gol,'("grib read record: wrong time; skip ...")'); call goPr
  825. write (gol,'(" paramkey : ",a)') paramkey; call goPr
  826. call wrtgol( ' req. tref : ', tref ); call goPr
  827. call wrtgol( ' t1 : ', t1 ); call goPr
  828. call wrtgol( ' t2 : ', t2 ); call goPr
  829. call wrtgol( ' grib tref : ', mf%tref ); call goPr
  830. call wrtgol( ' t1 : ', mf%t1 ); call goPr
  831. call wrtgol( ' t2 : ', mf%t2 ); call goPr
  832. write (gol,'(" grib file : ",a)') trim(mf%fname); call goPr
  833. end if
  834. cycle
  835. end if
  836. end if ! time checking
  837. ! extract level stuff:
  838. call Get( grib, nlev=nlev, levtype=glevtype, level=glevel, status=status )
  839. IF_NOTOK_RETURN(status=1)
  840. ! check level type:
  841. select case ( glevtype )
  842. case ( levtype_sfc, levtype_land )
  843. ! surface field
  844. nlev = 1
  845. glevel = 1
  846. case ( levtype_hyb )
  847. select case ( paramkey )
  848. case ( 'LNSP', 'sp' )
  849. nlev = 1
  850. case default
  851. ! level in 3d field
  852. end select
  853. case default
  854. write (gol,'("found unexpected level type: ")'); call goErr
  855. write (gol,'(" leveltype : ",i3)') glevtype; call goErr
  856. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  857. write (gol,'(" grib file : ",a)') trim(mf%fname); call goErr
  858. TRACEBACK; status=1; return
  859. end select
  860. ! check level:
  861. level = level + 1
  862. if ( glevel /= level ) then
  863. write (gol,'("found unexpected level: ")'); call goErr
  864. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  865. write (gol,'(" req. level : ",i6)') level; call goErr
  866. write (gol,'(" grib level : ",i6)') glevel; call goErr
  867. write (gol,'(" grib nlev : ",i6)') nlev; call goErr
  868. write (gol,'(" grib file : ",a)') trim(mf%fname); call goErr
  869. TRACEBACK; status=1; return
  870. end if
  871. ! number of output levels:
  872. nlev_out = nlev
  873. if ( nw == 'w' ) nlev_out = nlev_out + 1
  874. !
  875. ! define grids and arrays
  876. !
  877. if ( isfirst ) then
  878. !
  879. ! * info
  880. !
  881. ! example of history:
  882. ! model=ecmwf;class=od;type=fc;tref=2000,12,31,12,00; ...
  883. ! trange=001,234,240,001;sh=159;nlev=60
  884. !
  885. call Init( tmi, paramkey, 'unknown', status )
  886. call AddHistory( tmi, 'model==ecmwf', status )
  887. call AddHistory( tmi, 'class=='//trim(mf%ec_class), status )
  888. call AddHistory( tmi, 'type=='//trim(mf%ec_type) , status )
  889. !
  890. call Get( grib, status, reftime=greftime, timerange=gtimerange )
  891. IF_NOTOK_RETURN(status=1)
  892. write (key,'("tref==",i4.4,4(",",i2.2))') greftime
  893. call AddHistory( tmi, trim(key), status )
  894. write (key,'("trange==",i3.3,3(",",i3.3))') gtimerange
  895. call AddHistory( tmi, trim(key), status )
  896. !
  897. write (key,'("nlev==",i3.3)') nlev
  898. call AddHistory( tmi, trim(key), status )
  899. !
  900. ! * define horizontal grid:
  901. !
  902. ! extract grid type:
  903. call Get( grib, status, gridtype=ggridtype )
  904. IF_NOTOK_RETURN(status=1)
  905. ! setup:
  906. select case ( ggridtype )
  907. ! o lat/lon
  908. case ( gridtype_ll )
  909. ! routine returns lat/lon grid:
  910. gridtype = 'll'
  911. ! grib storage is north pole to south pole:
  912. call Get( grib, status, &
  913. lon_first=lon_first, lon_inc=lon_inc, lon_n=lon_n, &
  914. lat_last =lat_first, lat_inc=lat_inc, lat_n=lat_n )
  915. IF_NOTOK_RETURN(status=1)
  916. ! change from [0,360] (east-west) to [-180,180] (west-east) ?
  917. ! only if global coverage and first point less than half a grid cell from lon==0 :
  918. ll_ew_to_we = (abs(lon_n*lon_inc - 360.0) < 0.01) .and. &
  919. (abs(lon_first - 0.5*lon_inc) < 0.01 )
  920. ! apply ?
  921. if ( ll_ew_to_we ) then
  922. ! shift west bound:
  923. lon_first = lon_first - 180.0
  924. end if
  925. ! define grid structure:
  926. call Init( lli, lon_first, lon_inc, lon_n, &
  927. lat_first, lat_inc, lat_n, status )
  928. IF_NOTOK_RETURN(status=1)
  929. ! init array to store 2d field from grib file (north-south order):
  930. call pa_SetShape( pat, lon_n, lat_n )
  931. ! allocate output:
  932. call pa_SetShape( ll, lon_n, lat_n, nlev_out )
  933. ll = 0.0
  934. ! add to history:
  935. write (key,'("longrid==",f7.2,",",f6.2,",",i4)') lon_first, lon_inc, lon_n
  936. call AddHistory( tmi, trim(key), status )
  937. write (key,'("latgrid==",f7.2,",",f6.2,",",i4)') lat_first, lat_inc, lat_n
  938. call AddHistory( tmi, trim(key), status )
  939. ! o gaussian grid (NOTE: it is assumed that 'ecmwf_tm5' met field
  940. ! are **ALWAYS** on the reduced grid. --> to avoid potential
  941. ! problem we probably need to get rid of GRIBEX (where
  942. ! gridtype_gg implied reduced!). With grib_api we get the 'gridtype_red_gg'.
  943. case ( gridtype_gg, gridtype_red_gg )
  944. ! routine returns gg grid:
  945. gridtype = 'gg'
  946. ! extract grid number:
  947. call Get( grib, status, N=ggN )
  948. IF_NOTOK_RETURN(status=1)
  949. ! define grid structure:
  950. call Init( ggi, ggN, .true., status )
  951. IF_NOTOK_RETURN(status=1)
  952. ! allocate output:
  953. call pa_SetShape( gg, ggi%np, nlev_out )
  954. gg = 0.0
  955. ! add to history:
  956. write (key,'("gg==",i4.4)') ggN
  957. call AddHistory( tmi, trim(key), status )
  958. ! o spectral field:
  959. case ( gridtype_sh )
  960. ! routine returns sh grid:
  961. gridtype = 'sh'
  962. ! extract spectral truncation:
  963. call Get( grib, status, T=shT )
  964. IF_NOTOK_RETURN(status=1)
  965. ! intialize spherical harmonic field info:
  966. call Init( shi, shT, status )
  967. IF_NOTOK_RETURN(status=1)
  968. ! allocate output:
  969. call pa_SetShape( sh, shi%np, nlev_out )
  970. sh = cmplx(0.0,0.0)
  971. ! add to history:
  972. write (key,'("sh==",i4.4)') shT
  973. call AddHistory( tmi, trim(key), status )
  974. case default
  975. write (gol,'("unsupported gridtype for setup : ",i6)') ggridtype; call goErr
  976. TRACEBACK; status=1; return
  977. end select
  978. !
  979. ! * levels
  980. !
  981. select case ( nlev )
  982. case ( 1 )
  983. call Init( levi, nlev, (/0.0,0.0/), (/0.0,0.0/), status )
  984. IF_NOTOK_RETURN(status=1)
  985. case ( 60 )
  986. call Init( levi, 'ec60', status )
  987. IF_NOTOK_RETURN(status=1)
  988. case ( 62 )
  989. call Init( levi, 'ec62', status )
  990. IF_NOTOK_RETURN(status=1)
  991. case ( 91 )
  992. call Init( levi, 'ec91', status )
  993. IF_NOTOK_RETURN(status=1)
  994. case ( 137 )
  995. call Init( levi, 'ec137', status )
  996. IF_NOTOK_RETURN(status=1)
  997. case default
  998. write (gol,'("do not how to init levi for nlev = ",i6)') nlev; call goErr
  999. TRACEBACK; status=1; return
  1000. end select
  1001. ! not again ...
  1002. isfirst = .false.
  1003. end if ! isfirst (grid definition and allocation)
  1004. !
  1005. ! store
  1006. !
  1007. ! layers numbered 1..nlev, half levels numberd 1..nlev+1
  1008. ! top-down, thus 1 is space and nlev+1 is surface
  1009. if ( nw == 'w' ) then
  1010. ! store half levels
  1011. select case ( paramkey )
  1012. ! store in upper half level of a layer:
  1013. case ( 'UDMF', 'DDMF' )
  1014. level_out = level
  1015. !! store in lower half level of a layer:
  1016. !case ( 'dummy' )
  1017. ! level_out = level + 1
  1018. ! to be implemented ...
  1019. case default
  1020. write (gol,'("do not if data is on upper or lower half level ...")'); call goErr
  1021. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  1022. TRACEBACK; status=1; return
  1023. end select
  1024. else
  1025. ! store full levels
  1026. level_out = level
  1027. end if
  1028. select case ( ggridtype )
  1029. case ( gridtype_ll )
  1030. ! read 2d pat from grib; storred from north to south
  1031. call Get( grib, status, ll=pat )
  1032. IF_NOTOK_RETURN(status=1)
  1033. ! store from south to north:
  1034. do ilat = 1, lat_n
  1035. ! reshuffle ?
  1036. if ( ll_ew_to_we ) then
  1037. ! fill west part:
  1038. do ilon = 1, lon_n/2
  1039. ll(ilon,ilat,level_out) = pat(lon_n/2+ilon,lat_n+1-ilat)
  1040. end do
  1041. ! fill east part:
  1042. do ilon = lon_n/2+1, lon_n
  1043. ll(ilon,ilat,level_out) = pat(ilon-lon_n/2,lat_n+1-ilat)
  1044. end do
  1045. else
  1046. ! copy longitudes:
  1047. ll(:,ilat,level_out) = pat(:,lat_n+1-ilat)
  1048. end if
  1049. end do
  1050. case ( gridtype_gg, gridtype_red_gg )
  1051. ! read 2d pat from grib:
  1052. call Get( grib, status, gg=gg(:,level_out) )
  1053. IF_NOTOK_RETURN(status=1)
  1054. ! convert from lnsp to sp ?
  1055. if ( paramkey == 'sp' .and. spm_lnsp2sp ) gg(:,level_out) = exp(gg(:,level_out)) ! Pa
  1056. case ( gridtype_sh )
  1057. ! read 2d pat from grib:
  1058. call Get( grib, status, sh=sh(:,level_out) )
  1059. IF_NOTOK_RETURN(status=1)
  1060. case default
  1061. write (gol,'("unsupported gridtype for 2d pat : ",i6)') gridtype; call goErr
  1062. TRACEBACK; status=1; return
  1063. end select
  1064. ! last record for this field ?
  1065. if ( glevel == nlev ) exit
  1066. end do ! records
  1067. ! close grib file
  1068. call Done( grib, status )
  1069. IF_NOTOK_RETURN(status=1)
  1070. !
  1071. ! ~~~ surface pressure
  1072. !
  1073. SPM: if ( do_spm ) then
  1074. ! read lnsp and covert to sp ?
  1075. if ( spm_lnsp .or. spm_lnsp2sp) then
  1076. spm_levs = levs
  1077. spm_paramkey = 'LNSP'
  1078. else
  1079. spm_levs = 'sfc'
  1080. spm_paramkey = 'SP'
  1081. end if
  1082. !print *, rname//': xxx do_spm = ', do_spm
  1083. !print *, rname//': xxx spm_lnsp ', spm_lnsp, ' spm_lnsp2sp ', spm_lnsp2sp
  1084. !print *, rname//': xxx spm_levs = ', spm_levs
  1085. !print *, rname//': xxx spm_paramkey = ', spm_paramkey
  1086. ! write gribcode:
  1087. call GetPid( 'ec', spm_paramkey, pid, tabid, status )
  1088. IF_NOTOK_RETURN(status=1)
  1089. write (gribcode,'(i3,".128")') pid
  1090. write (gribcode2,'(i3)') pid
  1091. gribcode = adjustl(gribcode)
  1092. gribcode2 = adjustl(gribcode2)
  1093. ! create file name:
  1094. ! dir/od-fc-2000-01-ml60-T159-T_20000101_fg006up4tr3.gb
  1095. write (spm_fname,'(a,"/",a,"-",a,"-",i4.4,2i2.2,"-",a,"-",a,"-",a,"-",a,".gb")') &
  1096. trim(mf%dir), &
  1097. trim(ec_class), trim(ec_type), ccyy, mm, dd, trim(timekey), &
  1098. trim(spm_levs), trim(gribcode), trim(ec_grid)
  1099. ! exist ?
  1100. inquire( file=spm_fname, exist=exist )
  1101. if ( .not. exist ) then
  1102. ! testing ...
  1103. write (gol,'("grib file does not exist:")'); call goPr
  1104. write (gol,'(" ",a)') trim(spm_fname); call goPr
  1105. write (gol,'("...will try another name")'); call goPr
  1106. write (spm_fname,'(a,"/",a,"-",a,"-",i4.4,2i2.2,"-",a,"-",a,"-",a,"-",a,".gb")') &
  1107. trim(mf%dir), &
  1108. trim(ec_class), trim(ec_type), ccyy, mm, dd, trim(timekey), &
  1109. trim(spm_levs), trim(gribcode2), trim(ec_grid)
  1110. inquire( file=spm_fname, exist=exist )
  1111. if (.not. exist) then
  1112. write (gol,'("grib file does not exist:")'); call goErr
  1113. write (gol,'(" ",a)') trim(spm_fname); call goErr
  1114. TRACEBACK; status=1; return
  1115. endif
  1116. end if
  1117. ! open grib file
  1118. call Init( spm_grib, spm_fname, 'r', status )
  1119. IF_NOTOK_RETURN(status=1)
  1120. ! loop over time records
  1121. do
  1122. ! read gribsection in file buffer
  1123. call ReadRecord( spm_grib, status )
  1124. IF_NOTOK_RETURN(status=1)
  1125. ! fill times
  1126. call SetTime( mf, spm_grib, status )
  1127. IF_NOTOK_RETURN(status=1)
  1128. ! check time:
  1129. call CheckTime( mf, tref, t1, t2, status )
  1130. if (status/=0) then
  1131. !write (gol,'("grib read record: spm wrong time; skip ...")'); call goPr
  1132. cycle
  1133. !write (gol,'("found unexpected times in grib file:")'); call goErr
  1134. !write (gol,'(" paramkey : ",a)') paramkey; call goErr
  1135. !call wrtgol( ' req. t1 : ', t1 ); call goErr
  1136. !call wrtgol( ' t2 : ', t2 ); call goErr
  1137. !call wrtgol( ' grib t1 : ', mf%t1 ); call goErr
  1138. !call wrtgol( ' t2 : ', mf%t2 ); call goErr
  1139. !write (gol,'(" grib file : ",a)') trim(spm_fname); call goErr
  1140. !TRACEBACK; status=1; return
  1141. end if
  1142. ! time ok
  1143. exit
  1144. end do ! time loop
  1145. ! set param id:
  1146. select case ( ggridtype )
  1147. case ( gridtype_ll )
  1148. call GetPid( 'ec', 'SP', pid, tabid, status )
  1149. IF_NOTOK_RETURN(status=1)
  1150. case ( gridtype_gg, gridtype_red_gg )
  1151. if ( spm_lnsp2sp ) then
  1152. call GetPid( 'ec', 'LNSP', pid, tabid, status )
  1153. IF_NOTOK_RETURN(status=1)
  1154. else
  1155. call GetPid( 'ec', 'SP', pid, tabid, status )
  1156. IF_NOTOK_RETURN(status=1)
  1157. end if
  1158. case ( gridtype_sh )
  1159. call GetPid( 'ec', 'LNSP', pid, tabid, status )
  1160. IF_NOTOK_RETURN(status=1)
  1161. case default
  1162. write (gol,'("unsupported gridtype for setup sp/lnsp : ",i6)') ggridtype; call goErr
  1163. TRACEBACK; status=1; return
  1164. end select
  1165. ! check parameter:
  1166. call Check( spm_grib, pid=pid, debug=1, status=status )
  1167. IF_NOTOK_RETURN(status=1)
  1168. ! check level:
  1169. call Get( spm_grib, levtype=glevtype, level=glevel, status=status )
  1170. IF_NOTOK_RETURN(status=1)
  1171. select case ( ggridtype )
  1172. case ( gridtype_ll )
  1173. if ( glevtype /= levtype_sfc ) then
  1174. write (gol,'("found unexpected level type ")'); call goErr
  1175. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  1176. write (gol,'(" sfc level type : ",i6)') levtype_sfc; call goErr
  1177. write (gol,'(" grib level type : ",i6)') glevtype; call goErr
  1178. write (gol,'(" grib file : ",a)') trim(spm_fname); call goErr
  1179. TRACEBACK; status=1; return
  1180. end if
  1181. case ( gridtype_gg, gridtype_red_gg )
  1182. if ( spm_lnsp2sp ) then
  1183. if ( (glevtype /= levtype_hyb) .or. (glevel /= 1) ) then
  1184. write (gol,'("found unexpected level type (lnsp for 3d gg)")'); call goErr
  1185. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  1186. write (gol,'(" hyb level type : ",i6)') levtype_hyb; call goErr
  1187. write (gol,'(" grib level type : ",i6)') glevtype; call goErr
  1188. write (gol,'(" grib level : ",i6)') glevel; call goErr
  1189. write (gol,'(" grib file : ",a)') trim(spm_fname); call goErr
  1190. TRACEBACK; status=1; return
  1191. end if
  1192. else
  1193. if ( glevtype /= levtype_sfc ) then
  1194. write (gol,'("found unexpected level type ")'); call goErr
  1195. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  1196. write (gol,'(" sfc level type : ",i6)') levtype_sfc; call goErr
  1197. write (gol,'(" grib level type : ",i6)') glevtype; call goErr
  1198. write (gol,'(" grib file : ",a)') trim(spm_fname); call goErr
  1199. TRACEBACK; status=1; return
  1200. end if
  1201. end if
  1202. case ( gridtype_sh )
  1203. if ( (glevtype /= levtype_hyb) .or. (glevel /= 1) ) then
  1204. write (gol,'("found unexpected level type ")'); call goErr
  1205. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  1206. write (gol,'(" hyb level type : ",i6)') levtype_hyb; call goErr
  1207. write (gol,'(" grib level type : ",i6)') glevtype; call goErr
  1208. write (gol,'(" grib level : ",i6)') glevel; call goErr
  1209. write (gol,'(" grib file : ",a)') trim(spm_fname); call goErr
  1210. TRACEBACK; status=1; return
  1211. end if
  1212. case default
  1213. write (gol,'("unsupported gridtype for sp/lnsp levs : ",i6)') ggridtype; call goErr
  1214. TRACEBACK; status=1; return
  1215. end select
  1216. ! read and store surface pressure field:
  1217. select case ( ggridtype )
  1218. case ( gridtype_ll )
  1219. ! allocate storage
  1220. call pa_SetShape( sp_ll, lon_n, lat_n )
  1221. ! read 2d pat from grib; storred from north to south
  1222. call Get( spm_grib, status, ll=pat )
  1223. IF_NOTOK_RETURN(status=1)
  1224. ! store from south to north:
  1225. do ilat = 1, lat_n
  1226. ! reshuffle ?
  1227. if ( ll_ew_to_we ) then
  1228. ! fill west part:
  1229. do ilon = 1, lon_n/2
  1230. sp_ll(ilon,ilat) = pat(lon_n/2+ilon,lat_n+1-ilat)
  1231. end do
  1232. ! fill east part:
  1233. do ilon = lon_n/2+1, lon_n
  1234. sp_ll(ilon,ilat) = pat(ilon-lon_n/2,lat_n+1-ilat)
  1235. end do
  1236. else
  1237. ! copy longitudes:
  1238. sp_ll(:,ilat) = pat(:,lat_n+1-ilat)
  1239. end if
  1240. end do
  1241. case ( gridtype_gg, gridtype_red_gg )
  1242. ! allocate storage
  1243. call pa_SetShape( sp_gg, ggi%np )
  1244. ! read gg field from grib:
  1245. call Get( spm_grib, status, gg=sp_gg )
  1246. IF_NOTOK_RETURN(status=1)
  1247. ! convert from lnsp to sp ?
  1248. if ( spm_lnsp2sp ) sp_gg = exp(sp_gg) ! Pa
  1249. case ( gridtype_sh )
  1250. ! allocate storage
  1251. call pa_SetShape( lnsp_sh, shi%np )
  1252. ! read spectral coeff:
  1253. call Get( spm_grib, status, sh=lnsp_sh )
  1254. IF_NOTOK_RETURN(status=1)
  1255. case default
  1256. write (gol,'("unsupported gridtype for reading sp/lnsp : ",i6)') ggridtype; call goErr
  1257. TRACEBACK; status=1; return
  1258. end select
  1259. ! close grib file
  1260. call Done( spm_grib, status )
  1261. IF_NOTOK_RETURN(status=1)
  1262. end if SPM
  1263. !
  1264. ! ~~~ done
  1265. !
  1266. call pa_Done( pat ) ! deallocate arrays
  1267. status = 0
  1268. end subroutine mf_ReadRecord_2
  1269. ! ****************************************************************************
  1270. !
  1271. ! In gribfile:
  1272. ! reftime : for example time at which forecast is made
  1273. ! timerange: increment or interval
  1274. !
  1275. ! arguments: ok if:
  1276. !
  1277. ! time1 == time2 time1==time2 == reftime+timerange
  1278. !
  1279. ! time1 == 0 time2 == reftime+timerange
  1280. !
  1281. ! time2 == 0 time1 == reftime
  1282. !
  1283. ! time1 < time2 time1 == refitme, time2 == reftime+timerange
  1284. !
  1285. !
  1286. ! grib [t1-----------t2]
  1287. ! status
  1288. ! o time1/2 record too old 1
  1289. ! o time1/2 ok 0
  1290. ! o time1/2 record too new 2
  1291. !
  1292. !
  1293. ! SetTime( mf, status )
  1294. !
  1295. ! Extracts time values from current grib record,
  1296. ! store in mf%t1, mf%t2
  1297. !
  1298. ! return status:
  1299. ! 0 : ok
  1300. ! other : some error
  1301. !
  1302. ! CheckTime( mf, time1, time2, status )
  1303. !
  1304. ! return status:
  1305. ! 0 : times match
  1306. ! 1 : times do not match, try next record
  1307. ! 2 : current record is newer than requested (reopen ?)
  1308. ! 3 : some error
  1309. !
  1310. ! ***
  1311. !
  1312. ! Return time parameters for grib files:
  1313. ! o tfile : date in filename
  1314. ! o trange : time interval covered by fields in file
  1315. ! o tref : reference time (forecast start?) for tday,[t1,t2]
  1316. !
  1317. ! Called as:
  1318. ! call GetGribTime( treskey, tday, t1, t2, status, tref=tref )
  1319. ! call GetGribTime( treskey, tref, t1, t2, status, tfile=tfile )
  1320. !
  1321. subroutine GetGribTime( treskey, t0, t1, t2, status, tfile, trange, tref, tshift )
  1322. use GO, only : TDate, TIncrDate, Get, Set, wrtgol, NewDate, IncrDate
  1323. use GO, only : operator(+), operator(-), operator(<), rTotal, iTotal
  1324. use GO, only : AnyDate, IsAnyDate
  1325. use GO, only : wrtgol
  1326. ! --- in/out --------------------------------
  1327. character(len=*), intent(in) :: treskey
  1328. type(TDate), intent(in) :: t0, t1, t2
  1329. integer, intent(out) :: status
  1330. type(TDate), intent(out), optional :: tfile
  1331. type(TDate), intent(out), optional :: trange(2)
  1332. type(TDate), intent(out), optional :: tref
  1333. type(TIncrDate), intent(out), optional :: tshift
  1334. ! --- const --------------------------------------
  1335. character(len=*), parameter :: rname = mname//'/GetGribTime'
  1336. ! --- local --------------------------------
  1337. integer :: hour1, hour2, time6(6)
  1338. integer :: dd, hh, step
  1339. integer :: anhh
  1340. real :: ddr
  1341. ! --- begin --------------------------------
  1342. !! testing ...
  1343. !write (gol,'(" GetGribTime: treskey : ",a)') trim(treskey); call goPr
  1344. !call wrtgol( ' GetGribTime: t0 : ', t0 ); call goPr
  1345. !call wrtgol( ' GetGribTime: t1 : ', t1 ); call goPr
  1346. !call wrtgol( ' GetGribTime: t2 : ', t2 ); call goPr
  1347. ! files opened upon reading, thus no particular time range for which file is valid:
  1348. if ( present(trange) ) then
  1349. trange(1) = AnyDate()
  1350. trange(2) = AnyDate()
  1351. end if
  1352. ! zero shift by default
  1353. if ( present(tshift) ) tshift = IncrDate(hour=0)
  1354. ! set day shift, start hour, and step
  1355. select case ( treskey )
  1356. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1357. ! constant field
  1358. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1359. case ( 'const' )
  1360. ! only t0 is usefull ...
  1361. if ( present(tfile ) ) tfile = t0
  1362. !if ( present(trange) ) trange = (/t1,t2/) ! any, any
  1363. if ( present(tref ) ) tref = t0 ! dummy ...
  1364. ! take analysed fields always at least 24 hour old,
  1365. ! since these are the only analysed fields available in forecast mode
  1366. if ( present(tshift) ) then
  1367. !tshift = IncrDate(hour=24)
  1368. ! FIX for start of ml91 test suite; try if 12 is ok too ...
  1369. !AJS>>> ea test:
  1370. ! tshift = IncrDate(hour=12)
  1371. tshift = IncrDate(hour=24)
  1372. !AJS<<<
  1373. end if
  1374. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1375. ! fc, 3/6 hourly
  1376. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1377. case ( '_03p03', '_06p06' )
  1378. ! extract end hour:
  1379. call Get( t2, hour=hour2 )
  1380. ! set forecast start time and step given hour:
  1381. select case ( hour2 )
  1382. case ( 00 ) ; dd = -1 ; hh = 00 ; step = 24
  1383. case ( 03 ) ; dd = 0 ; hh = 00 ; step = 3
  1384. case ( 06 ) ; dd = 0 ; hh = 00 ; step = 6
  1385. case ( 09 ) ; dd = 0 ; hh = 00 ; step = 9
  1386. case ( 12 ) ; dd = 0 ; hh = 00 ; step = 12
  1387. case ( 15 ) ; dd = 0 ; hh = 00 ; step = 15
  1388. case ( 18 ) ; dd = 0 ; hh = 00 ; step = 18
  1389. case ( 21 ) ; dd = 0 ; hh = 00 ; step = 21
  1390. case default
  1391. write (gol,'("unsupported hour :")'); call goErr
  1392. write (gol,'(" hour2 : ",i2)') hour2; call goErr
  1393. write (gol,'(" timesteps : ",a )') treskey; call goErr
  1394. call wrtgol( ' time1 : ', t1 ); call goErr
  1395. write (gol,'("in ",a)') rname; call goErr; status=1; return
  1396. end select
  1397. ! file ccyymmdd contains fields for (00,24] :
  1398. if ( present(tfile) ) then
  1399. ! current day by default:
  1400. tfile = t2
  1401. call Set( tfile, hour=0, min=0, sec=0, mili=0 ) ! 00:00
  1402. ! trap (..,00:00], this should be previous day:
  1403. call Get( t2, time6=time6 )
  1404. if ( all(time6(4:6)==0) ) tfile = tfile - IncrDate(day=1)
  1405. end if
  1406. ! fields valid for (00,24] :
  1407. if ( present(trange) ) then
  1408. trange(1) = t2
  1409. call Set( trange(1), hour=0, min=0, sec=0, mili=0 ) ! 00:00
  1410. ! trap 00:00, this should be previous day:
  1411. call Get( t2, time6=time6 )
  1412. if ( all(time6(4:6)==0) ) trange(1) = trange(1) - IncrDate(day=1)
  1413. ! complete (00,24]
  1414. trange(2) = trange(1) + IncrDate(day=1) ! 24:00
  1415. call Set( trange(1), mili=1 ) ! > 00:00
  1416. end if
  1417. ! reference time = start of forecast
  1418. if ( present(tref) ) then
  1419. call Get( t2, time6=time6 )
  1420. tref = NewDate( time6=time6 )
  1421. time6(4:6) = 0
  1422. tref = NewDate( time6=time6 ) + IncrDate( day=dd, hour=hh )
  1423. end if
  1424. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1425. ! fc, 3 hourly
  1426. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1427. case ( '_fc012up2tr3' )
  1428. ! end hour counted from t0 00:00
  1429. hour2 = iTotal( t2 - t0, 'hour' )
  1430. ! set forecast start time and step given hour:
  1431. if ( hour2 == 0 ) then
  1432. ! 00:00 fc day 0
  1433. dd = -1 ; hh = 12 ; step = 12
  1434. else if ( (hour2 <= 12) .and. (modulo(hour2,3) == 0) ) then
  1435. ! (00,12] fc day 0
  1436. dd = 0
  1437. hh = 00
  1438. step = hour2
  1439. else if ( ( (t0 < NewDate(year=2006,month=03,day=14) ) .and. &
  1440. ( ((hour2 <= 12+ 72) .and. (modulo(hour2,3) == 0)) .or. &
  1441. ((hour2 <= 12+240) .and. (modulo(hour2,6) == 0)) ) ) &
  1442. .or. ( ( ((hour2 <= 12+ 96) .and. (modulo(hour2,3) == 0)) .or. &
  1443. ((hour2 <= 12+240) .and. (modulo(hour2,6) == 0)) ) ) ) then
  1444. ! (12,240] fc days 1-10
  1445. dd = 0
  1446. hh = 12
  1447. step = hour2 - 12
  1448. else
  1449. write (gol,'("unsupported hour :")'); call goErr
  1450. write (gol,'(" hour2 : ",i3)') hour2; call goErr
  1451. write (gol,'(" treskey : ",a )') treskey; call goErr
  1452. call wrtgol( ' time1 : ', t1 ); call goErr
  1453. write (gol,'("in ",a)') rname; call goErr; status=1; return
  1454. end if
  1455. !! fields valid for hh+(00,12] :
  1456. !if ( present(trange) ) then
  1457. ! trange(1) = t2
  1458. ! call Set( trange(1), hour=hh, min=0, sec=0, mili=0 ) ! hh:00
  1459. ! ! trap 00:00, this should be previous day:
  1460. ! call Get( t2, time6=time6 )
  1461. ! if ( all(time6(4:6)==0) ) trange(1) = trange(1) - IncrDate(day=1)
  1462. ! ! complete (00,12]
  1463. ! trange(2) = trange(1) + IncrDate(hour=12) ! 24:00
  1464. ! call Set( trange(1), mili=1 ) ! > 00:00
  1465. !end if
  1466. ! reference time = start of forecast
  1467. if ( present(tref) ) then
  1468. tref = t0 + IncrDate(day=dd,hour=hh)
  1469. end if
  1470. ! adhoc: if tfile is requested, probably the 'tref' returned before
  1471. ! is now in input 't0' ...
  1472. if ( present(tfile) ) then
  1473. tfile = t0 ! .. is tref !
  1474. end if
  1475. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1476. ! fc, 3 hourly or 1 hourl; base times 06:00 and 18:00
  1477. ! archived fields at 1 hour resolution?
  1478. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1479. case ( '_h06h18tr3', '_h06h18tr1' )
  1480. ! end hour counted from t0 00:00
  1481. hour2 = iTotal( t2 - t0, 'hour' )
  1482. ! set forecast start time and step given hour:
  1483. if ( hour2 <= 6 ) then
  1484. ! [00:00,06:00] fc day 0
  1485. dd = -1
  1486. hh = 18
  1487. step = 6+hour2
  1488. else if ( hour2 <= 18 ) then
  1489. ! (06,18] fc day 0
  1490. dd = 0
  1491. hh = 6
  1492. step = hour2-6
  1493. else if ( hour2 <= 24 ) then
  1494. ! (18,24] fc day 0
  1495. dd = 0
  1496. hh = 18
  1497. step = hour2-18
  1498. else
  1499. write (gol,'("unsupported hour :")'); call goErr
  1500. write (gol,'(" hour2 : ",i3)') hour2; call goErr
  1501. write (gol,'(" treskey : ",a )') treskey; call goErr
  1502. call wrtgol( ' time1 : ', t1 ); call goErr
  1503. write (gol,'("in ",a)') rname; call goErr; status=1; return
  1504. end if
  1505. !! fields valid for hh+(00,12] :
  1506. !if ( present(trange) ) then
  1507. ! trange(1) = t2
  1508. ! call Set( trange(1), hour=hh, min=0, sec=0, mili=0 ) ! hh:00
  1509. ! ! trap 00:00, this should be previous day:
  1510. ! call Get( t2, time6=time6 )
  1511. ! if ( all(time6(4:6)==0) ) trange(1) = trange(1) - IncrDate(day=1)
  1512. ! ! complete (00,12]
  1513. ! trange(2) = trange(1) + IncrDate(hour=12) ! 24:00
  1514. ! call Set( trange(1), mili=1 ) ! > 00:00
  1515. !end if
  1516. ! reference time = start of forecast
  1517. if ( present(tref) ) then
  1518. tref = t0 + IncrDate(day=dd,hour=hh)
  1519. end if
  1520. ! adhoc: if tfile is requested, probably the 'tref' returned before
  1521. ! is now in input 't0' ...
  1522. if ( present(tfile) ) then
  1523. tfile = t0 ! .. is tref !
  1524. end if
  1525. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1526. ! analysis, files for hours 0, 6, 12, and 18,
  1527. ! or files for hous 00,..,23
  1528. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1529. case ( '_an0tr6', '_an0tr1' )
  1530. ! reference time = analysis time
  1531. if ( present(tref) ) then
  1532. tref = t1
  1533. end if
  1534. ! t0 t1,t2 ->
  1535. ! -+-----------------------+-----------------------+--->
  1536. ! 00 06 12 18 00 06 12 18 00
  1537. ! a
  1538. ! a a
  1539. ! a a(-----------] 00 analysis/forecast
  1540. ! a a(--------------> 12 forecast
  1541. !
  1542. ! -24 -24 -24 -24 -48 shift
  1543. ! take analysed fields always at least 24 hour old,
  1544. ! since these are the only analysed fields available in forecast mode,
  1545. ! and to obtain a contineous time line
  1546. ! t0 is always 00:00
  1547. if ( present(tshift) ) then
  1548. ! difference between t1 and t0 00:00 in fraction of days:
  1549. ddr = rTotal( t1 - t0, 'day' )
  1550. ! set time shift in days:
  1551. tshift = IncrDate(day=floor(ddr)+1)
  1552. !! FIX for start of ml91 test suite; try if 12 is ok too ...
  1553. !tshift = IncrDate(day=floor(ddr),hour=12)
  1554. end if
  1555. ! one file for each time:
  1556. if ( present(tfile) ) then
  1557. tfile = t1
  1558. end if
  1559. !! fields in file valid for instant time:
  1560. !if ( present(trange) ) then
  1561. ! trange(1) = t1
  1562. ! trange(2) = t1
  1563. !end if
  1564. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1565. ! fc, 1 hourly emissions
  1566. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1567. case ( '_fc000up24tr1' )
  1568. ! macc emisisons
  1569. ! fields in grib file have time stamps 00:30, 01:30, etc
  1570. ! reference time = start of forecast
  1571. if ( present(tref) ) then
  1572. ! end hour counted from t0 00:00
  1573. hour2 = iTotal( t2 - t0, 'hour' )
  1574. ! field from current day, 'forecast time' 00:30 etc:
  1575. tref = t0 + IncrDate(day=0,hour=hour2-1,min=30)
  1576. ! no steps in this timing convention:
  1577. step = 0
  1578. !! debug ...
  1579. !write (gol,*) ' GetGribTime: dd, hh, step : ', dd, hh, step; call goPr
  1580. !call wrtgol( ' GetGribTime: set tref to : ', tref ); call goPr
  1581. end if
  1582. ! adhoc: if tfile is requested, probably the 'tref' returned before
  1583. ! is now in input 't0' ...
  1584. if ( present(tfile) ) then
  1585. tfile = t0 ! .. is tref !
  1586. !! debug ...
  1587. !call wrtgol( ' GetGribTime: set tfile to : ', tfile ); call goPr
  1588. end if
  1589. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1590. ! fc, daily emissions
  1591. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1592. case ( '_fc000up1tr24' )
  1593. ! macc emisisons
  1594. ! fields in grib file have time stamp 12:00
  1595. ! reference time = start of forecast ;
  1596. ! her always 12:00 of current day:
  1597. if ( present(tref) ) then
  1598. ! reference time is 12:00 on day including [t1,t2],
  1599. ! thus simply use t1 and reset some values:
  1600. tref = t1
  1601. call Set( tref, hour=12, min=0, sec=0 )
  1602. end if
  1603. ! time in file is the day including [t1,t2] too:
  1604. if ( present(tfile) ) then
  1605. tfile = t1
  1606. call Set( tfile, hour=12, min=0, sec=0 )
  1607. end if
  1608. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1609. ! ???
  1610. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1611. case default
  1612. write (gol,'("unsupported time resolution key:")'); call goErr
  1613. write (gol,'(" `",a,"`")') trim(treskey); call goErr
  1614. TRACEBACK; status=1; return
  1615. end select
  1616. ! ok
  1617. status = 0
  1618. end subroutine GetGribTime
  1619. ! ***
  1620. !
  1621. ! Extract time fields of current grib record,
  1622. ! and store them in mf%tref, mf%t1, mf%t2
  1623. !
  1624. subroutine SetTime( mf, grib, status )
  1625. use GO, only : TDate, NewDate, IncrDate, operator(+), wrtgol
  1626. use file_grib, only : TGribFile, Get
  1627. ! --- const -------------------------------------
  1628. character(len=*), parameter :: rname = mname//'/SetTime'
  1629. ! --- in/out -------------------------------
  1630. type(TMeteoFile_ecmwf_tm5), intent(inout) :: mf
  1631. type(TGribFile), intent(inout) :: grib
  1632. integer, intent(out) :: status
  1633. ! --- local -------------------------------
  1634. integer :: reftime(5), timerange(4)
  1635. ! --- begin -------------------------------
  1636. ! extract time fields from grib record:
  1637. call Get( grib, status, reftime=reftime, timerange=timerange )
  1638. IF_NOTOK_RETURN(status=1)
  1639. ! Fill t1 and t2 with the time information; might be equal.
  1640. ! Check time range indicator (WMO code table 5):
  1641. select case ( timerange(4) )
  1642. case ( 0, 1 )
  1643. !
  1644. ! 0 = Forecast product valid for reference time + P1 (P1>0),
  1645. ! or uninitialized analysis product for reference time (P1=0)
  1646. !
  1647. ! 1 = Initialized analysis product for reference time (P1=0).
  1648. !
  1649. ! fill reference time:
  1650. mf%tref = NewDate( time5=reftime )
  1651. ! fill t1 with reftime+timerange;
  1652. ! add P1 in hours; check time unit (WMO code table 4)
  1653. mf%t1 = NewDate( time5=reftime )
  1654. select case ( timerange(1) )
  1655. case ( 1 ) ! hours
  1656. mf%t1 = mf%t1 + IncrDate( hour=timerange(2) )
  1657. case default
  1658. write (gol,'("grib timerange units other than hours not supported yet")'); call goErr
  1659. write (gol,'(" reftime : ",i4,4i3)') reftime; call goErr
  1660. write (gol,'(" timerange : ",4i3)') timerange; call goErr
  1661. write (gol,'(" file : ",a)') trim(grib%fname); call goErr
  1662. TRACEBACK; status=1; return
  1663. end select
  1664. ! instant time:
  1665. mf%t2 = mf%t1
  1666. case ( 2 )
  1667. !
  1668. ! 2 = Product with a valid time ranging between
  1669. ! reference time + P1 and reference time + P2
  1670. !
  1671. ! fill reftime:
  1672. mf%tref = NewDate( time5=reftime )
  1673. ! fill t1 with reftime+P1;
  1674. ! add P1 in hours; check time unit (WMO code table 4)
  1675. mf%t1 = mf%tref
  1676. select case ( timerange(1) )
  1677. case ( 1 ) ! hours
  1678. mf%t1 = mf%t1 + IncrDate( hour=timerange(2) )
  1679. case default
  1680. write (gol,'("grib timerange units other than hours not supported yet")'); call goErr
  1681. write (gol,'(" file : ",a)') trim(grib%fname); call goErr
  1682. TRACEBACK; status=1; return
  1683. end select
  1684. ! fill t2 with reftime+P2;
  1685. ! add P2 in hours; check time unit (WMO code table 4)
  1686. mf%t2 = mf%tref
  1687. select case ( timerange(1) )
  1688. case ( 1 ) ! hours
  1689. mf%t2 = mf%t2 + IncrDate( hour=timerange(3) )
  1690. case default
  1691. write (gol,'("grib timerange units other than hours not supported yet")'); call goErr
  1692. write (gol,'(" file : ",a)') trim(grib%fname); call goErr
  1693. TRACEBACK; status=1; return
  1694. end select
  1695. case default
  1696. write (gol,'("unsupported time range indicator:")'); call goErr
  1697. write (gol,'(" indicator : ",i6)') timerange(4); call goErr
  1698. write (gol,'(" file : ",a)') trim(grib%fname); call goErr
  1699. TRACEBACK; status=1; return
  1700. end select
  1701. ! ok
  1702. status = 0
  1703. end subroutine SetTime
  1704. ! ***
  1705. subroutine CheckTime( mf, tref, t1, t2, status )
  1706. use GO
  1707. use file_grib, only : Get
  1708. ! --- const -------------------------------------
  1709. character(len=*), parameter :: rname = mname//'/CheckTime'
  1710. ! --- in/out -------------------------------
  1711. type(TMeteoFile_ecmwf_tm5), intent(in) :: mf
  1712. type(TDate), intent(in) :: tref, t1, t2
  1713. integer, intent(out) :: status
  1714. ! --- local -------------------------------
  1715. integer :: year1, year2
  1716. ! --- begin -------------------------------
  1717. !call wrtgol( 'CheckTime: (', tref, ') ', t1, ' - ', t2 ); call goPr
  1718. !call wrtgol( 'CheckTime: (', mf%tref, ') ', mf%t1, ' - ', mf%t2 ); call goPr
  1719. ! requested year zero ? always ok
  1720. call Get( t1, year=year1 )
  1721. call Get( t2, year=year2 )
  1722. if ( (year1 == 0) .and. (year2 == 0) ) then
  1723. ! requested constant field, always ok
  1724. status = 0; return ! ok
  1725. end if
  1726. if ( year1 == 0 ) then
  1727. ! do not test t1, only t2
  1728. if ( t2 == mf%t2 ) then
  1729. status = 0; return ! ok
  1730. else
  1731. status = 1; return ! not ok, try next
  1732. end if
  1733. else if ( year2 == 0 ) then
  1734. ! do not test t2, only t1
  1735. if ( t1 == mf%t1 ) then
  1736. status = 0; return ! ok
  1737. else
  1738. status = 1; return ! not ok, try next
  1739. end if
  1740. end if
  1741. ! ! interval or instant time
  1742. ! if ( t1 < t2 ) then
  1743. !
  1744. ! !! time interval: [t1,t2] should be inside [t1,t2]
  1745. ! !if ( (t1 >= mf%t1) .and. (t2 <= mf%t2) ) then
  1746. ! ! status = 0; return ! ok
  1747. ! !else
  1748. ! ! status = 1; return ! try next
  1749. ! !end if
  1750. !
  1751. ! ! time interval: [t1,t2] should be equal to [t1,t2]
  1752. ! if ( (t1 == mf%t1) .and. (t2 == mf%t2) ) then
  1753. ! status = 0; return ! ok
  1754. ! else
  1755. ! status = 1; return ! try next
  1756. ! end if
  1757. !
  1758. ! else if ( t1 == t2 ) then
  1759. !
  1760. ! ! instant time: t2 should match t2
  1761. ! if ( t2 == mf%t2 ) then
  1762. ! status = 0; return ! ok
  1763. ! else
  1764. ! status = 1; return ! try next
  1765. ! end if
  1766. !
  1767. ! else
  1768. !
  1769. ! write (gol,'("t1 should not exceed t2:")'); call goErr
  1770. ! call wrtgol( ' t1 : ', t1 ); call goErr
  1771. ! call wrtgol( ' t2 : ', t2 ); call goErr
  1772. ! TRACEBACK; status=3; return
  1773. !
  1774. ! end if
  1775. ! compare all:
  1776. if ( (tref == mf%tref) .and. (t1 == mf%t1) .and. (t2 == mf%t2) ) then
  1777. status = 0; return ! ok
  1778. else
  1779. status = 1; return ! try next
  1780. end if
  1781. ! some error ...
  1782. status = 1
  1783. end subroutine CheckTime
  1784. end module tmm_mf_ecmwf_tm5