tmm_mf_ecmwf_tmpp.F90 58 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778
  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_tmpp
  15. use GO , only : gol, goErr, goPr
  16. use GO , only : TDate
  17. use file_grib, only : TGribFile
  18. implicit none
  19. ! --- in/out ----------------------------
  20. private
  21. public :: TMeteoFile_ecmwf_tmpp
  22. public :: Init, Done
  23. public :: Get
  24. public :: ReadRecord
  25. ! --- const ------------------------------
  26. character(len=*), parameter :: mname = 'tmm_mf_ecmwf_tmpp'
  27. !--- type ---------------------------------
  28. type TMeteoFile_ecmwf_tmpp
  29. ! file name:
  30. character(len=256) :: fname
  31. ! time range covered by file:
  32. type(TDate) :: trange(2)
  33. logical :: constant
  34. ! other time keys for this file:
  35. character(len=16) :: treskey
  36. type(TDate) :: tday
  37. ! current time range covered by grib record:
  38. type(TDate) :: tref, t1, t2
  39. !
  40. ! file description
  41. !
  42. character(len=16) :: ec_class, ec_type
  43. character(len=256) :: paramkeys
  44. !
  45. ! 3d field
  46. !
  47. type(TGribFile) :: grib
  48. !
  49. ! surface pressure field
  50. !
  51. logical :: do_spm
  52. character(len=256) :: spm_fname
  53. type(TGribFile) :: spm_grib
  54. logical :: spm_lnsp2sp
  55. !
  56. end type TMeteoFile_ecmwf_tmpp
  57. ! --- interfaces -------------------------
  58. interface Init
  59. module procedure mf_Init
  60. end interface
  61. interface Done
  62. module procedure mf_Done
  63. end interface
  64. interface Get
  65. module procedure mf_Get
  66. end interface
  67. interface ReadRecord
  68. module procedure mf_ReadRecord
  69. end interface
  70. contains
  71. ! ==============================================================
  72. ! ====
  73. ! ==== original
  74. ! ====
  75. ! ==============================================================
  76. subroutine mf_Init( mf, dir, archivekeys, paramkey, &
  77. tday, t1, t2, status )
  78. use GO, only : TDate, Get, NewDate, operator(>)
  79. use GO, only : goVarValue, goWriteKeyNum
  80. ! --- in/out ----------------------------
  81. type(TMeteoFile_ecmwf_tmpp), intent(out) :: mf
  82. character(len=*), intent(in) :: dir
  83. character(len=*), intent(in) :: archivekeys
  84. character(len=*), intent(in) :: paramkey
  85. type(TDate), intent(in) :: tday, t1, t2
  86. integer, intent(out) :: status
  87. ! --- const --------------------------------------
  88. character(len=*), parameter :: rname = mname//'/mf_Init'
  89. ! --- local --------------------------------
  90. character(len=16) :: form
  91. character(len=16) :: ec_class, ec_type, ec_tres, ec_levs, mfile
  92. integer :: ec_sh, ec_gg
  93. character(len=16) :: grid, gridN, gridT
  94. character(len=16) :: levs
  95. character(len=16) :: spm_tres
  96. type(TDate) :: tfile
  97. integer :: ccyy, mm, dd
  98. type(TDate) :: tc
  99. logical :: exist
  100. ! --- begin --------------------------------
  101. !
  102. ! extract fields from archivekey :
  103. ! form=tmpp;class=od;type=fg;nlev=60;sh=159;gg=80;tres=_fg006up4tr3
  104. !
  105. form = 'tmpp'
  106. call goVarValue( archivekeys, ';', 'form', '=', form, status )
  107. IF_ERROR_RETURN(status=1)
  108. !
  109. ec_class = 'od'
  110. call goVarValue( archivekeys, ';', 'class', '=', ec_class, status )
  111. IF_ERROR_RETURN(status=1)
  112. !
  113. ec_type = 'fc'
  114. call goVarValue( archivekeys, ';', 'type', '=', ec_type, status )
  115. IF_ERROR_RETURN(status=1)
  116. !
  117. ec_levs = 'ml60'
  118. call goVarValue( archivekeys, ';', 'levs', '=', ec_levs, status )
  119. IF_ERROR_RETURN(status=1)
  120. !
  121. ec_sh = 159
  122. call goVarValue( archivekeys, ';', 'sh', '=', ec_sh, status )
  123. IF_ERROR_RETURN(status=1)
  124. !
  125. ec_gg = 80
  126. call goVarValue( archivekeys, ';', 'gg', '=', ec_gg, status )
  127. IF_ERROR_RETURN(status=1)
  128. !
  129. ec_tres = ''
  130. call goVarValue( archivekeys, ';', 'tres', '=', ec_tres, status )
  131. IF_ERROR_RETURN(status=1)
  132. ! >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
  133. ! fg data available up to 2000-09-12 00:00 ; after, use fc data:
  134. if ( ec_tres == '_fg006up4tr3' ) then
  135. tc = NewDate( 2000, 09, 12, 00, 00, 00 )
  136. if ( t1 > tc ) then
  137. write (gol,'(" WARNING - using fc data after 2000-09-12 00:00")'); call goPr
  138. ec_type = 'fc'
  139. ec_tres = '_fc012up2tr3'
  140. end if
  141. end if
  142. ! <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
  143. ! store some values ...
  144. mf%ec_class = ec_class
  145. mf%ec_type = ec_type
  146. !
  147. ! meteo file
  148. !
  149. ! grid : T159, N80, etc
  150. call goWriteKeyNum( gridT, 'T', ec_sh )
  151. call goWriteKeyNum( gridN, 'N', ec_gg )
  152. ! defaults
  153. levs = ec_levs
  154. grid = 'Xxx'
  155. mfile = trim(paramkey)
  156. mf%paramkeys = '-'//trim(paramkey)//'-'
  157. mf%constant = .false.
  158. mf%do_spm = .false.
  159. mf%spm_fname = 'none'
  160. mf%spm_lnsp2sp = .false.
  161. spm_tres = ec_tres
  162. ! specials
  163. select case ( paramkey )
  164. case ( 'LNSP' )
  165. levs = 'ml1'
  166. grid = gridT
  167. if ( form /= '3hr' ) ec_tres = '_03p03'
  168. case ( 'VO', 'D' )
  169. mfile = 'VOD'
  170. mf%paramkeys = '-VO-D-'
  171. grid = gridT
  172. mf%do_spm = .true.
  173. spm_tres = '_03p03'
  174. if ( form == '3hr' ) then
  175. mfile = paramkey
  176. mf%paramkeys = '-'//trim(paramkey)//'-'
  177. spm_tres = ec_tres
  178. end if
  179. case ( 'T', 'W' )
  180. grid = gridT
  181. mf%do_spm = .true.
  182. spm_tres = '_03p03'
  183. if ( form == '3hr' ) then
  184. spm_tres = ec_tres
  185. end if
  186. case ( 'Q' )
  187. grid = gridN
  188. mf%do_spm = .true.
  189. spm_tres = '_03p03'
  190. mf%spm_lnsp2sp = .true.
  191. if ( form == '3hr' ) then
  192. spm_tres = ec_tres
  193. end if
  194. case ( 'CLWC', 'CIWC', 'CC', 'CCO', 'CCU' )
  195. grid = gridN
  196. mfile = 'CLD'
  197. mf%paramkeys = '-CLWC-CIWC-CC-CCO-CCU-'
  198. mf%do_spm = .true.
  199. spm_tres = '_03p03'
  200. mf%spm_lnsp2sp = .true.
  201. if ( form == '3hr' ) then
  202. spm_tres = ec_tres
  203. end if
  204. case ( 'oro' )
  205. levs = 'sfc'
  206. grid = gridN
  207. mf%constant = .true.
  208. ec_tres = 'const'
  209. case ( 'lsm' )
  210. levs = 'sfc'
  211. grid = gridN
  212. mf%constant = .true.
  213. case ( 'cvl', 'cvh', 'tvl', 'tvh', 'sr', 'al', 'lsrh' )
  214. ec_type = 'an'
  215. levs = 'sfc'
  216. grid = gridN
  217. mfile = 'S0'
  218. mf%paramkeys = '-cvl-cvh-tvl-tvh-sr-al-lsrh-'
  219. ec_tres = '_06p06'
  220. case ( 'ci', 'swvl1', 'swvl2', 'swvl3', 'swvl4', '10fg', 'sd', 'lsp', &
  221. 'cp', 'sf', 'sshf', 'slhf', 'blh', 'u10m', 'v10m', 't2m', 'd2m', &
  222. 'ssr', 'ewss', 'nsss', 'sstr' ,'src' )
  223. levs = 'sfc'
  224. grid = gridN
  225. mfile = 'S1'
  226. mf%paramkeys = '-'
  227. mf%paramkeys = trim(mf%paramkeys)//'ci-swvl1-swvl2-swvl3-swvl4-10fg-sd-lsp-'
  228. mf%paramkeys = trim(mf%paramkeys)//'cp-sf-sshf-slhf-blh-10u-10v-2t-2d-'
  229. mf%paramkeys = trim(mf%paramkeys)//'ssr-ewss-nsss-sstr-src-'
  230. ec_tres = '_03p03'
  231. end select
  232. ! convert input times to file name times:
  233. call GetGribTime( ec_tres, tday, t1, t2, status, tfile=tfile, trange=mf%trange )
  234. IF_NOTOK_RETURN(status=1)
  235. ! store some time params
  236. mf%treskey = ec_tres
  237. if ( ec_type == 'an' ) mf%treskey = 'an'//ec_tres
  238. mf%tday = tday
  239. ! create file name:
  240. ! dir/od-fc-2000-01-ml60-T159-T_20000101_fg006up4tr3.gb
  241. select case ( paramkey )
  242. case ( 'oro' )
  243. write (mf%fname,'(a,"/",a,"-",a,"-",i4.4,"-",i2.2,"-",a,"-",a,"-",a,a)') &
  244. trim(dir), &
  245. trim(ec_class), trim(ec_type), 0000, 00, trim(levs), trim(grid), &
  246. 'Z', '.gb'
  247. case ( 'lsm' )
  248. write (mf%fname,'(a,"/",a,"-",a,"-",i4.4,"-",i2.2,"-",a,"-",a,"-",a,a)') &
  249. trim(dir), &
  250. trim(ec_class), trim(ec_type), 0000, 00, trim(levs), trim(grid), &
  251. 'LSM', '.gb'
  252. case default
  253. ! extract time values:
  254. call Get( tfile, year=ccyy, month=mm, day=dd )
  255. ! path and file include date:
  256. write (mf%fname,'(a,"/",a,"-",a,"-",i4.4,"-",i2.2,"-",a,"-",a,"-",a,"_",i4.4,2i2.2,a,a)') &
  257. trim(dir), &
  258. trim(ec_class), trim(ec_type), ccyy, mm, trim(levs), trim(grid), &
  259. trim(mfile), ccyy, mm, dd, trim(ec_tres), '.gb'
  260. end select
  261. ! exist ?
  262. inquire( file=mf%fname, exist=exist )
  263. if ( .not. exist ) then
  264. write (gol,'("grib file does not exist:")'); call goErr
  265. write (gol,'(" ",a)') trim(mf%fname); call goErr
  266. write (gol,'("in ",a)') rname; call goErr; status=1; return
  267. end if
  268. !
  269. ! sp or lnsp ?
  270. !
  271. if ( mf%do_spm ) then
  272. ! grid : T159
  273. grid = gridT
  274. ! levels: ml1
  275. levs = 'ml1'
  276. ! create file name:
  277. ! dir/od-fc-2000-01-ml60-T159-T_20000101_fg006up4tr3.gb
  278. write (mf%spm_fname,'(a,"/",a,"-",a,"-",i4.4,"-",i2.2,"-",a,"-",a,"-",a,"_",i4.4,2i2.2,a,a)') &
  279. trim(dir), &
  280. trim(ec_class), trim(ec_type), ccyy, mm, trim(levs), trim(grid), &
  281. 'LNSP', ccyy, mm, dd, trim(spm_tres), '.gb'
  282. ! exist ?
  283. inquire( file=mf%spm_fname, exist=exist )
  284. if ( .not. exist ) then
  285. write (gol,'("grib file does not exist:")'); call goErr
  286. write (gol,'(" ",a)') trim(mf%spm_fname); call goErr
  287. write (gol,'("in ",a)') rname; call goErr; status=1; return
  288. end if
  289. end if
  290. ! ok
  291. status = 0
  292. end subroutine mf_Init
  293. ! ***
  294. subroutine mf_Done( mf, status )
  295. use file_grib, only : Done
  296. ! --- in/out ------------------------------------
  297. type(TMeteoFile_ecmwf_tmpp), intent(inout) :: mf
  298. integer, intent(out) :: status
  299. ! --- const --------------------------------------
  300. character(len=*), parameter :: rname = mname//'/mf_Done'
  301. ! --- begin -------------------------------------
  302. ! nothing to be done ...
  303. ! ok
  304. status = 0
  305. end subroutine mf_Done
  306. ! ***
  307. subroutine mf_Get( mf, status, trange1, trange2, paramkeys )
  308. use GO, only : TDate
  309. ! --- in/out ----------------------------
  310. type(TMeteoFile_ecmwf_tmpp), intent(in) :: mf
  311. integer, intent(out) :: status
  312. type(TDate), intent(out), optional :: trange1, trange2
  313. character(len=*), intent(out), optional :: paramkeys
  314. ! --- const --------------------------------------
  315. character(len=*), parameter :: rname = mname//'/mf_Get'
  316. ! --- local --------------------------------
  317. ! --- begin --------------------------------
  318. ! time range:
  319. if ( present(trange1) ) trange1 = mf%trange(1)
  320. if ( present(trange2) ) trange2 = mf%trange(2)
  321. ! contents:
  322. if ( present(paramkeys) ) paramkeys = trim(mf%paramkeys)
  323. ! ok
  324. status = 0
  325. end subroutine mf_Get
  326. ! ***
  327. subroutine mf_ReadRecord( mf, paramkey, t1, t2, nuv, nw, &
  328. gridtype, levi, &
  329. lli, ll, sp_ll, &
  330. ggi, gg, sp_gg, &
  331. shi, sh, lnsp_sh, &
  332. tmi, status )
  333. use parray , only : pa_Init, pa_Done
  334. use GO , only : TDate
  335. use Grid , only : TLevelInfo
  336. use Grid , only : TllGridInfo, TggGridInfo, TshGridInfo
  337. use tmm_info , only : TMeteoInfo
  338. ! --- in/out -------------------------------
  339. type(TMeteoFile_ecmwf_tmpp), intent(inout) :: mf
  340. character(len=*), intent(in) :: paramkey
  341. type(TDate), intent(in) :: t1, t2
  342. character(len=1), intent(in) :: nuv
  343. character(len=1), intent(in) :: nw
  344. character(len=2), intent(out) :: gridtype
  345. type(TLevelInfo), intent(out) :: levi
  346. type(TllGridInfo), intent(inout) :: lli
  347. real, pointer :: ll(:,:,:)
  348. real, pointer :: sp_ll(:,:)
  349. type(TggGridInfo), intent(inout) :: ggi
  350. real, pointer :: gg(:,:)
  351. real, pointer :: sp_gg(:)
  352. type(TshGridInfo), intent(inout) :: shi
  353. complex, pointer :: sh(:,:)
  354. complex, pointer :: lnsp_sh(:)
  355. type(TMeteoInfo), intent(out) :: tmi
  356. integer, intent(out) :: status
  357. ! --- const --------------------------------------
  358. character(len=*), parameter :: rname = mname//'/mf_ReadRecord'
  359. ! --- local -------------------------------
  360. real, pointer :: ll2(:,:,:)
  361. real, pointer :: gg2(:,:)
  362. complex, pointer :: sh2(:,:)
  363. ! --- begin ---------------------------------
  364. ! combined field ?
  365. select case ( paramkey )
  366. case ( 'sstr' )
  367. ! read first field:
  368. call mf_ReadRecord_1( mf, 'ewss', t1, t2, nuv, nw, &
  369. gridtype, levi, &
  370. lli, ll, sp_ll, &
  371. ggi, gg, sp_gg, &
  372. shi, sh, lnsp_sh, &
  373. tmi, status )
  374. IF_NOTOK_RETURN(status=1)
  375. ! init pointer:
  376. call pa_Init( ll2 )
  377. call pa_Init( gg2 )
  378. call pa_Init( sh2 )
  379. ! read second field:
  380. call mf_ReadRecord_1( mf, 'nsss', t1, t2, nuv, nw, &
  381. gridtype, levi, &
  382. lli, ll2, sp_ll, &
  383. ggi, gg2, sp_gg, &
  384. shi, sh2, lnsp_sh, &
  385. tmi, status )
  386. IF_NOTOK_RETURN(status=1)
  387. ! process:
  388. select case ( gridtype )
  389. case ( 'll' ) ; ll = sqrt( ll**2 + ll2**2 )
  390. case ( 'gg' ) ; gg = sqrt( gg**2 + gg2**2 )
  391. case ( 'sh' ) ; sh = sqrt( sh**2 + sh2**2 )
  392. case default
  393. write (gol,'("unsupported gridtype for substract :",a)') gridtype; call goErr
  394. write (gol,'("in ",a)') rname; call goErr; status=1; return
  395. end select
  396. ! clear pointers:
  397. call pa_Done( ll2 )
  398. call pa_Done( gg2 )
  399. call pa_Done( sh2 )
  400. case default
  401. call mf_ReadRecord_1( mf, paramkey, t1, t2, nuv, nw, &
  402. gridtype, levi, &
  403. lli, ll, sp_ll, &
  404. ggi, gg, sp_gg, &
  405. shi, sh, lnsp_sh, &
  406. tmi, status )
  407. IF_NOTOK_RETURN(status=1)
  408. end select
  409. ! ok
  410. status = 0
  411. end subroutine mf_ReadRecord
  412. ! ***
  413. subroutine mf_ReadRecord_1( mf, paramkey, t1, t2, nuv, nw, &
  414. gridtype, levi, &
  415. lli, ll, sp_ll, &
  416. ggi, gg, sp_gg, &
  417. shi, sh, lnsp_sh, &
  418. tmi, status )
  419. use parray , only : pa_Init, pa_Done
  420. use GO , only : TDate, operator(<), operator(-), rTotal, wrtgol
  421. use Grid , only : TLevelInfo
  422. use Grid , only : TllGridInfo, TggGridInfo, TshGridInfo
  423. use tmm_info , only : TMeteoInfo
  424. ! --- in/out -------------------------------
  425. type(TMeteoFile_ecmwf_tmpp), intent(inout) :: mf
  426. character(len=*), intent(in) :: paramkey
  427. type(TDate), intent(in) :: t1, t2
  428. character(len=1), intent(in) :: nuv
  429. character(len=1), intent(in) :: nw
  430. character(len=2), intent(out) :: gridtype
  431. type(TLevelInfo), intent(out) :: levi
  432. type(TllGridInfo), intent(inout) :: lli
  433. real, pointer :: ll(:,:,:)
  434. real, pointer :: sp_ll(:,:)
  435. type(TggGridInfo), intent(inout) :: ggi
  436. real, pointer :: gg(:,:)
  437. real, pointer :: sp_gg(:)
  438. type(TshGridInfo), intent(inout) :: shi
  439. complex, pointer :: sh(:,:)
  440. complex, pointer :: lnsp_sh(:)
  441. type(TMeteoInfo), intent(out) :: tmi
  442. integer, intent(out) :: status
  443. ! --- const --------------------------------------
  444. character(len=*), parameter :: rname = mname//'/mf_ReadRecord_1'
  445. ! --- local -------------------------------
  446. type(TDate) :: tref
  447. real, pointer :: ll1(:,:,:)
  448. real, pointer :: gg1(:,:)
  449. complex, pointer :: sh1(:,:)
  450. real :: dt_sec
  451. ! --- begin ---------------------------------
  452. ! accumulated field ?
  453. select case ( paramkey )
  454. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  455. ! accumulated fields
  456. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  457. case ( 'lsp', 'cp', 'sf', 'sshf', 'slhf', 'ssr', 'ewss', 'nsss' )
  458. ! get reference time for requested time interval:
  459. call GetGribTime( mf%treskey, mf%tday, t1, t2, status, tref=tref )
  460. IF_NOTOK_RETURN(status=1)
  461. ! should be a time interval ...
  462. if ( .not. (t1 < t2) ) then
  463. write (gol,'("accumulated fields requires time interval:")'); call goErr
  464. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  465. call wrtgol( ' t1 : ', t1 ); call goErr
  466. call wrtgol( ' t2 : ', t2 ); call goErr
  467. write (gol,'("in ",a)') rname; call goErr; status=1; return
  468. end if
  469. ! read field accumulated over [tref,t2] :
  470. call mf_ReadRecord_2( mf, paramkey, tref, t2, t2, 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. ! substract [tref,t1] if necessary:
  478. if ( tref < t1 ) then
  479. ! init pointer:
  480. call pa_Init( ll1 )
  481. call pa_Init( gg1 )
  482. call pa_Init( sh1 )
  483. ! read field accumulated over [tref,t1] :
  484. call mf_ReadRecord_2( mf, paramkey, tref, t1, t1, nuv, nw, &
  485. gridtype, levi, &
  486. lli, ll1, sp_ll, &
  487. ggi, gg1, sp_gg, &
  488. shi, sh1, lnsp_sh, &
  489. tmi, status )
  490. IF_NOTOK_RETURN(status=1)
  491. ! substract:
  492. select case ( gridtype )
  493. case ( 'll' ) ; ll = ll - ll1
  494. case ( 'gg' ) ; gg = gg - gg1
  495. case ( 'sh' ) ; sh = sh - sh1
  496. case default
  497. write (gol,'("unsupported gridtype for substract :",a)') gridtype; call goErr
  498. write (gol,'("in ",a)') rname; call goErr; status=1; return
  499. end select
  500. ! clear pointers:
  501. call pa_Done( ll1 )
  502. call pa_Done( gg1 )
  503. call pa_Done( sh1 )
  504. end if
  505. ! return time averages only:
  506. dt_sec = rTotal( t2 - t1, 'sec' )
  507. select case ( gridtype )
  508. case ( 'll' ) ; ll = ll / dt_sec
  509. case ( 'gg' ) ; gg = gg / dt_sec
  510. case ( 'sh' ) ; sh = sh / dt_sec
  511. case default
  512. write (gol,'("unsupported gridtype for time average :",a)') gridtype; call goErr
  513. write (gol,'("in ",a)') rname; call goErr; status=1; return
  514. end select
  515. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  516. ! instantaneous fields
  517. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  518. case default
  519. ! get reference time for requested time interval:
  520. call GetGribTime( mf%treskey, mf%tday, t1, t2, status, tref=tref )
  521. IF_NOTOK_RETURN(status=1)
  522. ! just read ..
  523. call mf_ReadRecord_2( mf, paramkey, tref, t1, t2, nuv, nw, &
  524. gridtype, levi, &
  525. lli, ll, sp_ll, &
  526. ggi, gg, sp_gg, &
  527. shi, sh, lnsp_sh, &
  528. tmi, status )
  529. IF_NOTOK_RETURN(status=1)
  530. end select
  531. ! ok
  532. status = 0
  533. end subroutine mf_ReadRecord_1
  534. ! ***
  535. subroutine mf_ReadRecord_2( mf, paramkey, tref, t1, t2, nuv, nw, &
  536. gridtype, levi, &
  537. lli, ll, sp_ll, &
  538. ggi, gg, sp_gg, &
  539. shi, sh, lnsp_sh, &
  540. tmi, status )
  541. use GO , only : TDate, wrtgol
  542. use Grid , only : Init, Done
  543. use Grid , only : TLevelInfo
  544. use Grid , only : TllGridInfo, TggGridInfo, TshGridInfo
  545. use Grid , only : Interpol
  546. use file_grib , only : Init, Done, ReadRecord, Get, Check
  547. use file_grib , only : levtype_sfc, levtype_hyb
  548. use file_grib , only : gridtype_ll, gridtype_gg, gridtype_sh
  549. use grib_table, only : GetPid
  550. use PArray , only : pa_Init, pa_Done, pa_SetShape
  551. use tmm_info , only : TMeteoInfo, Init, AddHistory
  552. ! --- in/out -------------------------------
  553. type(TMeteoFile_ecmwf_tmpp), intent(inout) :: mf
  554. character(len=*), intent(in) :: paramkey
  555. type(TDate), intent(in) :: tref, t1, t2
  556. character(len=1), intent(in) :: nuv
  557. character(len=1), intent(in) :: nw
  558. character(len=2), intent(out) :: gridtype
  559. type(TLevelInfo), intent(out) :: levi
  560. type(TllGridInfo), intent(inout) :: lli
  561. real, pointer :: ll(:,:,:)
  562. real, pointer :: sp_ll(:,:)
  563. type(TggGridInfo), intent(inout) :: ggi
  564. real, pointer :: gg(:,:)
  565. real, pointer :: sp_gg(:)
  566. type(TshGridInfo), intent(inout) :: shi
  567. complex, pointer :: sh(:,:)
  568. complex, pointer :: lnsp_sh(:)
  569. type(TMeteoInfo), intent(out) :: tmi
  570. integer, intent(out) :: status
  571. ! --- const --------------------------------------
  572. character(len=*), parameter :: rname = mname//'/mf_ReadRecord_2'
  573. ! --- local -------------------------------
  574. logical :: isfirst
  575. logical :: reopened
  576. integer :: pid, tabid
  577. integer :: nlev, glevtype, glevel
  578. integer :: level
  579. integer :: ggridtype
  580. real :: lon_first, lon_inc
  581. integer :: lon_n
  582. real :: lat_first, lat_inc
  583. integer :: lat_n
  584. integer :: ggN
  585. integer :: shT
  586. integer :: greftime(5), gtimerange(4)
  587. character(len=64) :: key
  588. integer :: ilat
  589. real, pointer :: pat(:,:)
  590. type(TshGridInfo) :: tmp_shi
  591. complex, pointer :: tmp_sh(:)
  592. ! --- begin ---------------------------------
  593. ! no fluxes through boundaries ...
  594. if ( nuv /= 'n' ) then
  595. write (gol,'("unsupported nuv key : ",a)') nuv; call goErr
  596. write (gol,'("in ",a)') rname; call goErr; status=1; return
  597. end if
  598. ! init pointer arrays:
  599. call pa_Init( pat )
  600. !
  601. ! ~~~ 3d field or 2d stored in 3d array
  602. !
  603. ! open grib file
  604. call Init( mf%grib, mf%fname, 'r', status )
  605. IF_NOTOK_RETURN(status=1)
  606. ! arrays and grids not defined yet
  607. isfirst = .true.
  608. reopened = .false.
  609. ! loop over records
  610. level = 0
  611. do
  612. !
  613. ! read gribsection in file buffer
  614. !
  615. call ReadRecord( mf%grib, status )
  616. select case ( status )
  617. case ( 0 )
  618. ! no error
  619. case ( 1 )
  620. ! eof
  621. if ( .not. reopened ) then
  622. !write (*,'("grib read record: re-open ...")')
  623. ! close:
  624. call Done( mf%grib, status )
  625. IF_NOTOK_RETURN(status=1)
  626. ! reopen:
  627. call Init( mf%grib, mf%fname, 'r', status )
  628. IF_NOTOK_RETURN(status=1)
  629. reopened = .true.
  630. cycle
  631. else
  632. write (gol,'("reached eof before requested record was found")') ; call goErr
  633. write (gol,'(" file : ",a)') trim(mf%fname) ; call goErr
  634. write (gol,'(" paramkey : ",a)') trim(paramkey) ; call goErr
  635. call wrtgol( ' tref : ', tref ) ; call goErr
  636. call wrtgol( ' t1 : ', t1 ) ; call goErr
  637. call wrtgol( ' t2 : ', t2 ) ; call goErr
  638. TRACEBACK ; status=1; return
  639. end if
  640. case default
  641. write (gol,'("error from grib ReadRecord; status=",i6)') status; call goErr
  642. TRACEBACK ; status=1; return
  643. end select
  644. !
  645. ! checks ...
  646. !
  647. ! get param id for the requested field from grib table:
  648. select case ( paramkey )
  649. case ( 'spm' ) ; call GetPid( 'ec', 'SP' , pid, tabid, status )
  650. case default ; call GetPid( 'ec', paramkey, pid, tabid, status )
  651. end select
  652. IF_NOTOK_RETURN(status=1)
  653. ! check parameter; continue if not ok:
  654. call Check( mf%grib, pid=pid, debug=0, status=status )
  655. if (status/=0) cycle
  656. ! fill times ?
  657. if ( .not. mf%constant ) then
  658. ! extract time fields from grib, store in mf%tref/mf%t1/mf%t2
  659. call SetTime( mf, status )
  660. IF_NOTOK_RETURN(status=1)
  661. ! check time:
  662. call CheckTime( mf, tref, t1, t2, status )
  663. if (status/=0) then
  664. !write (*,'("grib read record: wrong time; skip ...")')
  665. cycle
  666. !write (gol,'("found unexpected times in grib file:")'); call goErr
  667. !write (gol,'(" paramkey : ",a)') paramkey; call goErr
  668. !call wrtgol( ' req. t1 : ', t1 ); call goErr
  669. !call wrtgol( ' t2 : ', t2 ); call goErr
  670. !call wrtgol( ' grib t1 : ', mf%t1 ); call goErr
  671. !call wrtgol( ' t2 : ', mf%t2 ); call goErr
  672. !write (gol,'(" grib file : ",a)') trim(mf%fname); call goErr
  673. !TRACEBACK ; status=1; return
  674. end if
  675. end if ! time checking
  676. ! extract level stuff:
  677. call Get( mf%grib, nlev=nlev, levtype=glevtype, level=glevel, status=status )
  678. IF_NOTOK_RETURN(status=1)
  679. ! check level type:
  680. select case ( glevtype )
  681. case ( levtype_sfc )
  682. ! surface field
  683. nlev = 1
  684. glevel = 1
  685. case ( levtype_hyb )
  686. select case ( paramkey )
  687. case ( 'LNSP' )
  688. nlev = 1
  689. case default
  690. ! level in 3d field
  691. end select
  692. case default
  693. write (gol,'("found unexpected level type: ")'); call goErr
  694. write (gol,'(" leveltype : ",i3)') glevtype; call goErr
  695. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  696. write (gol,'(" grib file : ",a)') trim(mf%fname); call goErr
  697. TRACEBACK ; status=1; return
  698. end select
  699. ! check level:
  700. level = level + 1
  701. if ( glevel /= level ) then
  702. write (gol,'("found unexpected level: ")'); call goErr
  703. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  704. write (gol,'(" req. level : ",i6)') level; call goErr
  705. write (gol,'(" grib level : ",i6)') glevel; call goErr
  706. write (gol,'(" grib nlev : ",i6)') nlev; call goErr
  707. write (gol,'(" grib file : ",a)') trim(mf%fname); call goErr
  708. TRACEBACK ; status=1; return
  709. end if
  710. !
  711. ! define grids and arrays
  712. !
  713. if ( isfirst ) then
  714. !
  715. ! * info
  716. !
  717. ! example of history:
  718. ! model=ecmwf;class=od;type=fc;tref=2000,12,31,12,00; ...
  719. ! trange=001,234,240,001;sh=159;nlev=60
  720. !
  721. call Init( tmi, paramkey, 'unknown', status )
  722. call AddHistory( tmi, 'model==ecmwf', status )
  723. call AddHistory( tmi, 'class=='//trim(mf%ec_class), status )
  724. call AddHistory( tmi, 'type=='//trim(mf%ec_type) , status )
  725. !
  726. call Get( mf%grib, status, reftime=greftime, timerange=gtimerange )
  727. IF_NOTOK_RETURN(status=1)
  728. write (key,'("tref==",i4.4,4(",",i2.2))') greftime
  729. call AddHistory( tmi, trim(key), status )
  730. write (key,'("trange==",i3.3,3(",",i3.3))') gtimerange
  731. call AddHistory( tmi, trim(key), status )
  732. !
  733. write (key,'("nlev==",i3.3)') nlev
  734. call AddHistory( tmi, trim(key), status )
  735. !
  736. ! * define horizontal grid:
  737. !
  738. ! extract grid type:
  739. call Get( mf%grib, status, gridtype=ggridtype )
  740. IF_NOTOK_RETURN(status=1)
  741. ! setup:
  742. select case ( ggridtype )
  743. ! o lat/lon
  744. case ( gridtype_ll )
  745. ! routine returns lat/lon grid:
  746. gridtype = 'll'
  747. ! grib storage is north pole to south pole:
  748. call Get( mf%grib, status, &
  749. lon_first=lon_first, lon_inc=lon_inc, lon_n=lon_n, &
  750. lat_last =lat_first, lat_inc=lat_inc, lat_n=lat_n )
  751. IF_NOTOK_RETURN(status=1)
  752. ! define grid structure:
  753. call Init( lli, lon_first, lon_inc, lon_n, &
  754. lat_first, lat_inc, lat_n, status )
  755. IF_NOTOK_RETURN(status=1)
  756. ! init array to store 2d field from grib file (north-south order):
  757. call pa_SetShape( pat, lon_n, lat_n )
  758. ! allocate output:
  759. call pa_SetShape( ll, lon_n, lat_n, nlev )
  760. ! add to history:
  761. write (key,'("longrid==",f7.2,",",f6.2,",",i4)') lon_first, lon_inc, lon_n
  762. call AddHistory( tmi, trim(key), status )
  763. write (key,'("latgrid==",f7.2,",",f6.2,",",i4)') lat_first, lat_inc, lat_n
  764. call AddHistory( tmi, trim(key), status )
  765. ! o gaussian grid
  766. case ( gridtype_gg )
  767. ! routine returns gg grid:
  768. gridtype = 'gg'
  769. ! extract grid number:
  770. call Get( mf%grib, status, N=ggN )
  771. IF_NOTOK_RETURN(status=1)
  772. ! define grid structure:
  773. call Init( ggi, ggN, .true., status )
  774. IF_NOTOK_RETURN(status=1)
  775. ! allocate output:
  776. call pa_SetShape( gg, ggi%np, nlev )
  777. ! add to history:
  778. write (key,'("gg==",i4.4)') ggN
  779. call AddHistory( tmi, trim(key), status )
  780. ! o spectral field:
  781. case ( gridtype_sh )
  782. ! routine returns sh grid:
  783. gridtype = 'sh'
  784. ! extract spectral truncation:
  785. call Get( mf%grib, status, T=shT )
  786. IF_NOTOK_RETURN(status=1)
  787. ! intialize spherical harmonic field info:
  788. call Init( shi, shT, status )
  789. IF_NOTOK_RETURN(status=1)
  790. ! allocate output:
  791. call pa_SetShape( sh, shi%np, nlev )
  792. ! add to history:
  793. write (key,'("sh==",i4.4)') shT
  794. call AddHistory( tmi, trim(key), status )
  795. case default
  796. write (gol,'("unsupported gridtype for setup : ",i6)') ggridtype; call goErr
  797. TRACEBACK ; status=1; return
  798. end select
  799. !
  800. ! * levels
  801. !
  802. select case ( nlev )
  803. case ( 1 )
  804. call Init( levi, nlev, (/0.0,0.0/), (/0.0,0.0/), status )
  805. IF_NOTOK_RETURN(status=1)
  806. case ( 60 )
  807. call Init( levi, 'ec60', status )
  808. IF_NOTOK_RETURN(status=1)
  809. end select
  810. ! not again ...
  811. isfirst = .false.
  812. end if ! isfirst (grid definition and allocation)
  813. !
  814. ! store
  815. !
  816. select case ( ggridtype )
  817. case ( gridtype_ll )
  818. ! read 2d pat from grib; storred from north to south
  819. call Get( mf%grib, status, ll=pat )
  820. IF_NOTOK_RETURN(status=1)
  821. ! store from south to north:
  822. do ilat = 1, lat_n
  823. ll(:,ilat,level) = pat(:,lat_n+1-ilat)
  824. end do
  825. case ( gridtype_gg )
  826. ! read 2d pat from grib:
  827. call Get( mf%grib, status, gg=gg(:,level) )
  828. IF_NOTOK_RETURN(status=1)
  829. case ( gridtype_sh )
  830. ! read 2d pat from grib:
  831. call Get( mf%grib, status, sh=sh(:,level) )
  832. IF_NOTOK_RETURN(status=1)
  833. case default
  834. write (gol,'("unsupported gridtype for 2d pat : ",i6)') gridtype; call goErr
  835. TRACEBACK ; status=1; return
  836. end select
  837. ! last record for this field ?
  838. if ( glevel == nlev ) exit
  839. end do ! records
  840. ! close grib file
  841. call Done( mf%grib, status )
  842. IF_NOTOK_RETURN(status=1)
  843. !
  844. ! ~~~ surface pressure
  845. !
  846. if ( mf%do_spm ) then
  847. ! open grib file
  848. call Init( mf%spm_grib, mf%spm_fname, 'r', status )
  849. IF_NOTOK_RETURN(status=1)
  850. ! loop over time records
  851. do
  852. ! read gribsection in file buffer
  853. call ReadRecord( mf%spm_grib, status )
  854. IF_NOTOK_RETURN(status=1)
  855. ! fill times
  856. call SetTime( mf, status )
  857. IF_NOTOK_RETURN(status=1)
  858. ! check time:
  859. call CheckTime( mf, tref, t1, t2, status )
  860. if (status/=0) then
  861. !write (*,'("grib read record: spm wrong time; skip ...")')
  862. cycle
  863. !write (gol,'("found unexpected times in grib file:")'); call goErr
  864. !write (gol,'(" paramkey : ",a)') paramkey; call goErr
  865. !call wrtgol( ' req. t1 : ', t1 ); call goErr
  866. !call wrtgol( ' t2 : ', t2 ); call goErr
  867. !call wrtgol( ' grib t1 : ', mf%t1 ); call goErr
  868. !call wrtgol( ' t2 : ', mf%t2 ); call goErr
  869. !write (gol,'(" grib file : ",a)') trim(mf%spm_fname); call goErr
  870. !TRACEBACK ; status=1; return
  871. end if
  872. ! time ok
  873. exit
  874. end do ! time loop
  875. ! set param id:
  876. select case ( ggridtype )
  877. case ( gridtype_ll )
  878. call GetPid( 'ec', 'SP', pid, tabid, status )
  879. IF_NOTOK_RETURN(status=1)
  880. case ( gridtype_gg )
  881. if ( mf%spm_lnsp2sp ) then
  882. call GetPid( 'ec', 'LNSP', pid, tabid, status )
  883. IF_NOTOK_RETURN(status=1)
  884. else
  885. call GetPid( 'ec', 'SP', pid, tabid, status )
  886. IF_NOTOK_RETURN(status=1)
  887. end if
  888. case ( gridtype_sh )
  889. call GetPid( 'ec', 'LNSP', pid, tabid, status )
  890. IF_NOTOK_RETURN(status=1)
  891. case default
  892. write (gol,'("unsupported gridtype for setup sp/lnsp : ",i6)') ggridtype; call goErr
  893. TRACEBACK ; status=1; return
  894. end select
  895. ! check parameter:
  896. call Check( mf%spm_grib, pid=pid, debug=1, status=status )
  897. IF_NOTOK_RETURN(status=1)
  898. ! check level:
  899. call Get( mf%spm_grib, levtype=glevtype, level=glevel, status=status )
  900. IF_NOTOK_RETURN(status=1)
  901. select case ( ggridtype )
  902. case ( gridtype_ll )
  903. if ( glevtype /= levtype_sfc ) then
  904. write (gol,'("found unexpected level type ")'); call goErr
  905. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  906. write (gol,'(" sfc level type : ",i6)') levtype_sfc; call goErr
  907. write (gol,'(" grib level type : ",i6)') glevtype; call goErr
  908. write (gol,'(" grib file : ",a)') trim(mf%spm_fname); call goErr
  909. TRACEBACK ; status=1; return
  910. end if
  911. case ( gridtype_gg )
  912. if ( mf%spm_lnsp2sp ) then
  913. if ( (glevtype /= levtype_hyb) .or. (glevel /= 1) ) then
  914. write (gol,'("found unexpected level type (lnsp for 3d gg)")'); call goErr
  915. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  916. write (gol,'(" hyb level type : ",i6)') levtype_hyb; call goErr
  917. write (gol,'(" grib level type : ",i6)') glevtype; call goErr
  918. write (gol,'(" grib level : ",i6)') glevel; call goErr
  919. write (gol,'(" grib file : ",a)') trim(mf%spm_fname); call goErr
  920. TRACEBACK ; status=1; return
  921. end if
  922. else
  923. if ( glevtype /= levtype_sfc ) then
  924. write (gol,'("found unexpected level type ")'); call goErr
  925. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  926. write (gol,'(" sfc level type : ",i6)') levtype_sfc; call goErr
  927. write (gol,'(" grib level type : ",i6)') glevtype; call goErr
  928. write (gol,'(" grib file : ",a)') trim(mf%spm_fname); call goErr
  929. TRACEBACK ; status=1; return
  930. end if
  931. end if
  932. case ( gridtype_sh )
  933. if ( (glevtype /= levtype_hyb) .or. (glevel /= 1) ) then
  934. write (gol,'("found unexpected level type ")'); call goErr
  935. write (gol,'(" paramkey : ",a)') paramkey; call goErr
  936. write (gol,'(" hyb level type : ",i6)') levtype_hyb; call goErr
  937. write (gol,'(" grib level type : ",i6)') glevtype; call goErr
  938. write (gol,'(" grib level : ",i6)') glevel; call goErr
  939. write (gol,'(" grib file : ",a)') trim(mf%spm_fname); call goErr
  940. TRACEBACK ; status=1; return
  941. end if
  942. case default
  943. write (gol,'("unsupported gridtype for sp/lnsp levs : ",i6)') ggridtype; call goErr
  944. TRACEBACK ; status=1; return
  945. end select
  946. ! read and store surface pressure field:
  947. select case ( ggridtype )
  948. case ( gridtype_ll )
  949. ! allocate storage
  950. call pa_SetShape( sp_ll, lon_n, lat_n )
  951. ! read 2d pat from grib; storred from north to south
  952. call Get( mf%spm_grib, status, ll=pat )
  953. IF_NOTOK_RETURN(status=1)
  954. ! store from south to north:
  955. do ilat = 1, lat_n
  956. sp_ll(:,ilat) = pat(:,lat_n+1-ilat)
  957. end do
  958. case ( gridtype_gg )
  959. ! allocate storage
  960. call pa_SetShape( sp_gg, ggi%np )
  961. ! convert from sh lnsp or read directly:
  962. if ( mf%spm_lnsp2sp ) then
  963. ! allocate output:
  964. call pa_SetShape( sh, shi%np, nlev )
  965. ! extract spectral truncation:
  966. call Get( mf%spm_grib, status, T=shT )
  967. IF_NOTOK_RETURN(status=1)
  968. ! intialize spherical harmonic field info:
  969. call Init( tmp_shi, shT, status )
  970. IF_NOTOK_RETURN(status=1)
  971. ! allocate storage for lnsp:
  972. call pa_Init( tmp_sh )
  973. call pa_SetShape( tmp_sh, tmp_shi%np )
  974. ! read lnsp on sh grid:
  975. call Get( mf%spm_grib, status, sh=tmp_sh )
  976. IF_NOTOK_RETURN(status=1)
  977. ! interpolate from sh to gg:
  978. call Interpol( tmp_shi, tmp_sh, ggi, sp_gg, status ) ! ln(Pa)
  979. IF_NOTOK_RETURN(status=1)
  980. ! clear
  981. call Done( tmp_shi )
  982. call pa_Done( tmp_sh )
  983. ! convert from lnsp to sp :
  984. sp_gg = exp(sp_gg) ! Pa
  985. else
  986. ! read 2d pat from grib; storred from north to south
  987. call Get( mf%spm_grib, status, gg=sp_gg )
  988. IF_NOTOK_RETURN(status=1)
  989. end if
  990. case ( gridtype_sh )
  991. ! allocate storage
  992. call pa_SetShape( lnsp_sh, shi%np )
  993. ! read spectral coeff:
  994. call Get( mf%spm_grib, status, sh=lnsp_sh )
  995. IF_NOTOK_RETURN(status=1)
  996. case default
  997. write (gol,'("unsupported gridtype for reading sp/lnsp : ",i6)') ggridtype; call goErr
  998. TRACEBACK ; status=1; return
  999. end select
  1000. ! close grib file
  1001. call Done( mf%spm_grib, status )
  1002. IF_NOTOK_RETURN(status=1)
  1003. end if
  1004. !
  1005. ! ~~~ end
  1006. !
  1007. ! deallocate arrays
  1008. call pa_Done( pat )
  1009. ! ok
  1010. status = 0
  1011. end subroutine mf_ReadRecord_2
  1012. ! ****************************************************************************
  1013. !
  1014. ! In gribfile:
  1015. ! reftime : for example time at which forecast is made
  1016. ! timerange: increment or interval
  1017. !
  1018. ! arguments: ok if:
  1019. !
  1020. ! time1 == time2 time1==time2 == reftime+timerange
  1021. !
  1022. ! time1 == 0 time2 == reftime+timerange
  1023. !
  1024. ! time2 == 0 time1 == reftime
  1025. !
  1026. ! time1 < time2 time1 == refitme, time2 == reftime+timerange
  1027. !
  1028. !
  1029. ! grib [t1-----------t2]
  1030. ! status
  1031. ! o time1/2 record too old 1
  1032. ! o time1/2 ok 0
  1033. ! o time1/2 record too new 2
  1034. !
  1035. !
  1036. ! SetTime( mf, status )
  1037. !
  1038. ! Extracts time values from current grib record,
  1039. ! store in mf%t1, mf%t2
  1040. !
  1041. ! return status:
  1042. ! 0 : ok
  1043. ! other : some error
  1044. !
  1045. ! CheckTime( mf, time1, time2, status )
  1046. !
  1047. ! return status:
  1048. ! 0 : times match
  1049. ! 1 : times do not match, try next record
  1050. ! 2 : current record is newer than requested (reopen ?)
  1051. ! 3 : some error
  1052. !
  1053. ! ***
  1054. !
  1055. ! Return time parameters for grib files:
  1056. ! o tfile : date in filename
  1057. ! o trange : time interval covered by fields in file
  1058. ! o tref : reference time (forecast start?) for tday,[t1,t2]
  1059. !
  1060. subroutine GetGribTime( ec_treskey, tday, t1, t2, status, tfile, trange, tref )
  1061. use GO, only : TDate, Get, Set, wrtgol, NewDate, IncrDate, operator(+), operator(-)
  1062. ! --- in/out --------------------------------
  1063. character(len=*), intent(in) :: ec_treskey
  1064. type(TDate), intent(in) :: tday, t1, t2
  1065. integer, intent(out) :: status
  1066. type(TDate), intent(out), optional :: tfile
  1067. type(TDate), intent(out), optional :: trange(2)
  1068. type(TDate), intent(out), optional :: tref
  1069. ! --- const --------------------------------------
  1070. character(len=*), parameter :: rname = mname//'/GetGribTime'
  1071. ! --- local --------------------------------
  1072. integer :: hour2, time6(6)
  1073. integer :: dd, hh, step
  1074. ! --- begin --------------------------------
  1075. ! set day shift, start hour, and step
  1076. select case ( ec_treskey )
  1077. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1078. ! constant field
  1079. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1080. case ( 'const' )
  1081. ! only tday is usefull ...
  1082. if ( present(tfile ) ) tfile = tday
  1083. if ( present(trange) ) trange = (/t1,t2/) ! any, any
  1084. if ( present(tref ) ) tref = tday ! dummy ...
  1085. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1086. ! fg, 3 hourly
  1087. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1088. case ( '_fg006up4tr3' )
  1089. ! extract end hour:
  1090. call Get( t2, hour=hour2 )
  1091. ! set forecast start time and step given hour:
  1092. select case ( hour2 )
  1093. case ( 00 ) ; dd = 0 ; hh = 00 ; step = 6
  1094. case ( 03 ) ; dd = 0 ; hh = 03 ; step = 3
  1095. case ( 06 ) ; dd = 0 ; hh = 06 ; step = 6
  1096. case ( 09 ) ; dd = 0 ; hh = 09 ; step = 3
  1097. case ( 12 ) ; dd = 0 ; hh = 12 ; step = 6
  1098. case ( 15 ) ; dd = 0 ; hh = 15 ; step = 3
  1099. case ( 18 ) ; dd = 0 ; hh = 18 ; step = 6
  1100. case ( 21 ) ; dd = 0 ; hh = 21 ; step = 3
  1101. case default
  1102. write (gol,'("unsupported hour :")'); call goErr
  1103. write (gol,'(" hour2 : ",i2)') hour2; call goErr
  1104. write (gol,'(" timesteps : ",a )') ec_treskey; call goErr
  1105. call wrtgol( ' time1 : ', t1 ); call goErr
  1106. TRACEBACK ; status=1; return
  1107. end select
  1108. ! file ccyymmdd contains fields for [00,24) :
  1109. if ( present(tfile) ) then
  1110. tfile = t1
  1111. call Set( tfile, hour=00 )
  1112. end if
  1113. ! fields valid for [00,24) :
  1114. if ( present(trange) ) then
  1115. trange(1) = t1
  1116. call Set( trange(1), hour=0, min=0, sec=0, mili=0 )
  1117. trange(2) = trange(1) + IncrDate(hour=23,min=59,sec=59,mili=999)
  1118. ! trap last fg time 2000-09-12 00:00 ; data valid forr 00:00 only:
  1119. call Get( tfile, time6=time6 )
  1120. if ( all(time6(1:3)==(/2000,09,12/)) ) trange(2) = trange(1)
  1121. end if
  1122. ! reference time = start of forecast
  1123. if ( present(tref) ) then
  1124. call Get( t1, time6=time6 )
  1125. time6(4:6) = 0
  1126. tref = NewDate( time6=time6 ) + IncrDate( day=dd, hour=hh )
  1127. end if
  1128. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1129. ! fc, 3 hourly
  1130. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1131. case ( '_fc012up2tr3', '_03p03' )
  1132. ! extract end hour:
  1133. call Get( t2, hour=hour2 )
  1134. ! set forecast start time and step given hour:
  1135. select case ( hour2 )
  1136. case ( 00 ) ; dd = -1 ; hh = 12 ; step = 12
  1137. case ( 03 ) ; dd = 0 ; hh = 00 ; step = 3
  1138. case ( 06 ) ; dd = 0 ; hh = 00 ; step = 6
  1139. case ( 09 ) ; dd = 0 ; hh = 00 ; step = 9
  1140. case ( 12 ) ; dd = 0 ; hh = 00 ; step = 12
  1141. case ( 15 ) ; dd = 0 ; hh = 12 ; step = 3
  1142. case ( 18 ) ; dd = 0 ; hh = 12 ; step = 6
  1143. case ( 21 ) ; dd = 0 ; hh = 12 ; step = 9
  1144. case default
  1145. write (gol,'("unsupported hour :")'); call goErr
  1146. write (gol,'(" hour2 : ",i2)') hour2; call goErr
  1147. write (gol,'(" timesteps : ",a )') ec_treskey; call goErr
  1148. call wrtgol( ' time1 : ', t1 ); call goErr
  1149. TRACEBACK ; status=1; return
  1150. end select
  1151. ! file ccyymmdd contains fields for (00,24] :
  1152. if ( present(tfile) ) then
  1153. ! current day by default:
  1154. tfile = t2
  1155. call Set( tfile, hour=0, min=0, sec=0, mili=0 ) ! 00:00
  1156. ! trap (..,00:00], this should be previous day:
  1157. call Get( t2, time6=time6 )
  1158. if ( all(time6(4:6)==0) ) tfile = tfile - IncrDate(day=1)
  1159. end if
  1160. ! fields valid for (00,24] :
  1161. if ( present(trange) ) then
  1162. trange(1) = t2
  1163. call Set( trange(1), hour=0, min=0, sec=0, mili=0 ) ! 00:00
  1164. ! trap 00:00, this should be previous day:
  1165. call Get( t2, time6=time6 )
  1166. if ( all(time6(4:6)==0) ) trange(1) = trange(1) - IncrDate(day=1)
  1167. ! complete (00,24]
  1168. trange(2) = trange(1) + IncrDate(day=1) ! 24:00
  1169. call Set( trange(1), mili=1 ) ! > 00:00
  1170. end if
  1171. ! reference time = start of forecast
  1172. if ( present(tref) ) then
  1173. call Get( t2, time6=time6 )
  1174. time6(4:6) = 0
  1175. tref = NewDate( time6=time6 ) + IncrDate( day=dd, hour=hh )
  1176. end if
  1177. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1178. ! fc, 6 hourly
  1179. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1180. case ( '_06p06' )
  1181. ! extract end hour:
  1182. call Get( t2, hour=hour2 )
  1183. ! set forecast start time and step given hour:
  1184. select case ( hour2 )
  1185. case ( 00 ) ; dd = -1 ; hh = 12 ; step = 12
  1186. case ( 06 ) ; dd = 0 ; hh = 00 ; step = 6
  1187. case ( 12 ) ; dd = 0 ; hh = 00 ; step = 12
  1188. case ( 18 ) ; dd = 0 ; hh = 12 ; step = 6
  1189. case default
  1190. write (gol,'("unsupported hour :")'); call goErr
  1191. write (gol,'(" hour2 : ",i2)') hour2; call goErr
  1192. write (gol,'(" timesteps : ",a )') ec_treskey; call goErr
  1193. call wrtgol( ' time1 : ', t1 ); call goErr
  1194. TRACEBACK ; status=1; return
  1195. end select
  1196. ! file ccyymmdd contains fields for (00,24] :
  1197. if ( present(tfile) ) then
  1198. ! current day by default:
  1199. tfile = t1
  1200. call Set( tfile, hour=00 )
  1201. ! trap 00:00, this should be previous day:
  1202. call Get( t1, time6=time6 )
  1203. if ( all(time6(4:6)==0) ) tfile = tfile - IncrDate(day=1)
  1204. end if
  1205. ! fields valid for (00,24] :
  1206. if ( present(trange) ) then
  1207. trange(1) = t1
  1208. call Set( trange(1), hour=0, min=0, sec=0, mili=0 ) ! 00:00
  1209. ! trap 00:00, this should be previous day:
  1210. call Get( t1, time6=time6 )
  1211. if ( all(time6(4:6)==0) ) trange(1) = trange(1) - IncrDate(day=1)
  1212. ! complete (00,24]
  1213. trange(2) = trange(1) + IncrDate(day=1) ! 24:00
  1214. call Set( trange(1), mili=1 ) ! > 00:00
  1215. end if
  1216. ! reference time = start of forecast
  1217. if ( present(tref) ) then
  1218. call Get( t1, time6=time6 )
  1219. time6(4:6) = 0
  1220. tref = NewDate( time6=time6 ) + IncrDate( day=dd, hour=hh )
  1221. end if
  1222. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1223. ! analysis, 6 hourly
  1224. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1225. case ( 'an_06p06' )
  1226. ! extract end hour:
  1227. call Get( t2, hour=hour2 )
  1228. ! set forecast start time and step given hour:
  1229. select case ( hour2 )
  1230. case ( 00 ) ; dd = 0 ; hh = 00 ; step = 00
  1231. case ( 06 ) ; dd = 0 ; hh = 06 ; step = 00
  1232. case ( 12 ) ; dd = 0 ; hh = 12 ; step = 00
  1233. case ( 18 ) ; dd = 0 ; hh = 18 ; step = 00
  1234. case default
  1235. write (gol,'("unsupported hour :")'); call goErr
  1236. write (gol,'(" hour2 : ",i2)') hour2; call goErr
  1237. write (gol,'(" timesteps : ",a )') ec_treskey; call goErr
  1238. call wrtgol( ' time1 : ', t1 ); call goErr
  1239. TRACEBACK ; status=1; return
  1240. end select
  1241. ! file ccyymmdd contains fields for (00,24] :
  1242. if ( present(tfile) ) then
  1243. ! current day by default:
  1244. tfile = t1
  1245. call Set( tfile, hour=00 )
  1246. ! trap 00:00, this should be previous day:
  1247. call Get( t1, time6=time6 )
  1248. if ( all(time6(4:6)==0) ) tfile = tfile - IncrDate(day=1)
  1249. end if
  1250. ! fields valid for (00,24] :
  1251. if ( present(trange) ) then
  1252. trange(1) = t1
  1253. call Set( trange(1), hour=0, min=0, sec=0, mili=0 ) ! 00:00
  1254. ! trap 00:00, this should be previous day:
  1255. call Get( t1, time6=time6 )
  1256. if ( all(time6(4:6)==0) ) trange(1) = trange(1) - IncrDate(day=1)
  1257. ! complete (00,24]
  1258. trange(2) = trange(1) + IncrDate(day=1) ! 24:00
  1259. call Set( trange(1), mili=1 ) ! > 00:00
  1260. end if
  1261. ! reference time = start of forecast
  1262. if ( present(tref) ) then
  1263. call Get( t1, time6=time6 )
  1264. time6(4:6) = 0
  1265. tref = NewDate( time6=time6 ) + IncrDate( day=dd, hour=hh )
  1266. end if
  1267. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1268. ! ???
  1269. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1270. case default
  1271. write (gol,'("unsupported time resolution key:")'); call goErr
  1272. write (gol,'(" ",a)') trim(ec_treskey); call goErr
  1273. TRACEBACK ; status=1; return
  1274. end select
  1275. ! ok
  1276. status = 0
  1277. end subroutine GetGribTime
  1278. ! ***
  1279. !
  1280. ! Extract time fields of current grib record,
  1281. ! store in mf%tref, mf%t1, mf%t2
  1282. !
  1283. subroutine SetTime( mf, status )
  1284. use GO, only : TDate, NewDate, IncrDate, operator(+), wrtgol
  1285. use file_grib, only : TGribFile, Get
  1286. ! --- const -------------------------------------
  1287. character(len=*), parameter :: rname = mname//'/SetTime'
  1288. ! --- in/out -------------------------------
  1289. type(TMeteoFile_ecmwf_tmpp), intent(inout) :: mf
  1290. integer, intent(out) :: status
  1291. ! --- local -------------------------------
  1292. integer :: reftime(5), timerange(4)
  1293. ! --- begin -------------------------------
  1294. ! extract time fields from grib record:
  1295. call Get( mf%grib, status, reftime=reftime, timerange=timerange )
  1296. IF_NOTOK_RETURN(status=1)
  1297. ! Fill t1 and t2 with the time information; might be equal.
  1298. ! Check time range indicator (WMO code table 5):
  1299. select case ( timerange(4) )
  1300. case ( 0, 1 )
  1301. !
  1302. ! 0 = Forecast product valid for reference time + P1 (P1>0),
  1303. ! or uninitialized analysis product for reference time (P1=0)
  1304. !
  1305. ! 1 = Initialized analysis product for reference time (P1=0).
  1306. !
  1307. ! fill reference time:
  1308. mf%tref = NewDate( time5=reftime )
  1309. ! fill t1 with reftime+timerange;
  1310. ! add P1 in hours; check time unit (WMO code table 4)
  1311. mf%t1 = NewDate( time5=reftime )
  1312. select case ( timerange(1) )
  1313. case ( 1 ) ! hours
  1314. mf%t1 = mf%t1 + IncrDate( hour=timerange(2) )
  1315. case default
  1316. write (gol,'("grib timerange units other than hours not supported yet")'); call goErr
  1317. write (gol,'(" reftime : ",i4,4i3)') reftime; call goErr
  1318. write (gol,'(" timerange : ",4i3)') timerange; call goErr
  1319. write (gol,'(" file : ",a)') trim(mf%grib%fname); call goErr
  1320. TRACEBACK ; status=1; return
  1321. end select
  1322. ! instant time:
  1323. mf%t2 = mf%t1
  1324. case ( 2 )
  1325. !
  1326. ! 2 = Product with a valid time ranging between
  1327. ! reference time + P1 and reference time + P2
  1328. !
  1329. ! fill t1 with reftime+P1;
  1330. ! add P1 in hours; check time unit (WMO code table 4)
  1331. mf%t1 = NewDate( time5=reftime )
  1332. select case ( timerange(1) )
  1333. case ( 1 ) ! hours
  1334. mf%t1 = mf%t1 + IncrDate( hour=timerange(2) )
  1335. case default
  1336. write (gol,'("grib timerange units other than hours not supported yet")'); call goErr
  1337. write (gol,'(" file : ",a)') trim(mf%grib%fname); call goErr
  1338. TRACEBACK ; status=1; return
  1339. end select
  1340. ! fill t2 with reftime+P1;
  1341. ! add P1 in hours; check time unit (WMO code table 4)
  1342. mf%t2 = NewDate( time5=reftime )
  1343. select case ( timerange(1) )
  1344. case ( 1 ) ! hours
  1345. mf%t2 = mf%t2 + IncrDate( hour=timerange(3) )
  1346. case default
  1347. write (gol,'("grib timerange units other than hours not supported yet")'); call goErr
  1348. write (gol,'(" file : ",a)') trim(mf%grib%fname); call goErr
  1349. TRACEBACK ; status=1; return
  1350. end select
  1351. case default
  1352. write (gol,'("unsupported time range indicator:")'); call goErr
  1353. write (gol,'(" indicator : ",i6)') timerange(4); call goErr
  1354. write (gol,'(" file : ",a)') trim(mf%grib%fname); call goErr
  1355. TRACEBACK ; status=1; return
  1356. end select
  1357. ! ok
  1358. status = 0
  1359. end subroutine SetTime
  1360. ! ***
  1361. subroutine CheckTime( mf, tref, t1, t2, status )
  1362. use GO
  1363. use file_grib, only : Get
  1364. ! --- const -------------------------------------
  1365. character(len=*), parameter :: rname = mname//'/CheckTime'
  1366. ! --- in/out -------------------------------
  1367. type(TMeteoFile_ecmwf_tmpp), intent(in) :: mf
  1368. type(TDate), intent(in) :: tref, t1, t2
  1369. integer, intent(out) :: status
  1370. ! --- local -------------------------------
  1371. integer :: year1, year2
  1372. ! --- begin -------------------------------
  1373. ! requested year zero ? always ok
  1374. call Get( t1, year=year1 )
  1375. call Get( t2, year=year2 )
  1376. if ( (year1 == 0) .and. (year2 == 0) ) then
  1377. ! requested constant field, always ok
  1378. status = 0; return ! ok
  1379. end if
  1380. if ( year1 == 0 ) then
  1381. ! do not test t1, only t2
  1382. if ( t2 == mf%t2 ) then
  1383. status = 0; return ! ok
  1384. else
  1385. status = 1; return ! not ok, try next
  1386. end if
  1387. else if ( year2 == 0 ) then
  1388. ! do not test t2, only t1
  1389. if ( t1 == mf%t1 ) then
  1390. status = 0; return ! ok
  1391. else
  1392. status = 1; return ! not ok, try next
  1393. end if
  1394. end if
  1395. ! ! interval or instant time
  1396. ! if ( t1 < t2 ) then
  1397. !
  1398. ! !! time interval: [t1,t2] should be inside [t1,t2]
  1399. ! !if ( (t1 >= mf%t1) .and. (t2 <= mf%t2) ) then
  1400. ! ! status = 0; return ! ok
  1401. ! !else
  1402. ! ! status = 1; return ! try next
  1403. ! !end if
  1404. !
  1405. ! ! time interval: [t1,t2] should be equal to [t1,t2]
  1406. ! if ( (t1 == mf%t1) .and. (t2 == mf%t2) ) then
  1407. ! status = 0; return ! ok
  1408. ! else
  1409. ! status = 1; return ! try next
  1410. ! end if
  1411. !
  1412. ! else if ( t1 == t2 ) then
  1413. !
  1414. ! ! instant time: t2 should match t2
  1415. ! if ( t2 == mf%t2 ) then
  1416. ! status = 0; return ! ok
  1417. ! else
  1418. ! status = 1; return ! try next
  1419. ! end if
  1420. !
  1421. ! else
  1422. !
  1423. ! write (gol,'("t1 should not exceed t2:")'); call goErr
  1424. ! call wrtgol( ' t1 : ', t1 ); call goErr
  1425. ! call wrtgol( ' t2 : ', t2 ); call goErr
  1426. ! write (*,'("ERROR in ",a)') rname; status=3; return
  1427. !
  1428. ! end if
  1429. ! compare all:
  1430. if ( (tref == mf%tref) .and. (t1 == mf%t1) .and. (t2 == mf%t2) ) then
  1431. status = 0; return ! ok
  1432. else
  1433. status = 1; return ! try next
  1434. end if
  1435. ! some error ...
  1436. status = 1
  1437. end subroutine CheckTime
  1438. end module tmm_mf_ecmwf_tmpp