tmm_mf_hdf.F90 92 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366236723682369237023712372237323742375237623772378237923802381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450245124522453245424552456245724582459246024612462246324642465246624672468246924702471247224732474247524762477247824792480248124822483248424852486248724882489249024912492249324942495249624972498249925002501250225032504250525062507250825092510251125122513251425152516251725182519252025212522252325242525252625272528252925302531253225332534253525362537253825392540254125422543254425452546254725482549255025512552255325542555255625572558255925602561256225632564256525662567256825692570257125722573257425752576257725782579258025812582258325842585258625872588258925902591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660266126622663266426652666266726682669267026712672267326742675267626772678267926802681268226832684268526862687268826892690269126922693269426952696269726982699270027012702270327042705270627072708270927102711271227132714271527162717271827192720272127222723272427252726272727282729
  1. !###############################################################################
  2. !
  3. ! Input/output of meteofiles : hdf version.
  4. !
  5. !### macro's ###################################################################
  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_hdf
  15. use GO , only : gol, goErr, goPr, goBug
  16. use GO , only : TDate
  17. use file_hdf, only : THdfFile, TSds
  18. implicit none
  19. ! --- in/out ----------------------------
  20. private
  21. public :: TMeteoFile_hdf
  22. public :: Init, Done
  23. public :: Get
  24. public :: ReadRecord
  25. ! public :: ReadEqvLatStuff
  26. public :: WriteRecord
  27. ! --- const ------------------------------
  28. character(len=*), parameter :: mname = 'tmm_mf_hdf'
  29. ! ~~~ output keys and defaults
  30. ! current format version
  31. character(len=*), parameter :: output_format = 'tmm-1.0'
  32. ! integer/real kinds
  33. integer, parameter :: iknd = 4 ! integer
  34. integer, parameter :: rknd = 8 ! real
  35. integer, parameter :: iknd_ds = 2 ! integer for big ds
  36. integer, parameter :: rknd_ds = 4 ! real for big ds
  37. ! z compression
  38. character(len=*), parameter :: compression = 'deflate'
  39. integer, parameter :: deflate_level = 6
  40. !--- type ---------------------------------
  41. type TMeteoFile_hdf
  42. ! input/output ?
  43. character(len=1) :: io
  44. !
  45. ! field collection
  46. !
  47. character(len=64) :: form
  48. character(len=256) :: fname
  49. type(THdfFile) :: hdf
  50. character(len=256) :: paramkeys
  51. type(TDate) :: trange(2)
  52. !
  53. ! file
  54. !
  55. type(TSds) :: sds
  56. logical :: selected
  57. character(len=16) :: paramkey
  58. !
  59. ! pw specials
  60. !
  61. logical :: mfw_redir
  62. !
  63. ! surface stress specials
  64. !
  65. logical :: sstr_to_ewss_nsss
  66. !
  67. ! surface pressure field
  68. !
  69. logical :: spm_load ! load spm ?
  70. logical :: spm_selected ! data set filled ?
  71. type(TSds) :: spm_sds ! data set for sp
  72. logical :: spm_incl ! record included in main file ?
  73. logical :: spm_extr ! record in external spm file ?
  74. character(len=256) :: spm_fname
  75. type(THdfFile) :: spm_hdf
  76. logical :: spm_n_to_uv
  77. !
  78. ! output
  79. !
  80. logical :: output_initialised
  81. integer :: output_nrec
  82. integer :: output_ntrec
  83. character(len=20) :: output_names(20)
  84. integer :: output_nname
  85. !
  86. ! adhoc ...
  87. integer :: fixyear
  88. logical :: qad
  89. end type TMeteoFile_hdf
  90. ! --- interfaces -------------------------
  91. interface Init
  92. module procedure mf_Init
  93. end interface
  94. interface Done
  95. module procedure mf_Done
  96. end interface
  97. interface Get
  98. module procedure mf_Get
  99. end interface
  100. interface ReadRecord
  101. module procedure mf_ReadRecord
  102. end interface
  103. ! interface ReadEqvLatStuff
  104. ! module procedure mf_ReadEqvLatStuff
  105. ! end interface
  106. interface WriteRecord
  107. module procedure mf_WriteRecord_2d
  108. module procedure mf_WriteRecord_3d
  109. end interface
  110. contains
  111. ! ==============================================================
  112. subroutine mf_Init( mf, io, dir, archivekeys, paramkey, &
  113. tref, t1, t2, status )
  114. use GO, only : TDate, Set, Get, NewDate, AnyDate, IsAnyDate
  115. use GO, only : rTotal, operator(-), operator(>=)
  116. use GO, only : goVarValue, goWriteKeyNum
  117. ! --- in/out ----------------------------
  118. type(TMeteoFile_hdf), intent(out) :: mf
  119. character(len=1), intent(in) :: io
  120. character(len=*), intent(in) :: dir
  121. character(len=*), intent(in) :: archivekeys
  122. character(len=*), intent(in) :: paramkey
  123. type(TDate), intent(in) :: tref, t1, t2
  124. integer, intent(out) :: status
  125. ! --- const --------------------------------------
  126. character(len=*), parameter :: rname = mname//'/mf_Init'
  127. ! --- local --------------------------------
  128. character(len=64) :: mf_mdir, mf_tres
  129. character(len=64) :: mf_class, mf_type, mf_grid, mf_levs
  130. character(len=1) :: mf_psep, mf_nsep
  131. character(len=64) :: mf_filekey
  132. character(len=4) :: mf_fckey
  133. type(TDate) :: tfile
  134. integer :: ccyy, mm, dd, dh
  135. type(TDate) :: tc
  136. logical :: exist
  137. ! --- begin --------------------------------
  138. ! store i/o :
  139. mf%io = io
  140. ! default flags:
  141. mf%sstr_to_ewss_nsss = .false.
  142. mf%mfw_redir = .false.
  143. !
  144. ! extract fields from archivekey :
  145. ! mdir=ec-fg_3h-ml60-glb3x2;tres=_21p06
  146. !
  147. mf%form = 'tmpp'
  148. call goVarValue( archivekeys, ';', 'form', '=', mf%form, status )
  149. if (status>0) then; TRACEBACK; status=1; return; end if
  150. !
  151. mf%fixyear = -1
  152. call goVarValue( archivekeys, ';', 'fixyear', '=', mf%fixyear, status )
  153. if (status>0) then; TRACEBACK; status=1; return; end if
  154. ! tmpp or tm5 hdf files ?
  155. select case ( mf%form )
  156. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  157. case ( 'tmpp' )
  158. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  159. mf_tres = 'no_tres'
  160. call goVarValue( archivekeys, ';', 'tres', '=', mf_tres, status )
  161. if (status>0) then; TRACEBACK; status=1; return; end if
  162. !
  163. mf_class = 'no_class'
  164. call goVarValue( archivekeys, ';', 'class', '=', mf_class, status )
  165. if (status>0) then; TRACEBACK; status=1; return; end if
  166. !
  167. mf_type = 'no_type'
  168. call goVarValue( archivekeys, ';', 'type', '=', mf_type, status )
  169. if (status>0) then; TRACEBACK; status=1; return; end if
  170. !
  171. mf_grid = 'no_grid'
  172. call goVarValue( archivekeys, ';', 'grid', '=', mf_grid, status )
  173. if (status>0) then; TRACEBACK; status=1; return; end if
  174. !
  175. mf_levs = 'no_mlevs'
  176. call goVarValue( archivekeys, ';', 'levs', '=', mf_levs, status )
  177. if (status>0) then; TRACEBACK; status=1; return; end if
  178. !
  179. ! path seperation character:
  180. mf_psep = '/'
  181. call goVarValue( archivekeys, ';', 'pathsep', '=', mf_psep, status )
  182. if (status>0) then; TRACEBACK; status=1; return; end if
  183. !
  184. ! name seperation character:
  185. mf_nsep = '-'
  186. call goVarValue( archivekeys, ';', 'namesep', '=', mf_nsep, status )
  187. if (status>0) then; TRACEBACK; status=1; return; end if
  188. !
  189. ! quick and dirty time checks ?
  190. mf%qad = .false.
  191. !call goVarValue( archivekeys, ';', 'qad', '=', mf%qad, status )
  192. !if (status>0) then; TRACEBACK; status=1; return; end if
  193. !
  194. ! adhoc flag
  195. mf%sstr_to_ewss_nsss = .false.
  196. call goVarValue( archivekeys, ';', 'sstr', '=', mf%sstr_to_ewss_nsss, status )
  197. if (status>0) then; TRACEBACK; status=1; return; end if
  198. !
  199. ! main file
  200. !
  201. ! by default, no surface pressure stuff ...
  202. mf%spm_load = .false.
  203. mf%spm_incl = .false. ! no spm fields included in hdf file
  204. mf%spm_extr = .false. ! no extra spm file
  205. mf%spm_n_to_uv = .false. ! no interpolation from 'n' to 'u' or 'v'
  206. ! default time resolution for tmpp produced files:
  207. mf_tres = '_21p06'
  208. ! * set mf_filekey (uvsp,t,etc) and parmeters:
  209. select case ( paramkey )
  210. case ( 'sp', 'pu', 'pv', 'mfu', 'mfv' )
  211. mf_filekey = 'uvsp'
  212. mf%paramkeys = '-sp-pu-pv-mfu-mfv-'
  213. mf%spm_load = .true.
  214. case ( 'pw', 'mfw' )
  215. mf_filekey = 'w'
  216. mf%paramkeys = '-pw-mfw-'
  217. mf%spm_load = .true.
  218. case ( 'T' )
  219. mf_filekey = 't'
  220. mf%paramkeys = '-T-'
  221. mf%spm_load = .true.
  222. case ( 'Q' )
  223. mf_filekey = 'q'
  224. mf%paramkeys = '-Q-'
  225. mf%spm_load = .true.
  226. case ( 'CLWC', 'CIWC', 'CC', 'CCO', 'CCU', &
  227. 'clwc', 'ciwc', 'cc', 'cco', 'ccu' )
  228. mf_filekey = 'cld'
  229. mf%paramkeys = '-CLWC-CIWC-CC-CCO-CCU-'
  230. mf%spm_load = .true.
  231. case ( 'eu', 'ed', 'du', 'dd', 'cloud_base', 'cloud_top', 'cloud_lfs' )
  232. mf_filekey = 'sub'
  233. mf%paramkeys = '-eu-ed-du-dd-cloud_base-cloud_top-cloud_lfs-'
  234. mf%spm_load = .true.
  235. case ( 'oro', 'lsm', 'sr', 'srols', 'srmer', &
  236. 'cvl', 'cvh', &
  237. 'tv01', 'tv02', 'tv03', 'tv04', 'tv05', &
  238. 'tv06', 'tv07', 'tv08', 'tv09', 'tv10', &
  239. 'tv11', 'tv12', 'tv13', 'tv14', 'tv15', &
  240. 'tv16', 'tv17', 'tv18', 'tv19', 'tv20', &
  241. 'swvl1', &
  242. 'albedo', 'lsrh', 'ci', 'g10m', 'u10m', 'v10m', 'sd', &
  243. 'lsp', 'cp', 'sf', 'sshf', 'slhf', 'blh', &
  244. 't2m', 'd2m', 'ssr', 'sstr', 'src', 'raero', 'ustar', &
  245. 'sst', 'sps', &
  246. 'ewss', 'nsss' )
  247. mf_levs = 'sfc'
  248. mf_grid = 'glb1x1'
  249. mf_filekey = 'surf'
  250. mf_tres = '_21p03'
  251. mf%paramkeys= '-'
  252. mf%paramkeys= trim(mf%paramkeys)//'oro-lsm-sr-srols-srmer-'
  253. mf%paramkeys= trim(mf%paramkeys)//'cvl-cvh-'
  254. mf%paramkeys= trim(mf%paramkeys)//'tv01-tv02-tv03-tv04-tv05-'
  255. mf%paramkeys= trim(mf%paramkeys)//'tv06-tv07-tv08-tv09-tv10-'
  256. mf%paramkeys= trim(mf%paramkeys)//'tv11-tv12-tv13-tv14-tv15-'
  257. mf%paramkeys= trim(mf%paramkeys)//'tv16-tv17-tv18-tv19-tv20-'
  258. mf%paramkeys= trim(mf%paramkeys)//'swvl1-'
  259. mf%paramkeys= trim(mf%paramkeys)//'albedo-lsrh-ci-10fg-u10m-v10m-sd-'
  260. mf%paramkeys= trim(mf%paramkeys)//'lsp-cp-sf-sshf-slhf-blh-'
  261. mf%paramkeys= trim(mf%paramkeys)//'t2m-d2m-ssr-sstr-src-raero-ustar-'
  262. mf%paramkeys= trim(mf%paramkeys)//'sst-sps-'
  263. mf%paramkeys= trim(mf%paramkeys)//'ewss-nsss-'
  264. case ( 'spm' )
  265. mf_levs = 'ml1'
  266. mf_filekey = 'spm'
  267. mf_tres = '_00p06'
  268. mf%paramkeys = '-spm-'
  269. case default
  270. write (gol,'("unsupported paramkey `",a,"`")') paramkey; call goErr
  271. TRACEBACK; status=1; return
  272. end select
  273. ! convert input times to file name times:
  274. call GetTime( mf_filekey, mf_tres, tref, t1, t2, status, &
  275. tfile=tfile, trange=mf%trange )
  276. IF_NOTOK_RETURN(status=1)
  277. ! adhoc: fixed year ?
  278. if ( mf%fixyear > 0 ) call Set( tfile, year=mf%fixyear )
  279. ! extract time values:
  280. call Get( tfile, year=ccyy, month=mm, day=dd )
  281. ! main file:
  282. write (mf%fname,'(a,a,a,a,a,a,i4.4,a,i2.2,a,a,a,a,a,a,"_",i4.4,2i2.2,a,a)') &
  283. trim(dir), mf_psep, &
  284. trim(mf_class), mf_nsep, trim(mf_type), mf_nsep, &
  285. ccyy, mf_nsep, mm, mf_nsep, trim(mf_levs), mf_nsep, trim(mf_grid), mf_nsep, &
  286. trim(mf_filekey), ccyy, mm, dd, trim(mf_tres), '.hdf'
  287. ! pw specials
  288. mf%mfw_redir = .true.
  289. ! load surface pressure with 3d field ?
  290. if ( mf%spm_load ) then
  291. ! external surface pressure file:
  292. mf%spm_extr = .true.
  293. write (mf%spm_fname,'(a,a,a,a,a,a,i4.4,a,i2.2,a,a,a,a,a,a,"_",i4.4,2i2.2,a,a)') &
  294. trim(dir), mf_psep, &
  295. trim(mf_class), mf_nsep, trim(mf_type), mf_nsep, &
  296. ccyy, mf_nsep, mm, mf_nsep, 'ml1', mf_nsep, trim(mf_grid), mf_nsep, &
  297. 'spm', ccyy, mm, dd, '_00p06', '.hdf'
  298. ! only cell surface pressure in tmpp output ...
  299. mf%spm_n_to_uv = .true.
  300. end if
  301. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  302. case ( 'tm5' )
  303. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  304. mf_mdir = 'no_mdir'
  305. call goVarValue( archivekeys, ';', 'mdir', '=', mf_mdir, status )
  306. if (status>0) then; TRACEBACK; status=1; return; end if
  307. !
  308. mf_tres = 'no_tres'
  309. call goVarValue( archivekeys, ';', 'tres', '=', mf_tres, status )
  310. if (status>0) then; TRACEBACK; status=1; return; end if
  311. !
  312. ! path seperation character:
  313. mf_psep = '/'
  314. call goVarValue( archivekeys, ';', 'pathsep', '=', mf_psep, status )
  315. if (status>0) then; TRACEBACK; status=1; return; end if
  316. !
  317. ! name seperation character:
  318. mf_nsep = '-'
  319. call goVarValue( archivekeys, ';', 'namesep', '=', mf_nsep, status )
  320. if (status>0) then; TRACEBACK; status=1; return; end if
  321. !
  322. ! adhoc flag
  323. mf%sstr_to_ewss_nsss = .false.
  324. call goVarValue( archivekeys, ';', 'sstr', '=', mf%sstr_to_ewss_nsss, status )
  325. if (status>0) then; TRACEBACK; status=1; return; end if
  326. !
  327. ! main file
  328. !
  329. ! by default, no surface pressure stuff ...
  330. mf%spm_load = .false.
  331. mf%spm_incl = .false. ! no spm fields included in hdf file
  332. mf%spm_extr = .false. ! no extra spm file
  333. mf%spm_n_to_uv = .false. ! no interpolation from 'n' to 'u' or 'v'
  334. ! * set mf_filekey (uvsp,t,etc) and parmeters:
  335. select case ( paramkey )
  336. case ( 'sp', 'tsp' )
  337. mf_filekey = paramkey
  338. mf%paramkeys = '-'//trim(paramkey)//'-'
  339. mf%spm_load = .false.
  340. case ( 'spm' )
  341. mf_levs = 'ml1'
  342. mf_filekey = 'spm'
  343. mf_tres = '_00p06'
  344. mf%paramkeys = '-spm-'
  345. case ( 'mfu', 'mfv' )
  346. mf_filekey = 'mfuv'
  347. mf%paramkeys = '-mfu-mfv-'
  348. mf%spm_load = .true.
  349. case ( 'mfw' )
  350. mf_filekey = 'mfw'
  351. mf%paramkeys = '-mfw-'
  352. mf%spm_load = .true.
  353. case ( 'T' )
  354. mf_filekey = 't'
  355. mf%paramkeys = '-T-'
  356. mf%spm_load = .true.
  357. case ( 'Q' )
  358. mf_filekey = 'q'
  359. mf%paramkeys = '-Q-'
  360. mf%spm_load = .true.
  361. case ( 'CLWC', 'CIWC', 'CC', 'CCO', 'CCU', &
  362. 'clwc', 'ciwc', 'cc', 'cco', 'ccu' )
  363. mf_filekey = 'cld'
  364. mf%paramkeys = '-CLWC-CIWC-CC-CCO-CCU-'
  365. mf%spm_load = .true.
  366. case ( 'eu', 'ed', 'du', 'dd', 'cloud_base', 'cloud_top', 'cloud_lfs' )
  367. mf_filekey = 'sub'
  368. mf%paramkeys = '-eu-ed-du-dd-cloud_base-cloud_top-cloud_lfs-'
  369. mf%spm_load = .true.
  370. ! o constant fields
  371. case ( 'oro', 'lsm' )
  372. mf_tres = 'constant'
  373. mf_filekey = trim(paramkey)
  374. mf%paramkeys = '-'//trim(paramkey)//'-'
  375. mf%spm_load = .false.
  376. ! o monthly fields:
  377. case ( 'srols' )
  378. mf_tres = 'month'
  379. mf_filekey = trim(paramkey)
  380. mf%paramkeys = '-'//trim(paramkey)//'-'
  381. mf%spm_load = .false.
  382. ! o vegetation fields
  383. case ( 'cvl', 'cvh', &
  384. 'tv01', 'tv02', 'tv03', 'tv04', 'tv05', &
  385. 'tv06', 'tv07', 'tv08', 'tv09', 'tv10', &
  386. 'tv11', 'tv12', 'tv13', 'tv14', 'tv15', &
  387. 'tv16', 'tv17', 'tv18', 'tv19', 'tv20' )
  388. mf_filekey = 'veg'
  389. mf%paramkeys= '-'
  390. mf%paramkeys= trim(mf%paramkeys)//'cvl-cvh-'
  391. mf%paramkeys= trim(mf%paramkeys)//'tv01-tv02-tv03-tv04-tv05-'
  392. mf%paramkeys= trim(mf%paramkeys)//'tv06-tv07-tv08-tv09-tv10-'
  393. mf%paramkeys= trim(mf%paramkeys)//'tv11-tv12-tv13-tv14-tv15-'
  394. mf%paramkeys= trim(mf%paramkeys)//'tv16-tv17-tv18-tv19-tv20-'
  395. mf%spm_load = .false.
  396. ! o each surface file in a seperate file;
  397. ! might be collected in surf_*.tar files afterwards
  398. case ( 'sr', 'srmer', &
  399. 'swvl1', &
  400. 'albedo', 'lsrh', 'ci', 'g10m', 'u10m', 'v10m', 'sd', &
  401. 'lsp', 'cp', 'sf', 'sshf', 'slhf', 'blh', &
  402. 't2m', 'd2m', 'ssr', 'ssrd', 'str', 'strd', &
  403. 'sstr', 'src', 'raero', 'ustar', &
  404. 'sst', 'sps', 'skt', &
  405. 'ch4fire' )
  406. mf_filekey = trim(paramkey)
  407. mf%paramkeys = '-'//trim(paramkey)//'-'
  408. mf%spm_load = .false.
  409. case ( 'ewss', 'nsss' )
  410. if ( mf%sstr_to_ewss_nsss ) then
  411. mf_filekey = 'sstr'
  412. mf%paramkeys = '-sstr-'
  413. else
  414. mf_filekey = trim(paramkey)
  415. mf%paramkeys = '-'//trim(paramkey)//'-'
  416. end if
  417. mf%spm_load = .false.
  418. case default
  419. write (gol,'("unsupported paramkey `",a,"`")') paramkey; call goErr
  420. TRACEBACK; status=1; return
  421. end select
  422. ! convert input times to file name times:
  423. call GetTime( mf_filekey, mf_tres, tref, t1, t2, status, &
  424. tfile=tfile, trange=mf%trange )
  425. IF_NOTOK_RETURN(status=1)
  426. ! adhoc: fixed year ?
  427. if ( mf%fixyear > 0 ) call Set( tfile, year=mf%fixyear )
  428. ! extract time values:
  429. call Get( tfile, year=ccyy, month=mm, day=dd )
  430. ! special data set: trap change from fg to fc data:
  431. if ( mf_tres == '_fg006up4tr3' ) then
  432. tc = NewDate( 2000, 09, 12 )
  433. if ( tfile >= tc ) mf_tres = '_fc012up2tr3'
  434. end if
  435. ! forecast key: '', 'f1', .., 'f10' ;
  436. ! no key for constant files (t1 and t2 are anydate)
  437. ! or month files (t1 is begin of month thus probably < tref)
  438. mf_fckey = ''
  439. if ( (.not. IsAnyDate(t1)) .and. (t1 >= tref) ) then
  440. dh = floor( rTotal( t1 - tref, 'day' ) )
  441. if ( dh > 0 ) call goWriteKeyNum( mf_fckey, 'f', dh )
  442. end if
  443. ! create file name:
  444. ! dir / ec_od-ml60-T159 - oro.hdf
  445. ! dir / ec_od-ml60-T159 - T_20000101_fg006up4tr3.hdf
  446. select case ( mf_tres )
  447. case ( 'constant' )
  448. ! filename without date:
  449. write (mf%fname,'(a,a,a,a,a,".hdf")') trim(dir), mf_psep, trim(mf_mdir), mf_nsep, trim(mf_filekey)
  450. case ( 'month' )
  451. ! filename without day and forecast key:
  452. write (mf%fname,'(a,a,a,a,a,"_",i4.4,i2.2,a)') &
  453. trim(dir), mf_psep, trim(mf_mdir), mf_nsep, trim(mf_filekey), ccyy, mm, '.hdf'
  454. case default
  455. ! filename including date:
  456. write (mf%fname,'(a,a,a,a,a,"_",i4.4,2i2.2,a,a,a)') &
  457. trim(dir), mf_psep, trim(mf_mdir), mf_nsep, &
  458. trim(mf_filekey), ccyy, mm, dd, trim(mf_fckey), trim(mf_tres), '.hdf'
  459. ! trap request for sps ; might be in sp file ...
  460. if ( trim(mf_filekey) == 'sps' ) then
  461. inquire( file=trim(mf%fname), exist=exist )
  462. if ( .not. exist ) then
  463. write (mf%fname,'(a,a,a,a,a,"_",i4.4,2i2.2,a,a,a)') &
  464. trim(dir), mf_psep, trim(mf_mdir), mf_nsep, &
  465. 'sp', ccyy, mm, dd, trim(mf_fckey), trim(mf_tres), '.hdf'
  466. end if
  467. end if
  468. end select
  469. ! spm is included in files ...
  470. mf%spm_incl = mf%spm_load ! used to be external, now included
  471. mf%spm_fname = mf%fname ! same file
  472. mf%spm_extr = .false. ! not external for sure ...
  473. ! in case of output, not initialised yet ...
  474. mf%output_initialised = .false.
  475. mf%output_nname = 0
  476. ! number of expected time records in a file:
  477. call GetTime( mf_filekey, mf_tres, tref, t1, t2, status, nrec=mf%output_ntrec )
  478. IF_NOTOK_RETURN(status=1)
  479. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  480. case default
  481. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  482. write (gol,'("unsupported form `",a,"`")') trim(mf%form); call goErr
  483. TRACEBACK; status=1; return
  484. end select
  485. ! ok
  486. status = 0
  487. end subroutine mf_Init
  488. ! ***
  489. subroutine mf_Done( mf, status )
  490. !use file_hdf, only : Done
  491. ! --- in/out ------------------------------------
  492. type(TMeteoFile_hdf), intent(inout) :: mf
  493. integer, intent(out) :: status
  494. ! --- const --------------------------------------
  495. character(len=*), parameter :: rname = mname//'/mf_Done'
  496. ! --- begin -------------------------------------
  497. ! files have been closed in ReadRecord/WriteRecord
  498. ! ok
  499. status = 0
  500. end subroutine mf_Done
  501. ! ***
  502. subroutine mf_Get( mf, status, trange1, trange2, paramkeys )
  503. use GO, only : TDate
  504. ! --- in/out ----------------------------
  505. type(TMeteoFile_hdf), intent(in) :: mf
  506. integer, intent(out) :: status
  507. type(TDate), intent(out), optional :: trange1, trange2
  508. character(len=*), intent(out), optional :: paramkeys
  509. ! --- const --------------------------------------
  510. character(len=*), parameter :: rname = mname//'/mf_Get'
  511. ! --- local --------------------------------
  512. ! --- begin --------------------------------
  513. ! time range:
  514. if ( present(trange1) ) trange1 = mf%trange(1)
  515. if ( present(trange2) ) trange2 = mf%trange(2)
  516. ! parameter names:
  517. if ( present(paramkeys) ) paramkeys = mf%paramkeys
  518. ! ok
  519. status = 0
  520. end subroutine mf_Get
  521. ! ******************************************************************
  522. ! ***
  523. ! *** time range, parameters, file names
  524. ! ***
  525. ! ******************************************************************
  526. ! !
  527. ! ! Archive type:
  528. ! ! 'tmpp' : year and month are inserted in directory names,
  529. ! ! thus archive name 'od-fc-ml60-glb3x2'
  530. ! ! becomes 'od-fc-2000-01ml60-glb3x2' .
  531. ! ! 'tm5' : archivename contains var=value pairs:
  532. ! ! mdir=ec-fg_3h-ml60-glb3x2;tres=_00p06
  533. ! !
  534. !
  535. ! subroutine mf_hdf_GetKeys( archivetype, archivename, &
  536. ! paramkey, t1, t2, dirname, &
  537. ! mf_t1, mf_t2, mf_paramkeys, &
  538. ! mf_filename, mf_spm_filename, &
  539. ! status )
  540. !
  541. ! use GO, only : goSplitLine, goReadFromLine
  542. ! use GO, only : TDate, IncrDate, Get, NewDate, wrtgol, &
  543. ! Operator(+), Operator(-), Operator(/)
  544. !
  545. ! ! --- in/out -------------------------------------
  546. !
  547. ! character(len=*), intent(in) :: archivetype
  548. ! character(len=*), intent(in) :: archivename
  549. ! character(len=*), intent(in) :: paramkey
  550. ! type(TDate), intent(in) :: t1, t2
  551. ! character(len=*), intent(in) :: dirname
  552. !
  553. ! type(TDate), intent(out) :: mf_t1, mf_t2
  554. ! character(len=*), intent(out) :: mf_paramkeys
  555. ! character(len=*), intent(out) :: mf_filename
  556. ! character(len=*), intent(out) :: mf_spm_filename
  557. ! integer, intent(inout) :: status
  558. !
  559. ! ! --- const -------------------------------------
  560. !
  561. ! character(len=*), parameter :: rname = mname//'/mf_hdf_GetKeys'
  562. !
  563. ! ! --- local -------------------------------------
  564. !
  565. ! integer :: year1, month1, day1, hour1
  566. ! integer :: year2, month2, day2
  567. !
  568. ! character(len=100) :: archivenameX
  569. ! character(len=100) :: archivenameX_spm
  570. ! character(len=10) :: mclass
  571. ! character(len=10) :: mtype
  572. ! character(len=10) :: mlevs
  573. ! character(len=10) :: mgrid
  574. ! character(len=10) :: filekey
  575. ! character(len=10) :: treskey
  576. ! logical :: with_spm
  577. !
  578. ! character(len=256) :: archivekeys2
  579. ! character(len=64) :: varval
  580. ! character(len=64) :: var, val
  581. ! character(len=16) :: tm5_mdir, tm5_treskey
  582. !
  583. ! ! --- begin -------------------------------------
  584. !
  585. ! ! extract time values:
  586. ! call Get( t1, year=year1, month=month1, day=day1, hour=hour1 )
  587. !
  588. ! ! time range: [21,21]
  589. ! ! * set t1 to 21:00 previous day = 00:00 today minus 3 hour
  590. ! if ( hour1 < 21 ) then
  591. ! mf_t1 = NewDate( year=year1, month=month1, day=day1, hour=0 )
  592. ! mf_t1 = mf_t1 - IncrDate(hour=3)
  593. ! else
  594. ! mf_t1 = NewDate( year=year1, month=month1, day=day1, hour=21 )
  595. ! end if
  596. ! ! * set t2 to 21:00 today:
  597. ! mf_t2 = mf_t1 + IncrDate(hour=24)
  598. ! ! * date in file name is today:
  599. ! call Get( mf_t2, year=year2, month=month2, day=day2 )
  600. !
  601. ! !call wrtgol( ' fields valid from : ', mf%t1 )
  602. ! !call wrtgol( ' to : ', mf%t2 )
  603. !
  604. ! ! file type, name, params, ...
  605. ! ! * archivename (directory)
  606. ! select case ( archivetype )
  607. ! case ( 'tmpp' )
  608. ! archivenameX = archivename
  609. ! call goReadFromLine( archivenameX, mclass, sep='-' )
  610. ! call goReadFromLine( archivenameX, mtype , sep='-' )
  611. ! call goReadFromLine( archivenameX, mlevs , sep='-' )
  612. ! call goReadFromLine( archivenameX, mgrid , sep='-' )
  613. ! case ( 'tm5' )
  614. ! ! default values:
  615. ! tm5_mdir = 'xx'
  616. ! tm5_treskey = '_tres'
  617. ! ! overwrite with values in archivekey:
  618. ! archivekeys2 = archivename
  619. ! do
  620. ! ! no keys left ? then leave
  621. ! if ( len_trim(archivekeys2) == 0 ) exit
  622. ! ! extract var=value:
  623. ! call goReadFromLine( archivekeys2, varval, sep=';' )
  624. ! ! split in var and value:
  625. ! call goSplitLine( varval, var, '=', val )
  626. ! ! store:
  627. ! select case ( var )
  628. ! case ( 'mdir' ) ; tm5_mdir = trim(val)
  629. ! case ( 'treskey' ) ; tm5_treskey = trim(val)
  630. ! case default
  631. ! write (gol,'("unsupported archive key `",a,"`")') trim(varval); call goErr
  632. ! write (gol,'(" ",a)') trim(archivekeys); call goErr
  633. ! TRACEBACK; status=1; return
  634. ! end select
  635. ! end do
  636. ! case default
  637. ! write (gol,'("unsupported archivetype `",a,"`")') trim(archivetype); call goErr
  638. ! TRACEBACK; status=1; return
  639. ! end select
  640. ! ! * other
  641. ! treskey = '_21p06'
  642. ! with_spm = .true.
  643. ! ! * overwrite some fields:
  644. ! select case ( paramkey )
  645. ! case ( 'sp', 'pu', 'pv' )
  646. ! filekey = 'uvsp'
  647. ! mf_paramkeys = '-sp-pu-pv-'
  648. ! case ( 'T' )
  649. ! filekey = 't'
  650. ! mf_paramkeys = '-T-'
  651. ! case ( 'Q' )
  652. ! filekey = 'q'
  653. ! mf_paramkeys= '-Q-'
  654. ! case ( 'CLWC', 'CIWC', 'CC', 'CCO', 'CCU' )
  655. ! filekey = 'cld'
  656. ! mf_paramkeys= '-CLWC-CIWC-CC-CCO-CCU-'
  657. ! case ( 'eu', 'ed', 'du', 'dd', 'cloud_base', 'cloud_top', 'cloud_lfs' )
  658. ! filekey = 'sub'
  659. ! mf_paramkeys= '-eu-ed-du-dd-cloud_base-cloud_top-cloud_lfs-'
  660. ! case ( 'oro', 'lsm', 'sr_ecm', 'sr_ols', 'sr_mer', &
  661. ! 'cvl', 'cvh', &
  662. ! 'tv01', 'tv02', 'tv03', 'tv04', 'tv05', &
  663. ! 'tv06', 'tv07', 'tv08', 'tv09', 'tv10', &
  664. ! 'tv11', 'tv12', 'tv13', 'tv14', 'tv15', &
  665. ! 'tv16', 'tv17', 'tv18', 'tv19', 'tv20', &
  666. ! 'swvl1', &
  667. ! 'al', 'lsrh', 'ci', '10fg', 'u10m', 'v10m', 'sd', &
  668. ! 'lsp', 'cp', 'sf', 'sshf', 'slhf', 'blh', &
  669. ! 't2m', 'd2m', 'ssr', 'sstr', 'src', 'raero', 'ustar' )
  670. ! mlevs = 'sfc'
  671. ! mgrid = 'glb1x1'
  672. ! filekey = 'surf'
  673. ! treskey = '_21p03'
  674. ! mf_paramkeys= '-'
  675. ! mf_paramkeys= trim(mf_paramkeys)//'oro-lsm-sr_ecm-sr_ols-sr_mer-'
  676. ! mf_paramkeys= trim(mf_paramkeys)//'cvl-cvh-'
  677. ! mf_paramkeys= trim(mf_paramkeys)//'tv01-tv02-tv03-tv04-tv05-'
  678. ! mf_paramkeys= trim(mf_paramkeys)//'tv06-tv07-tv08-tv09-tv10-'
  679. ! mf_paramkeys= trim(mf_paramkeys)//'tv11-tv12-tv13-tv14-tv15-'
  680. ! mf_paramkeys= trim(mf_paramkeys)//'tv16-tv17-tv18-tv19-tv20-'
  681. ! mf_paramkeys= trim(mf_paramkeys)//'swvl1-'
  682. ! mf_paramkeys= trim(mf_paramkeys)//'al-lsrh-ci-10fg-u10m-v10m-sd-'
  683. ! mf_paramkeys= trim(mf_paramkeys)//'lsp-cp-sf-sshf-slhf-blh-'
  684. ! mf_paramkeys= trim(mf_paramkeys)//'t2m-d2m-ssr-sstr-src-raero-ustar-'
  685. ! with_spm = .false.
  686. ! case ( 'spm' )
  687. ! mlevs = 'ml1'
  688. ! filekey = 'spm'
  689. ! treskey = '_00p06'
  690. ! mf_paramkeys= '-spm-'
  691. ! case default
  692. ! write (gol,'("unsupported tmpp paramkey `",a,"`")') paramkey; call goErr
  693. ! TRACEBACK; status=1; return
  694. ! end select
  695. ! ! * create archive names:
  696. ! select case ( archivetype )
  697. ! case ( 'tmpp' )
  698. ! write (archivenameX,'(a,"-",a,"-",i4.4,"-",i2.2,"-",a,"-",a)') &
  699. ! trim(mclass), trim(mtype), year2, month2, trim(mlevs), trim(mgrid)
  700. ! write (archivenameX_spm,'(a,"-",a,"-",i4.4,"-",i2.2,"-",a,"-",a)') &
  701. ! trim(mclass), trim(mtype), year2, month2, 'ml1', trim(mgrid)
  702. ! case ( 'tm5' )
  703. ! archivenameX = tm5_mdir
  704. ! archivenameX_spm = tm5_mdir
  705. ! treskey = tm5_treskey
  706. ! case default
  707. ! write (gol,'("unsupported archivetype `",a,"`")') trim(archivetype); call goErr
  708. ! TRACEBACK; status=1; return
  709. ! end select
  710. ! ! * create filenames
  711. ! write (mf_filename,'(a,"/",a,"-",a,"_",i4.4,i2.2,i2.2,a,".hdf")') &
  712. ! trim(dirname), trim(archivenameX), &
  713. ! trim(filekey), year2, month2, day2, trim(treskey)
  714. ! if ( with_spm ) then
  715. ! write (mf_spm_filename,'(a,"/",a,"-",a,"_",i4.4,i2.2,i2.2,a,".hdf")') &
  716. ! trim(dirname), trim(archivenameX_spm), &
  717. ! 'spm', year2, month2, day2, '_00p06'
  718. ! else
  719. ! mf_spm_filename = 'none'
  720. ! endif
  721. !
  722. ! ! ok
  723. ! status = 0
  724. !
  725. ! end subroutine mf_hdf_GetKeys
  726. ! ***
  727. !
  728. ! Return time parameters:
  729. ! o tfile : date in filename
  730. ! o trange : time interval covered by fields in file
  731. !
  732. subroutine GetTime( filekey, tres, tref, t1, t2, status, tfile, trange, nrec )
  733. use GO, only : TDate, NewDate, AnyDate, Get, Set, wrtgol, IncrDate, IsAnyDate
  734. use GO, only : operator(<), operator(+), operator(-), rTotal
  735. ! --- in/out --------------------------------
  736. character(len=*), intent(in) :: filekey
  737. character(len=*), intent(in) :: tres
  738. type(TDate), intent(in) :: tref, t1, t2
  739. integer, intent(out) :: status
  740. type(TDate), intent(out), optional :: tfile
  741. type(TDate), intent(out), optional :: trange(2)
  742. integer, intent(out), optional :: nrec
  743. ! --- const --------------------------------------
  744. character(len=*), parameter :: rname = mname//'/GetTime'
  745. ! --- local --------------------------------
  746. integer :: year, month
  747. integer :: hour1, time6(6)
  748. integer :: dd, hh, step
  749. logical :: interval
  750. real :: dhr
  751. ! --- begin --------------------------------
  752. ! set day shift, start hour, and step
  753. select case ( tres )
  754. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  755. ! tmpp [21,21]
  756. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  757. case ( '_21p06', '_21p03', '_av21' )
  758. ! routine is called with tref,t1,t2:
  759. ! t1,t1,t2
  760. ! t1,any,any (oro and other constant fields)
  761. ! thus use tref to construct the file times
  762. if ( IsAnyDate(t1) ) then
  763. call Get( tref, hour=hour1 )
  764. interval = .false.
  765. else
  766. call Get( t1, hour=hour1 )
  767. interval = t1 < t2
  768. end if
  769. ! file ccyymmdd contains fields for (21,21];
  770. ! only uvsp is valid for [21,21] since it contains surface pressure for 21:00
  771. if ( present(tfile) ) then
  772. tfile = tref
  773. call Set( tfile, hour=0, min=0, sec=0 )
  774. if ( (hour1 > 21) .or. ((interval .or. filekey=='uvsp') .and. hour1==21) ) then
  775. tfile = tfile + IncrDate(day=1)
  776. end if
  777. end if
  778. ! fields by default valid for (21,21];
  779. ! only uvsp is valid for [21,21] since it contains surface pressure for 21:00
  780. if ( present(trange) ) then
  781. trange(1) = tref
  782. call Set( trange(1), hour=0, min=0, sec=0 ) ! 00:00 today
  783. if ( (hour1 > 21) .or. ((interval .or. filekey=='uvsp') .and. hour1==21) ) then
  784. trange(1) = trange(1) + IncrDate(day=1)
  785. end if
  786. trange(1) = trange(1) - IncrDate(hour=3) ! previous 21:00
  787. trange(2) = trange(1) + IncrDate(day=1) ! next 21:00
  788. ! boundary not included in most cases:
  789. if ( filekey /= 'uvsp' ) trange(1) = trange(1) + IncrDate(mili=1)
  790. end if
  791. ! number of records in file:
  792. if ( present(nrec) ) then
  793. select case ( tres )
  794. case ( '_21p06' ) ; nrec = 24/6
  795. case ( '_21p03' ) ; nrec = 24/3
  796. case ( '_av21' ) ; nrec = 24/24
  797. case default
  798. write (gol,'("unsupported tres for setting nrec : ",a)') tres; call goErr
  799. TRACEBACK; status=1; return
  800. end select
  801. end if
  802. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  803. ! tm5 constant
  804. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  805. case ( 'constant' )
  806. ! no date in filename ...
  807. if ( present(tfile) ) tfile = AnyDate()
  808. ! fields always valid ...
  809. if ( present(trange) ) then
  810. trange(1) = AnyDate()
  811. trange(2) = AnyDate()
  812. end if
  813. ! only one output record in constant file:
  814. if ( present(nrec) ) nrec = 1
  815. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  816. ! tm5 monthly file
  817. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  818. case ( 'month' )
  819. ! file ccyymmdd contains fields for this month:
  820. if ( present(tfile) ) then
  821. call Get( t1, year=year, month=month )
  822. tfile = NewDate( year=year, month=month, day=1 )
  823. end if
  824. ! field valid from begin to end of month:
  825. if ( present(trange) ) then
  826. call Get( t1, year=year, month=month )
  827. trange(1) = NewDate( year=year, month=month, day=1, hour=00 )
  828. month = month + 1
  829. if ( month > 12 ) then
  830. year = year + 1
  831. month = 1
  832. end if
  833. trange(2) = NewDate( year=year, month=month, day=1, hour=00 )
  834. end if
  835. ! only one output record in month file:
  836. if ( present(nrec) ) nrec = 1
  837. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  838. ! tm5 [00,24]
  839. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  840. case ( '_00p06', '_00p03', '_an0tr6', '_fg006up4tr3', '_fc012up2tr3', '_00p01' )
  841. ! file ccyymmdd contains fields for [00,24) :
  842. if ( present(tfile) ) then
  843. tfile = t1
  844. call Set( tfile, hour=0, min=0, sec=0 )
  845. end if
  846. ! fields valid for [00,24) :
  847. if ( present(trange) ) then
  848. trange(1) = t1
  849. call Set( trange(1), hour=0, min=0, sec=0 ) ! 00:00 today
  850. trange(2) = trange(1) + IncrDate(hour=24) - IncrDate(mili=1)
  851. end if
  852. ! number of records in file:
  853. if ( present(nrec) ) then
  854. select case ( tres )
  855. case ( '_00p06' ) ; nrec = 24/6
  856. case ( '_an0tr6' ) ; nrec = 24/6
  857. case ( '_00p03', '_fg006up4tr3', '_fc012up2tr3' )
  858. ! by default: 3 hourly files
  859. ! for forecasts after 12+72, only 6 hourly available:
  860. ! f0 [ 00, 24) : 00 03 06 09 12 15 18 21 : nrec=8
  861. ! f1 [ 24, 48) : 00 03 06 09 12 15 18 21 : nrec=8
  862. ! f2 [ 48, 72) : 00 03 06 09 12 15 18 21 : nrec=8
  863. ! f3 [ 72, 96) : 00 03 06 09 12 18 : nrec=6
  864. ! f4 [ 96,120) : 00 06 12 18 : nrec=4
  865. ! :
  866. ! f9 [192,216) : 00 06 12 18 : nrec=4
  867. ! f10 [216,240) : 00 06 12 : nrec=3
  868. dhr = rTotal( t1 - tref, 'hour' )
  869. if ( dhr < 72.0 ) then
  870. nrec = 8
  871. else if ( dhr < 96 ) then
  872. nrec = 4+2
  873. else if ( dhr < 216 ) then
  874. nrec = 4
  875. else
  876. nrec = 3
  877. end if
  878. case ( '_00p01' ) ; nrec = 24
  879. case default
  880. write (gol,'("unsupported tres for setting nrec : ",a)') tres; call goErr
  881. TRACEBACK; status=1; return
  882. end select
  883. end if
  884. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  885. ! ???
  886. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  887. case default
  888. write (gol,'("unsupported time resolution key:")'); call goErr
  889. write (gol,'(" ",a)') trim(tres); call goErr
  890. TRACEBACK; status=1; return
  891. end select
  892. ! ok
  893. status = 0
  894. end subroutine GetTime
  895. ! ******************************************************************
  896. ! ***
  897. ! *** input
  898. ! ***
  899. ! ******************************************************************
  900. subroutine mf_SelectRecord( mf, paramkey, t1, t2, status )
  901. use GO, only : TDate, NewDate, IncrDate, wrtgol, Set, Get, rTotal
  902. use GO, only : operator(-), operator(+), operator(/), operator(==), operator(/=)
  903. use GO, only : operator(>=), operator(<=), operator(>)
  904. use file_hdf, only : GetInfo
  905. use file_hdf, only : TSds, Select, CheckInfo, CheckAttribute, ReadAttribute
  906. ! --- in/out --------------------------------
  907. type(TMeteoFile_hdf), intent(inout) :: mf
  908. character(len=*), intent(in) :: paramkey
  909. type(TDate), intent(in) :: t1, t2
  910. integer, intent(out) :: status
  911. ! --- const --------------------------------------
  912. character(len=*), parameter :: rname = mname//'/mf_SelectRecord'
  913. ! --- local -------------------------------
  914. integer :: nsds, isds
  915. integer :: time1(6), time2(6)
  916. type(TDate) :: tmid, treq, thelp
  917. type(TDate) :: t_spm
  918. integer :: hour, dhour
  919. integer :: status1, status2
  920. integer :: time1s(6), time2s(6)
  921. type(TDate) :: tim1s, tim2s
  922. !! debug ...
  923. !character(len=64) :: xname
  924. !integer :: xtime1(6), xtime2(6)
  925. ! --- begin -------------------------------
  926. mf%selected = .false.
  927. ! initial no record is found ...
  928. status = 1
  929. ! number of data sets:
  930. call GetInfo( mf%hdf, status, num_datasets=nsds )
  931. if (status/=0) then; TRACEBACK; return; end if
  932. ! loop over all data sets
  933. do isds = 1, nsds
  934. !! debug ..
  935. !write (gol,'("DEBUG - isds = ",i6," / ",i6)') isds, nsds; call goPr
  936. call Select( mf%sds, mf%hdf, isds-1, status )
  937. if (status/=0) then; TRACEBACK; return; end if
  938. !! debug ..
  939. !call GetInfo( mf%sds, status, name=xname )
  940. !write (gol,'("DEBUG - sds name = ",a)') trim(xname); call goPr
  941. ! correct param ?
  942. status=-1; call CheckInfo( mf%sds, status, name=paramkey )
  943. if (status>0) then; TRACEBACK; status=1; return; end if
  944. ! adhoc: some data sets have other name ...
  945. if ( status < 0 ) then
  946. select case ( paramkey )
  947. case ( 'sp', 'spm' )
  948. status=-1; call CheckInfo( mf%sds, status, name='ps' )
  949. case ( 'sps' )
  950. status=-1; call CheckInfo( mf%sds, status, name='sp' )
  951. case ( 'mfu' )
  952. status=-1; call CheckInfo( mf%sds, status, name='pu' )
  953. case ( 'mfv' )
  954. status=-1; call CheckInfo( mf%sds, status, name='pv' )
  955. case ( 'mfw' )
  956. status=-1; call CheckInfo( mf%sds, status, name='pw' )
  957. case ( 'PVo' )
  958. status=-1; call CheckInfo( mf%sds, status, name='PV' )
  959. case ( 'sr' )
  960. status=-1; call CheckInfo( mf%sds, status, name='sr_ecm' )
  961. case ( 'srols' )
  962. status=-1; call CheckInfo( mf%sds, status, name='sr_ols' )
  963. case ( 'srmer' )
  964. status=-1; call CheckInfo( mf%sds, status, name='sr_mer' )
  965. case ( 'albedo' )
  966. status=-1; call CheckInfo( mf%sds, status, name='al' )
  967. case ( 'ewss', 'nsss' )
  968. if ( mf%sstr_to_ewss_nsss ) then
  969. status=-1; call CheckInfo( mf%sds, status, name='sstr' )
  970. end if
  971. end select
  972. if (status>0) then; TRACEBACK; status=1; return; end if
  973. ! try other data set ?
  974. if ( status < 0 ) cycle
  975. end if
  976. ! correct time ?
  977. select case ( paramkey )
  978. case ( 'oro' )
  979. ! constant field, skip time check
  980. case ( 'srols' )
  981. ! monthly field:
  982. ! in TMPP files: daily samples, valid for [21,21]
  983. ! in TM5 files: monthly value
  984. ! read time2 :
  985. call ReadAttribute( mf%sds, 'time2', time2s, status )
  986. if (status/=0) then; TRACEBACK; return; end if
  987. tim2s = NewDate( time6=time2s )
  988. ! [t1,t2] covers month; time2 should be in this month:
  989. if ( (t1 >= tim2s) .and. (tim2s <= t2) ) then
  990. ! ok
  991. status = 0
  992. end if
  993. case default
  994. ! extract time arrays:
  995. call Get( t1, time6=time1 )
  996. call Get( t2, time6=time2 )
  997. !
  998. ! replace year ?
  999. if ( mf%fixyear > 0 ) then
  1000. select case ( mf%form )
  1001. ! year is valid for time interval:
  1002. ! ( fixyear-1/12/31 21:00 , fixyear/12/31 21:00 ]
  1003. case ( 'tmpp' )
  1004. if ( t1 == t2 ) then
  1005. ! instant time
  1006. thelp = NewDate( year=time1(1), month=12, day=31, hour=21 )
  1007. if ( t1 > thelp ) then
  1008. time1(1) = mf%fixyear - 1
  1009. else
  1010. time1(1) = mf%fixyear
  1011. end if
  1012. time2 = time1
  1013. else
  1014. ! time interval
  1015. thelp = NewDate( year=time1(1), month=12, day=31, hour=21 )
  1016. if ( t1 >= thelp ) then
  1017. time1(1) = mf%fixyear - 1
  1018. else
  1019. time1(1) = mf%fixyear
  1020. end if
  1021. thelp = NewDate( time6=time1 ) + (t2-t1)
  1022. call Get( thelp, time6=time2 )
  1023. endif
  1024. ! year is valid for time interval:
  1025. ! [ fixyear/01/01 00:00 , fixyear/12/31 24:00 )
  1026. case ( 'tm5' )
  1027. if ( t1 == t2 ) then
  1028. ! instant time
  1029. time1(1) = mf%fixyear
  1030. time2 = time1
  1031. else
  1032. ! time interval
  1033. time1(1) = mf%fixyear
  1034. thelp = NewDate( time6=time1 ) + (t2-t1)
  1035. call Get( thelp, time6=time2 )
  1036. endif
  1037. ! unknown ..
  1038. case default
  1039. write (gol,'("fixyear : unsupported mf form : ",a)') trim(mf%form); call goErr
  1040. TRACEBACK; status=1; return
  1041. end select
  1042. end if
  1043. !
  1044. !! debug
  1045. !call ReadAttribute( mf%sds, 'time1', xtime1, status )
  1046. !call ReadAttribute( mf%sds, 'time2', xtime2, status )
  1047. !write (gol,'("DEBUG - sds time1 = ",i4,5i3)') xtime1; call goPr
  1048. !write (gol,'("DEBUG - sds time2 = ",i4,5i3)') xtime2; call goPr
  1049. !write (gol,'("DEBUG - request time1 = ",i4,5i3)') time1; call goPr
  1050. !write (gol,'("DEBUG - request time2 = ",i4,5i3)') time2; call goPr
  1051. !
  1052. if ( mf%qad ) then
  1053. ! test if times match exactly:
  1054. status1=-1 ; call CheckAttribute( mf%sds, 'time1', time1, status1 )
  1055. if (status1>0) then; TRACEBACK; status=1; return; end if
  1056. status2=-1 ; call CheckAttribute( mf%sds, 'time2', time2, status2 )
  1057. if (status2>0) then; TRACEBACK; status=1; return; end if
  1058. status = status1 + status2
  1059. ! times do not match ?
  1060. if ( status < 0 ) then
  1061. ! read time1 and time2 :
  1062. call ReadAttribute( mf%sds, 'time1', time1s, status )
  1063. if (status/=0) then; TRACEBACK; return; end if
  1064. call ReadAttribute( mf%sds, 'time2', time2s, status )
  1065. if (status/=0) then; TRACEBACK; return; end if
  1066. ! hours should match ...
  1067. if ( (time1s(4) /= time1(4)) .or. (time2s(4) /= time2(4)) ) then
  1068. status = -1
  1069. cycle
  1070. end if
  1071. ! warning ...
  1072. write (gol,'("WARNING - weak time check passed:")'); call goPr
  1073. write (gol,'("WARNING - parameter : ",a)') trim(paramkey); call goPr
  1074. call wrtgol( 'WARNING - t1 : ', t1 ); call goPr
  1075. call wrtgol( 'WARNING - t2 : ', t2 ); call goPr
  1076. write (gol,'("WARNING - file : ",a)') trim(mf%fname); call goPr
  1077. ! ok
  1078. status = 0
  1079. end if
  1080. ! weak time check passed
  1081. else
  1082. !! tmpp fields valid for [21,21] should be read as valid for [00,24] ...
  1083. !if ( rTotal(t2-t1,'hour') == 24.0 ) then
  1084. ! tim1s = t1 + IncrDate(hour=3)
  1085. ! tim2s = t2 + IncrDate(hour=3)
  1086. ! call Get( tim1s, time6=time1 )
  1087. ! call Get( tim2s, time6=time2 )
  1088. !end if
  1089. ! first try wether times exactely match;
  1090. status1=-1 ; call CheckAttribute( mf%sds, 'time1', time1, status1 )
  1091. if (status1>0) then; TRACEBACK; status=1; return; end if
  1092. status2=-1 ; call CheckAttribute( mf%sds, 'time2', time2, status2 )
  1093. if (status2>0) then; TRACEBACK; status=1; return; end if
  1094. status = status1 + status2
  1095. ! try mid time ?
  1096. if ( status < 0 ) then
  1097. if ( t1 == t2 ) then
  1098. ! instant time requested; check wether this is mid of times in file:
  1099. call ReadAttribute( mf%sds, 'time1', time1s, status )
  1100. IF_NOTOK_RETURN(status=1)
  1101. tim1s = NewDate( time6=time1s )
  1102. call ReadAttribute( mf%sds, 'time2', time2s, status )
  1103. IF_NOTOK_RETURN(status=1)
  1104. tim2s = NewDate( time6=time2s )
  1105. ! mid of times in file:
  1106. tmid = tim1s + (tim2s-tim1s)/2
  1107. ! requested time:
  1108. treq = t1
  1109. if ( mf%fixyear > 0 ) call Set( treq, year=mf%fixyear )
  1110. ! not ok ? then try again
  1111. if ( treq /= tmid ) then
  1112. status = -1
  1113. cycle
  1114. end if
  1115. else
  1116. ! interval requested; check wether time in file is mid time:
  1117. tmid = t1 + (t2-t1)/2
  1118. if ( mf%fixyear > 0 ) call Set( tmid, year=mf%fixyear )
  1119. call Get( tmid, time6=time1 )
  1120. status1=-1 ; call CheckAttribute( mf%sds, 'time1', time1, status1 )
  1121. if (status1>0) then; TRACEBACK; status=1; return; end if
  1122. status2=-1 ; call CheckAttribute( mf%sds, 'time2', time1, status2 )
  1123. if (status2>0) then; TRACEBACK; status=1; return; end if
  1124. status = status1 + status2
  1125. if ( status < 0 ) cycle
  1126. end if
  1127. end if
  1128. ! time check passed
  1129. end if
  1130. end select
  1131. ! found!
  1132. exit
  1133. end do
  1134. ! not found ?
  1135. if ( status /= 0 ) then
  1136. write (gol,'("Unable to locate field in hdf file:")'); call goErr
  1137. write (gol,'(" parameter : ",a)') trim(paramkey); call goErr
  1138. call wrtgol( ' t1 : ', t1 ); call goErr
  1139. call wrtgol( ' t2 : ', t2 ); call goErr
  1140. call wrtgol( ' mf%tr(1) : ', mf%trange(1) ); call goErr
  1141. call wrtgol( ' mf%tr(2) : ', mf%trange(2) ); call goErr
  1142. write (gol,'(" file : ",a)') trim(mf%fname); call goErr
  1143. TRACEBACK; status = 1; return
  1144. end if
  1145. ! store paramkey
  1146. mf%paramkey = paramkey
  1147. ! ok
  1148. mf%selected = .true.
  1149. ! ~~~ surface pressure ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1150. if ( mf%spm_load ) then
  1151. mf%spm_selected = .false.
  1152. if ( paramkey /= 'sp' ) then
  1153. ! only hours 00, 06, 12, 18
  1154. dhour = nint(rTotal(t2-t1,'hour'))
  1155. select case ( dhour )
  1156. case ( 0 )
  1157. t_spm = t1
  1158. case ( 3 )
  1159. call Get( t1, hour=hour )
  1160. if ( modulo(hour,6) == 0 ) then
  1161. t_spm = t1
  1162. else
  1163. t_spm = t2
  1164. end if
  1165. case ( 6 )
  1166. t_spm = t1 + IncrDate( hour=3 )
  1167. case default
  1168. write (gol,'("do not know how to form time for mid surface pressure:")'); call goErr
  1169. call wrtgol( ' t1 : ', t1 ); call goErr
  1170. call wrtgol( ' t2 : ', t2 ); call goErr
  1171. TRACEBACK; status = 1; return
  1172. end select
  1173. ! replace year ?
  1174. if ( mf%fixyear > 0 ) then
  1175. call Set( t_spm, year=mf%fixyear )
  1176. end if
  1177. ! initial no record is found ...
  1178. status = 1
  1179. ! number of data sets:
  1180. if ( mf%spm_extr ) then
  1181. call GetInfo( mf%spm_hdf, status, num_datasets=nsds )
  1182. else
  1183. call GetInfo( mf%hdf, status, num_datasets=nsds )
  1184. end if
  1185. if (status/=0) then; TRACEBACK; return; end if
  1186. ! loop over all data sets:
  1187. do isds = 1, nsds
  1188. ! select data set:
  1189. if ( mf%spm_extr ) then
  1190. call Select( mf%spm_sds, mf%spm_hdf, isds-1, status )
  1191. else
  1192. call Select( mf%spm_sds, mf%hdf, isds-1, status )
  1193. end if
  1194. if (status/=0) then; TRACEBACK; return; end if
  1195. ! correct param ?
  1196. status=-1; call CheckInfo( mf%spm_sds, status, name='ps' )
  1197. if (status>0) then; TRACEBACK; status=1; return; end if
  1198. ! not found ? also try other names:
  1199. if ( status < 0) then
  1200. select case ( paramkey )
  1201. case ( 'mfu', 'pu' )
  1202. status=-1; call CheckInfo( mf%spm_sds, status, name='spu' )
  1203. case ( 'mfv', 'pv' )
  1204. status=-1; call CheckInfo( mf%spm_sds, status, name='spv' )
  1205. case default
  1206. status=-1; call CheckInfo( mf%spm_sds, status, name='sp' )
  1207. end select
  1208. if (status>0) then; TRACEBACK; status=1; return; end if
  1209. ! try next ?
  1210. if ( status < 0 ) cycle
  1211. end if
  1212. ! correct time ?
  1213. call Get( t1, time6=time1 )
  1214. status=-1; call CheckAttribute( mf%spm_sds, 'time1', time1, status )
  1215. if (status>0) then; TRACEBACK; status=1; return; end if
  1216. if (status==0) then
  1217. call Get( t2, time6=time1 )
  1218. status=-1; call CheckAttribute( mf%spm_sds, 'time2', time2, status )
  1219. if (status>0) then; TRACEBACK; status=1; return; end if
  1220. else
  1221. ! try special spm times
  1222. call Get( t_spm, time6=time1 )
  1223. status=-1; call CheckAttribute( mf%spm_sds, 'time1', time1, status )
  1224. if (status<0) cycle
  1225. if (status>0) then; TRACEBACK; status=1; return; end if
  1226. ! try special spm times
  1227. call Get( t_spm, time6=time2 )
  1228. status=-1; call CheckAttribute( mf%spm_sds, 'time2', time2, status )
  1229. if (status<0) cycle
  1230. if (status>0) then; TRACEBACK; status=1; return; end if
  1231. end if
  1232. ! found!
  1233. exit
  1234. end do
  1235. ! not found ?
  1236. if ( status /= 0 ) then
  1237. write (gol,'("Unable to locate surface pressure field in hdf file:")'); call goErr
  1238. call wrtgol( ' t1 - t2 : ', t1, ' - ', t2 ); call goErr
  1239. call wrtgol( ' t_spm : ', t_spm ); call goErr
  1240. write (gol,'(" file : ",a)') trim(mf%spm_fname); call goErr
  1241. TRACEBACK; status = 1; return
  1242. end if
  1243. ! ok
  1244. mf%spm_selected = .true.
  1245. end if
  1246. end if
  1247. ! ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
  1248. ! ok
  1249. status = 0
  1250. end subroutine mf_SelectRecord
  1251. ! ***
  1252. !
  1253. ! initialiase grid info from sds
  1254. !
  1255. subroutine lli_Init_mf( lli, nuv, mf, status )
  1256. use file_hdf, only : ReadAttribute, CheckAttribute
  1257. use Grid, only : TllGridInfo, Init
  1258. ! --- in/out ----------------------------------
  1259. type(TllGridInfo), intent(inout) :: lli
  1260. character(len=1), intent(in) :: nuv
  1261. type(TMeteoFile_hdf), intent(in) :: mf
  1262. integer, intent(out) :: status
  1263. ! --- const --------------------------------------
  1264. character(len=*), parameter :: rname = mname//'/lli_Init_mf'
  1265. ! --- local -----------------------------------
  1266. real :: lon_deg, dlon_deg
  1267. integer :: nlon
  1268. real :: lat_deg, dlat_deg
  1269. integer :: nlat
  1270. integer :: stat
  1271. ! --- begin ------------------------------------
  1272. ! record not selected ? then return
  1273. if ( .not. mf%selected ) then
  1274. write (gol,'("no record selected ...")'); call goErr
  1275. TRACEBACK; status = 1; return
  1276. end if
  1277. ! check ...
  1278. call CheckAttribute( mf%sds, 'gridtype' , 'll', status )
  1279. if ( status /= 0 ) then
  1280. write (gol,'("sds does not seem to contain ll grid")'); call goErr
  1281. TRACEBACK; status=1; return
  1282. end if
  1283. ! extract grid position parameters from sds:
  1284. call ReadAttribute( mf%sds, 'lon_first', lon_deg , status )
  1285. if (status/=0) then; TRACEBACK; return; end if
  1286. call ReadAttribute( mf%sds, 'lon_inc ', dlon_deg, status )
  1287. if (status/=0) then; TRACEBACK; return; end if
  1288. call ReadAttribute( mf%sds, 'lon_n ', nlon , status )
  1289. if (status/=0) then; TRACEBACK; return; end if
  1290. call ReadAttribute( mf%sds, 'lat_first', lat_deg , status )
  1291. if (status/=0) then; TRACEBACK; return; end if
  1292. call ReadAttribute( mf%sds, 'lat_inc ', dlat_deg, status )
  1293. if (status/=0) then; TRACEBACK; return; end if
  1294. call ReadAttribute( mf%sds, 'lat_n ', nlat , status )
  1295. if (status/=0) then; TRACEBACK; return; end if
  1296. ! the just read values might define points on the cell boundaries,
  1297. ! while lli should define the cell centers;
  1298. ! fill correct values using nuv :
  1299. select case ( nuv )
  1300. case ( 'n' )
  1301. ! sds attributes defined for lat/lon of center
  1302. call Init( lli, lon_deg, dlon_deg, nlon, &
  1303. lat_deg, dlat_deg, nlat, status )
  1304. if (status/=0) then; TRACEBACK; return; end if
  1305. case ( 'u' )
  1306. ! sds attributes defined for lat/lon of east/west bound
  1307. call Init( lli, lon_deg+0.5*dlon_deg, dlon_deg, nlon-1, &
  1308. lat_deg , dlat_deg, nlat , status )
  1309. if (status/=0) then; TRACEBACK; return; end if
  1310. case ( 'v' )
  1311. ! sds attributes defined for lat/lon of south/north bound
  1312. call Init( lli, lon_deg , dlon_deg, nlon , &
  1313. lat_deg+0.5*dlat_deg, dlat_deg, nlat-1, status )
  1314. if (status/=0) then; TRACEBACK; return; end if
  1315. case default
  1316. write (gol,'("unsupported nuv `",a,"`")') nuv; call goErr
  1317. TRACEBACK; status=1; return
  1318. end select
  1319. ! ok
  1320. status = 0
  1321. end subroutine lli_Init_mf
  1322. ! ***
  1323. !
  1324. ! initialiase level info from sds
  1325. !
  1326. subroutine levi_Init_mf( levi, mf, status )
  1327. use file_hdf, only : GetInfo, ReadAttribute
  1328. use Grid, only : TLevelInfo, Init
  1329. ! --- in/out ----------------------------------
  1330. type(TLevelInfo), intent(out) :: levi
  1331. type(TMeteoFile_hdf), intent(in) :: mf
  1332. integer, intent(out) :: status
  1333. ! --- const --------------------------------------
  1334. character(len=*), parameter :: rname = mname//'/levi_Init_mf'
  1335. ! --- local -----------------------------------
  1336. integer :: data_rank
  1337. integer :: lm
  1338. real, allocatable :: a(:), b(:)
  1339. ! --- begin ------------------------------------
  1340. ! record not selected ? then return
  1341. if ( .not. mf%selected ) then
  1342. write (gol,'("no record selected ...")'); call goErr
  1343. TRACEBACK; status = 1; return
  1344. end if
  1345. ! extract size of data array:
  1346. call GetInfo( mf%sds, status, data_rank=data_rank )
  1347. if ( status/= 0 ) then; TRACEBACK; status=1; return; end if
  1348. ! 2D or 3D
  1349. select case ( data_rank )
  1350. case ( 2 )
  1351. ! set dummy values ...
  1352. call Init( levi, 1, (/0.0,0.0/), (/0.0,0.0/), status )
  1353. if ( status/= 0 ) then; TRACEBACK; status=1; return; end if
  1354. case ( 3 )
  1355. ! read number of levels and hybride parameters:
  1356. call ReadAttribute( mf%sds, 'lm', lm, status )
  1357. ! extract hybride coeff
  1358. allocate( a(lm+1), b(lm+1) )
  1359. call ReadAttribute( mf%sds, 'at', a, status )
  1360. if (status/=0) then; TRACEBACK; return; end if
  1361. call ReadAttribute( mf%sds, 'bt', b, status )
  1362. if (status/=0) then; TRACEBACK; return; end if
  1363. ! fill ...
  1364. call Init( levi, lm, a, b, status )
  1365. if ( status/= 0 ) then; TRACEBACK; status=1; return; end if
  1366. ! done
  1367. deallocate( a, b )
  1368. case default
  1369. write (gol,'("unsupported data rank : ",i6)') data_rank; call goErr
  1370. TRACEBACK; status=1; return
  1371. end select
  1372. ! ok
  1373. status = 0
  1374. end subroutine levi_Init_mf
  1375. ! ***
  1376. subroutine mf_GetField( mf, status, gridtype, ll, spm )
  1377. use PArray, only : pa_SetShape
  1378. use file_hdf, only : GetInfo, ReadData, ReadAttribute
  1379. ! --- in/out --------------------------------
  1380. type(TMeteoFile_hdf), intent(inout) :: mf
  1381. integer, intent(out) :: status
  1382. character(len=*), intent(out), optional :: gridtype
  1383. real, pointer, optional :: ll(:,:,:)
  1384. real, pointer, optional :: spm(:,:)
  1385. ! --- const --------------------------------------
  1386. character(len=*), parameter :: rname = mname//'/mf_GetField'
  1387. ! --- local -------------------------------
  1388. integer :: data_rank
  1389. integer :: data_dims(3)
  1390. ! --- begin -------------------------------
  1391. ! record not selected ? then return
  1392. if ( .not. mf%selected ) then
  1393. write (gol,'("no record selected ...")'); call goErr
  1394. TRACEBACK; status = 1; return
  1395. end if
  1396. ! initial data is not extracted ...
  1397. status = 1
  1398. ! return grid type ?
  1399. if ( present(gridtype) ) then
  1400. call ReadAttribute( mf%sds, 'gridtype', gridtype, status )
  1401. if (status/=0) then; TRACEBACK; return; end if
  1402. end if
  1403. ! return 3d data array ?
  1404. if ( present(ll) ) then
  1405. ! extract data rank and shape:
  1406. call GetInfo( mf%sds, status, data_rank=data_rank, data_dims=data_dims )
  1407. if (status/=0) then; TRACEBACK; return; end if
  1408. ! extract data array:
  1409. select case ( data_rank )
  1410. case ( 2 )
  1411. data_dims(3) = 1
  1412. call pa_SetShape( ll, data_dims )
  1413. call ReadData( mf%sds, ll(:,:,1), status )
  1414. if (status/=0) then; TRACEBACK; return; end if
  1415. case ( 3 )
  1416. call pa_SetShape( ll, data_dims )
  1417. call ReadData( mf%sds, ll, status )
  1418. if (status/=0) then; TRACEBACK; return; end if
  1419. case default
  1420. write (gol,'("unsupported data rank:",i6)') data_rank; call goErr
  1421. TRACEBACK; status=1; return
  1422. end select
  1423. ! ReadData breaks on error ...
  1424. status = 0
  1425. end if
  1426. ! return surface pressure array ?
  1427. if ( present(spm) ) then
  1428. if ( .not. mf%spm_selected ) then
  1429. write (gol,'("no spm record selected ...")'); call goErr
  1430. TRACEBACK; status = 1; return
  1431. end if
  1432. ! extract data rank and shape:
  1433. call GetInfo( mf%spm_sds, status, data_rank=data_rank, data_dims=data_dims )
  1434. if (status/=0) then; TRACEBACK; return; end if
  1435. ! extract data array:
  1436. select case ( data_rank )
  1437. case ( 2 )
  1438. call pa_SetShape( spm, data_dims(1:2) )
  1439. call ReadData( mf%spm_sds, spm, status )
  1440. if (status/=0) then; TRACEBACK; return; end if
  1441. case default
  1442. write (gol,'("unsupported data rank for spm:",i6)') data_rank; call goErr
  1443. TRACEBACK; status=1; return
  1444. end select
  1445. ! ReadData breaks on error ...
  1446. status = 0
  1447. end if
  1448. ! no arguments processed ?
  1449. ! probably subroutine is called incorrectly ...
  1450. if ( status /= 0 ) then
  1451. write (gol,'("no arguments processed; wrong call ?")'); call goErr
  1452. TRACEBACK; status = 1; return
  1453. end if
  1454. ! ok
  1455. status = 0
  1456. end subroutine mf_GetField
  1457. ! ***
  1458. subroutine mf_ReadRecord( mf, paramkey, t1, t2, nuv, nw, &
  1459. gridtype, levi, &
  1460. lli, ll, sp_ll, &
  1461. status )
  1462. use PArray, only : pa_Done
  1463. use GO, only : TDate
  1464. use Grid, only : TllGridInfo, TLevelInfo
  1465. use file_hdf, only : Init, Done
  1466. ! --- in/out -------------------------------
  1467. type(TMeteoFile_hdf), intent(inout) :: mf
  1468. character(len=*), intent(in) :: paramkey
  1469. type(TDate), intent(in) :: t1, t2
  1470. character(len=1), intent(in) :: nuv
  1471. character(len=2), intent(out) :: gridtype
  1472. type(TLevelInfo), intent(out) :: levi
  1473. character(len=1), intent(in) :: nw
  1474. type(TllGridInfo), intent(inout) :: lli
  1475. real, pointer :: ll(:,:,:)
  1476. real, pointer :: sp_ll(:,:)
  1477. integer, intent(out) :: status
  1478. ! --- const --------------------------------------
  1479. character(len=*), parameter :: rname = mname//'/mf_ReadRecord'
  1480. ! --- local -------------------------------
  1481. logical :: exist
  1482. real, allocatable :: mfw_n(:,:,:)
  1483. real, allocatable :: sp_ll_n(:,:)
  1484. integer :: i, j
  1485. ! --- begin ---------------------------------
  1486. ! input ?
  1487. if ( mf%io /= 'i' ) then
  1488. write (gol,'("file should have been opened for input, but io=",a)') mf%io; call goErr
  1489. TRACEBACK; status=1; return
  1490. end if
  1491. ! open for reading:
  1492. ! if it is opened in Init, to many hdf files would be open:
  1493. !
  1494. inquire( file=trim(mf%fname), exist=exist )
  1495. if ( .not. exist ) then
  1496. write (gol,'("main file does not exist:")'); call goErr
  1497. write (gol,'(" ",a)') trim(mf%fname); call goErr
  1498. TRACEBACK; status=1; return
  1499. end if
  1500. !
  1501. call Init( mf%hdf, trim(mf%fname), 'read', status )
  1502. if (status/=0) then; TRACEBACK; return; end if
  1503. !
  1504. call Init( mf%sds, status )
  1505. if (status/=0) then; TRACEBACK; return; end if
  1506. !
  1507. mf%selected = .false.
  1508. ! open spm file if necessary;
  1509. ! if it is opened in Init, to many hdf files would be open:
  1510. if ( mf%spm_load ) then
  1511. !
  1512. if ( mf%spm_extr ) then
  1513. !
  1514. inquire( file=trim(mf%spm_fname), exist=exist )
  1515. if ( .not. exist ) then
  1516. write (gol,'("spm file does not exist:")'); call goErr
  1517. write (gol,'(" ",a)') trim(mf%spm_fname); call goErr
  1518. TRACEBACK; status=1; return
  1519. end if
  1520. !
  1521. call Init( mf%spm_hdf, trim(mf%spm_fname), 'read', status )
  1522. if (status/=0) then; TRACEBACK; return; end if
  1523. !
  1524. end if
  1525. !
  1526. call Init( mf%spm_sds, status )
  1527. if (status/=0) then; TRACEBACK; return; end if
  1528. !
  1529. mf%spm_selected = .false.
  1530. end if
  1531. ! select records in hdf files:
  1532. call mf_SelectRecord( mf, paramkey, t1, t2, status )
  1533. if ( status/= 0 ) then; TRACEBACK; status=1; return; end if
  1534. ! always regular lat/lon grid ..
  1535. gridtype = 'll'
  1536. ! setup grid definition:
  1537. call lli_Init_mf( lli, nuv, mf, status )
  1538. if ( status/= 0 ) then; TRACEBACK; status=1; return; end if
  1539. ! setup level definition:
  1540. call levi_Init_mf( levi, mf, status )
  1541. if ( status/= 0 ) then; TRACEBACK; status=1; return; end if
  1542. ! fill data array:
  1543. call mf_GetField( mf, status, ll=ll )
  1544. if ( status/= 0 ) then; TRACEBACK; status=1; return; end if
  1545. ! ***
  1546. ! special treatment of pw fields ?
  1547. if ( (paramkey == 'mfw') .or. (paramkey == 'pw') ) then
  1548. ! add extra top level ?
  1549. if ( size(ll,3) == levi%nlev ) then
  1550. ! copy current pw ('n' levels)
  1551. allocate( mfw_n(lli%im,lli%jm,levi%nlev) )
  1552. mfw_n = ll
  1553. ! renew target array
  1554. deallocate( ll )
  1555. allocate( ll(lli%nlon,lli%nlat,levi%nlev+1) )
  1556. ! store new pw:
  1557. ll(:,:,1:levi%nlev) = mfw_n
  1558. ll(:,:,levi%nlev+1) = 0.0 ! kg/s
  1559. ! clear
  1560. deallocate( mfw_n )
  1561. end if
  1562. ! change flux direction ?
  1563. if ( mf%mfw_redir ) ll = - ll ! upwards (increasing level)
  1564. end if
  1565. ! ***
  1566. ! special treatment of surface stress fields ?
  1567. if ( ((paramkey=='ewss') .or. (paramkey=='nsss')) .and. mf%sstr_to_ewss_nsss ) then
  1568. ! sstr**2 = (sstr**2)/2 + (sstr**2)/2 = nsss**2 + ewss**2
  1569. ! thus nsss = sqrt( (sstr**2)/2.0 )
  1570. ll = sqrt( (ll**2) / 2.0 )
  1571. end if
  1572. ! ***
  1573. ! fill surface pressure field ?
  1574. if ( mf%spm_load .and. mf%spm_selected ) then
  1575. ! read field:
  1576. call mf_GetField( mf, status, spm=sp_ll )
  1577. if ( status/= 0 ) then; TRACEBACK; status=1; return; end if
  1578. ! convert from 'n' to 'u'/'v' ?
  1579. if ( mf%spm_n_to_uv ) then
  1580. select case ( nuv )
  1581. case ( 'n' )
  1582. ! no interpolation
  1583. case ( 'u' )
  1584. ! copy current sp ('n')
  1585. allocate( sp_ll_n(lli%im,lli%jm) )
  1586. sp_ll_n = sp_ll
  1587. ! renew size of output array:
  1588. deallocate( sp_ll )
  1589. allocate( sp_ll(0:lli%im,lli%jm) )
  1590. ! interpol:
  1591. sp_ll(0,:) = 1.5*sp_ll_n(1,:) - 0.5*sp_ll_n(2,:)
  1592. do i = 1, lli%im-1
  1593. sp_ll(i,:) = 1.5*sp_ll_n(i,:) + 0.5*sp_ll_n(i+1,:)
  1594. end do
  1595. sp_ll(lli%im,:) = -0.5*sp_ll_n(lli%im-1,:) + 1.5*sp_ll_n(lli%im,:)
  1596. ! clear
  1597. deallocate( sp_ll_n )
  1598. case ( 'v' )
  1599. ! copy current sp ('n')
  1600. allocate( sp_ll_n(lli%im,lli%jm) )
  1601. sp_ll_n = sp_ll
  1602. ! renew size of output array:
  1603. deallocate( sp_ll )
  1604. allocate( sp_ll(lli%im,0:lli%jm) )
  1605. ! interpol:
  1606. sp_ll(:,0) = 1.5*sp_ll_n(:,1) - 0.5*sp_ll_n(:,2)
  1607. do j = 1, lli%jm-1
  1608. sp_ll(:,j) = 1.5*sp_ll_n(:,j) + 0.5*sp_ll_n(:,j+1)
  1609. end do
  1610. sp_ll(:,lli%jm) = -0.5*sp_ll_n(:,lli%jm-1) + 1.5*sp_ll_n(:,lli%jm)
  1611. ! clear
  1612. deallocate( sp_ll_n )
  1613. case default
  1614. write (gol,'("unsupported nuv `",a,"`")') nuv; call goErr
  1615. TRACEBACK; status=1; return
  1616. end select
  1617. end if
  1618. else
  1619. call pa_Done( sp_ll )
  1620. end if
  1621. ! close surface pressure file ?
  1622. if ( mf%spm_load ) then
  1623. call Done( mf%spm_sds, status )
  1624. if (status/=0) then; TRACEBACK; return; end if
  1625. !
  1626. if ( mf%spm_extr ) then
  1627. call Done( mf%spm_hdf, status )
  1628. if (status/=0) then; TRACEBACK; return; end if
  1629. end if
  1630. end if
  1631. ! close field file:
  1632. call Done( mf%sds, status )
  1633. if (status/=0) then; TRACEBACK; return; end if
  1634. call Done( mf%hdf, status )
  1635. if (status/=0) then; TRACEBACK; return; end if
  1636. ! ok
  1637. status = 0
  1638. end subroutine mf_ReadRecord
  1639. ! ***
  1640. ! !
  1641. ! ! Read equivalent latitude bounds and indices
  1642. ! !
  1643. !
  1644. ! subroutine mf_ReadEqvLatStuff( mf, t1, t2, eqvlatb, eqvinds, status )
  1645. !
  1646. ! use PArray, only : pa_Done
  1647. ! use GO, only : TDate, Get, wrtgol
  1648. ! use file_hdf, only : TSds, Select, CheckInfo, CheckAttribute
  1649. ! use file_hdf, only : GetInfo, ReadData
  1650. !
  1651. ! ! --- in/out -------------------------------
  1652. !
  1653. ! type(TMeteoFile_hdf), intent(inout) :: mf
  1654. ! type(TDate), intent(in) :: t1, t2
  1655. ! real, intent(out) :: eqvlatb(:,:)
  1656. ! integer, intent(out) :: eqvinds(:,:,:)
  1657. ! integer, intent(out) :: status
  1658. !
  1659. ! ! --- const --------------------------------------
  1660. !
  1661. ! character(len=*), parameter :: rname = mname//'/mf_ReadEqvLatStuff'
  1662. !
  1663. ! ! --- local -------------------------------
  1664. !
  1665. ! integer :: nsds, isds
  1666. ! integer :: time(6)
  1667. ! type(TDate) :: t_spm
  1668. ! integer :: hour, dhour
  1669. !
  1670. ! character(len=20) :: paramkey
  1671. ! integer :: data_dims(2)
  1672. !
  1673. ! ! --- begin ---------------------------------
  1674. !
  1675. ! ! input ?
  1676. ! if ( mf%io /= 'i' ) then
  1677. ! write (gol,'("file should have been opened for input, but io=",a)') mf%io; call goErr
  1678. ! TRACEBACK; status=1; return
  1679. ! end if
  1680. !
  1681. ! mf%selected = .false.
  1682. !
  1683. ! ! initial no record is found ...
  1684. ! status = 1
  1685. !
  1686. ! ! ***
  1687. !
  1688. ! paramkey = 'eqvlatb'
  1689. !
  1690. ! ! loop over all data sets
  1691. ! call GetInfo( mf%hdf, status, num_datasets=nsds )
  1692. ! if (status/=0) then; TRACEBACK; return; end if
  1693. ! do isds = 1, nsds
  1694. ! call Select( mf%sds, mf%hdf, isds-1, status )
  1695. ! if (status/=0) then; TRACEBACK; return; end if
  1696. !
  1697. ! ! correct param ?
  1698. ! call CheckInfo( mf%sds, status, name=paramkey )
  1699. ! if (status/=0) cycle
  1700. !
  1701. ! ! correct time ?
  1702. ! call Get( t1, time6=time )
  1703. ! call CheckAttribute( mf%sds, 'time1', time, status )
  1704. ! if (status/=0) cycle
  1705. ! call Get( t2, time6=time )
  1706. ! call CheckAttribute( mf%sds, 'time2', time, status )
  1707. ! if (status/=0) cycle
  1708. !
  1709. ! ! found!
  1710. ! exit
  1711. ! end do
  1712. !
  1713. ! ! not found ?
  1714. ! if ( status /= 0 ) then
  1715. ! write (gol,'("Unable to locate field in hdf file:")'); call goErr
  1716. ! write (gol,'(" parameter : ",a)') trim(paramkey); call goErr
  1717. ! call wrtgol( ' t1 : ', t1 ); call goErr
  1718. ! call wrtgol( ' t2 : ', t2 ); call goErr
  1719. ! write (gol,'(" file : ",a)') trim(mf%fname); call goErr
  1720. ! TRACEBACK; status = 1; return
  1721. ! end if
  1722. !
  1723. ! ! read field
  1724. ! call ReadData( mf%sds, eqvlatb, status )
  1725. ! if (status/=0) then; TRACEBACK; return; end if
  1726. !
  1727. !
  1728. ! ! ***
  1729. !
  1730. ! paramkey = 'eqvinds'
  1731. !
  1732. ! ! loop over all data sets
  1733. ! call GetInfo( mf%hdf, status, num_datasets=nsds )
  1734. ! if (status/=0) then; TRACEBACK; return; end if
  1735. ! do isds = 1, nsds
  1736. ! call Select( mf%sds, mf%hdf, isds-1, status )
  1737. ! if (status/=0) then; TRACEBACK; return; end if
  1738. !
  1739. ! ! correct param ?
  1740. ! call CheckInfo( mf%sds, status, name=paramkey )
  1741. ! if (status/=0) cycle
  1742. !
  1743. ! ! correct time ?
  1744. ! call Get( t1, time6=time )
  1745. ! call CheckAttribute( mf%sds, 'time1', time, status )
  1746. ! if (status/=0) cycle
  1747. ! call Get( t2, time6=time )
  1748. ! call CheckAttribute( mf%sds, 'time2', time, status )
  1749. ! if (status/=0) cycle
  1750. !
  1751. ! ! found!
  1752. ! exit
  1753. ! end do
  1754. !
  1755. ! ! not found ?
  1756. ! if ( status /= 0 ) then
  1757. ! write (gol,'("Unable to locate field in hdf file:")'); call goErr
  1758. ! write (gol,'(" parameter : ",a)') trim(paramkey); call goErr
  1759. ! call wrtgol( ' t1 : ', t1 ); call goErr
  1760. ! call wrtgol( ' t2 : ', t2 ); call goErr
  1761. ! write (gol,'(" file : ",a)') trim(mf%fname); call goErr
  1762. ! TRACEBACK; status = 1; return
  1763. ! end if
  1764. !
  1765. ! ! read field
  1766. ! call ReadData( mf%sds, eqvinds, status )
  1767. ! if (status/=0) then; TRACEBACK; return; end if
  1768. !
  1769. ! ! ***
  1770. !
  1771. ! ! ok
  1772. ! status = 0
  1773. !
  1774. ! end subroutine mf_ReadEqvLatStuff
  1775. ! ******************************************************************
  1776. ! ***
  1777. ! *** output
  1778. ! ***
  1779. ! ******************************************************************
  1780. subroutine WriteHeader( mf, lli, status, levi )
  1781. use Binas, only : grav, ae
  1782. use Grid, only : TllGridInfo, TLevelInfo
  1783. use file_hdf, only : WriteAttribute
  1784. ! --- in/out -------------------------------
  1785. type(TMeteoFile_hdf), intent(inout) :: mf
  1786. type(TllGridInfo), intent(in) :: lli
  1787. integer, intent(out) :: status
  1788. type(TLevelInfo), intent(in), optional :: levi
  1789. ! --- const --------------------------------------
  1790. character(len=*), parameter :: rname = mname//'/WriteHeader'
  1791. ! --- begin ---------------------------------
  1792. ! write header:
  1793. call WriteAttribute( mf%hdf, 'fname' , trim(mf%fname), status )
  1794. if (status/=0) then; TRACEBACK; return; end if
  1795. call WriteAttribute( mf%hdf, 'format' , output_format, status )
  1796. if (status/=0) then; TRACEBACK; return; end if
  1797. call WriteAttribute( mf%hdf, 'gridtype', 'll' , status )
  1798. if (status/=0) then; TRACEBACK; return; end if
  1799. ! save first and last lon/lat (center) for use with HIPHOP
  1800. call WriteAttribute( mf%hdf, 'lonmin', lli%lon_deg(1) , status, knd=rknd )
  1801. if (status/=0) then; TRACEBACK; return; end if
  1802. call WriteAttribute( mf%hdf, 'lonmax', lli%lon_deg(lli%nlon), status, knd=rknd )
  1803. if (status/=0) then; TRACEBACK; return; end if
  1804. call WriteAttribute( mf%hdf, 'latmin', lli%lat_deg(1) , status, knd=rknd )
  1805. if (status/=0) then; TRACEBACK; return; end if
  1806. call WriteAttribute( mf%hdf, 'latmax', lli%lat_deg(lli%nlat), status, knd=rknd )
  1807. if (status/=0) then; TRACEBACK; return; end if
  1808. ! other useful stuff ...
  1809. call WriteAttribute( mf%hdf, 'grav' , grav , status, knd=rknd )
  1810. if (status/=0) then; TRACEBACK; return; end if
  1811. call WriteAttribute( mf%hdf, 'ae' , ae , status, knd=rknd )
  1812. if (status/=0) then; TRACEBACK; return; end if
  1813. call WriteAttribute( mf%hdf, 'area_m2', lli%area_m2, status, knd=rknd )
  1814. if (status/=0) then; TRACEBACK; return; end if
  1815. ! level stuff
  1816. if ( present(levi) ) then
  1817. call WriteAttribute( mf%hdf, 'lm', levi%nlev, status, knd=iknd )
  1818. if (status/=0) then; TRACEBACK; return; end if
  1819. call WriteAttribute( mf%hdf, 'at', levi%a , status, knd=rknd )
  1820. if (status/=0) then; TRACEBACK; return; end if
  1821. call WriteAttribute( mf%hdf, 'bt', levi%b , status, knd=rknd )
  1822. if (status/=0) then; TRACEBACK; return; end if
  1823. end if
  1824. ! ok
  1825. status = 0
  1826. end subroutine WriteHeader
  1827. ! ***
  1828. subroutine WriteSdsHeader( sds, tmi, unit, tref, t1, t2, lli, nuv, status, &
  1829. levi, nw, nlev )
  1830. use Binas , only : p_global
  1831. use file_hdf, only : TSds
  1832. use file_hdf, only : SetDim, WriteAttribute, Compress
  1833. use GO , only : TDate, Get, rTotal, operator(-), IsAnyDate
  1834. use Grid , only : TllGridInfo, TLevelInfo
  1835. use tmm_info, only : TMeteoInfo
  1836. ! --- in/out -----------------------------
  1837. type(TSds), intent(inout) :: sds
  1838. type(TMeteoInfo), intent(in) :: tmi
  1839. character(len=*), intent(in) :: unit
  1840. type(TDate), intent(in) :: tref, t1, t2
  1841. type(TllGridInfo), intent(in) :: lli
  1842. character(len=1), intent(in) :: nuv
  1843. integer, intent(out) :: status
  1844. type(TLevelInfo), intent(in), optional :: levi
  1845. character(len=1), intent(in), optional :: nw
  1846. integer, intent(in), optional :: nlev
  1847. ! --- const --------------------------------------
  1848. character(len=*), parameter :: rname = mname//'/WriteSdsHeader'
  1849. ! --- local -----------------------------
  1850. integer :: time6(6)
  1851. integer :: dhour
  1852. ! --- begin -----------------------------
  1853. ! *** history
  1854. ! write history of meteo field:
  1855. if ( len_trim(tmi%history) < 1 ) then
  1856. call WriteAttribute( sds, 'history', '-', status )
  1857. IF_NOTOK_RETURN(status=1)
  1858. else
  1859. call WriteAttribute( sds, 'history', trim(tmi%history), status )
  1860. IF_NOTOK_RETURN(status=1)
  1861. end if
  1862. ! *** unit
  1863. ! write unit attribute
  1864. call WriteAttribute( sds, 'unit', unit, status )
  1865. IF_NOTOK_RETURN(status=1)
  1866. ! *** time
  1867. ! time interval in hours
  1868. if ( IsAnyDate(t1) .or. IsAnyDate(t2) ) then
  1869. dhour = 0
  1870. else
  1871. dhour = nint(rTotal( t2 - t2, 'hour' ))
  1872. end if
  1873. ! write old time attributes
  1874. call Get( t1, time6=time6 )
  1875. call WriteAttribute( sds, 'idate', time6, status, knd=iknd )
  1876. IF_NOTOK_RETURN(status=1)
  1877. call WriteAttribute( sds, 'dthrs', dhour, status, knd=iknd ) ! hours
  1878. IF_NOTOK_RETURN(status=1)
  1879. ! write new time attributes
  1880. call Get( tref, time6=time6 )
  1881. call WriteAttribute( sds, 'tref', time6, status, knd=iknd )
  1882. IF_NOTOK_RETURN(status=1)
  1883. call Get( t1, time6=time6 )
  1884. call WriteAttribute( sds, 'time1', time6, status, knd=iknd )
  1885. IF_NOTOK_RETURN(status=1)
  1886. call Get( t2, time6=time6 )
  1887. call WriteAttribute( sds, 'time2', time6, status, knd=iknd )
  1888. IF_NOTOK_RETURN(status=1)
  1889. time6 = 0
  1890. time6(4) = dhour
  1891. call WriteAttribute( sds, 'dtime', time6, status, knd=iknd )
  1892. IF_NOTOK_RETURN(status=1)
  1893. ! *** grid
  1894. select case ( nuv )
  1895. case ( 'n' )
  1896. ! sds dimensions:
  1897. call SetDim( sds, 1-1, 'LON' , 'deg', lli%lon_deg, status, knd=rknd )
  1898. IF_NOTOK_RETURN(status=1)
  1899. call SetDim( sds, 2-1, 'LAT' , 'deg', lli%lat_deg, status, knd=rknd )
  1900. IF_NOTOK_RETURN(status=1)
  1901. ! sds attributes:
  1902. call WriteAttribute( sds, 'gridtype' , 'll' , status )
  1903. IF_NOTOK_RETURN(status=1)
  1904. call WriteAttribute( sds, 'lon_first', lli%lon_deg(1), status, knd=rknd )
  1905. IF_NOTOK_RETURN(status=1)
  1906. call WriteAttribute( sds, 'lon_inc ', lli%dlon_deg , status, knd=rknd )
  1907. IF_NOTOK_RETURN(status=1)
  1908. call WriteAttribute( sds, 'lon_n ', lli%nlon , status, knd=iknd )
  1909. IF_NOTOK_RETURN(status=1)
  1910. call WriteAttribute( sds, 'lat_first', lli%lat_deg(1), status, knd=rknd )
  1911. IF_NOTOK_RETURN(status=1)
  1912. call WriteAttribute( sds, 'lat_inc ', lli%dlat_deg , status, knd=rknd )
  1913. IF_NOTOK_RETURN(status=1)
  1914. call WriteAttribute( sds, 'lat_n ', lli%nlat , status, knd=iknd )
  1915. IF_NOTOK_RETURN(status=1)
  1916. case ( 'u' )
  1917. ! sds dimensions:
  1918. call SetDim( sds, 1-1, 'LONP1' , 'deg', lli%blon_deg, status, knd=rknd )
  1919. IF_NOTOK_RETURN(status=1)
  1920. call SetDim( sds, 2-1, 'LAT' , 'deg', lli%lat_deg , status, knd=rknd )
  1921. IF_NOTOK_RETURN(status=1)
  1922. ! sds attributes:
  1923. call WriteAttribute( sds, 'gridtype' , 'll', status )
  1924. IF_NOTOK_RETURN(status=1)
  1925. call WriteAttribute( sds, 'lon_first', lli%blon_deg(0), status, knd=rknd )
  1926. IF_NOTOK_RETURN(status=1)
  1927. call WriteAttribute( sds, 'lon_inc ', lli%dlon_deg , status, knd=rknd )
  1928. IF_NOTOK_RETURN(status=1)
  1929. call WriteAttribute( sds, 'lon_n ', lli%im+1 , status, knd=iknd )
  1930. IF_NOTOK_RETURN(status=1)
  1931. call WriteAttribute( sds, 'lat_first', lli%lat_deg(1) , status, knd=rknd )
  1932. IF_NOTOK_RETURN(status=1)
  1933. call WriteAttribute( sds, 'lat_inc ', lli%dlat_deg , status, knd=rknd )
  1934. IF_NOTOK_RETURN(status=1)
  1935. call WriteAttribute( sds, 'lat_n ', lli%nlat , status, knd=iknd )
  1936. IF_NOTOK_RETURN(status=1)
  1937. case ( 'v' )
  1938. ! sds dimensions:
  1939. call SetDim( sds, 1-1, 'LON' , 'deg', lli%lon_deg , status, knd=rknd )
  1940. IF_NOTOK_RETURN(status=1)
  1941. call SetDim( sds, 2-1, 'LATP1' , 'deg', lli%blat_deg, status, knd=rknd )
  1942. IF_NOTOK_RETURN(status=1)
  1943. ! sds attributes:
  1944. call WriteAttribute( sds, 'gridtype' , 'll', status )
  1945. call WriteAttribute( sds, 'lon_first', lli%lon_deg(1) , status, knd=rknd )
  1946. IF_NOTOK_RETURN(status=1)
  1947. call WriteAttribute( sds, 'lon_inc ', lli%dlon_deg , status, knd=rknd )
  1948. IF_NOTOK_RETURN(status=1)
  1949. call WriteAttribute( sds, 'lon_n ', lli%nlon , status, knd=iknd )
  1950. IF_NOTOK_RETURN(status=1)
  1951. call WriteAttribute( sds, 'lat_first', lli%blat_deg(0), status, knd=rknd )
  1952. IF_NOTOK_RETURN(status=1)
  1953. call WriteAttribute( sds, 'lat_inc ', lli%dlat_deg , status, knd=rknd )
  1954. IF_NOTOK_RETURN(status=1)
  1955. call WriteAttribute( sds, 'lat_n ', lli%jm+1 , status, knd=iknd )
  1956. IF_NOTOK_RETURN(status=1)
  1957. case default
  1958. write (gol,'("unsupported nuv `",a,"`")') nuv; call goErr
  1959. TRACEBACK; status=1; return
  1960. end select
  1961. ! *** levels
  1962. if ( present(levi) ) then
  1963. if ( .not. present(nw) ) then
  1964. write (gol,'("optional levi requires nw")'); call goErr
  1965. TRACEBACK; status=1; return
  1966. end if
  1967. ! sds dimensions:
  1968. select case ( nw )
  1969. case ( '*' )
  1970. if ( present(nlev) ) then
  1971. call SetDim( sds, 3-1, 'HYBRID_SELECTED', 'Pa' , levi%fp0(1:nlev), status, knd=rknd )
  1972. IF_NOTOK_RETURN(status=1)
  1973. end if
  1974. case ( 'n' )
  1975. call SetDim( sds, 3-1, 'HYBRID', 'Pa' , levi%fp0, status, knd=rknd )
  1976. IF_NOTOK_RETURN(status=1)
  1977. case ( 'w' )
  1978. call SetDim( sds, 3-1, 'HYBRIDh', 'Pa', levi%p0, status, knd=rknd )
  1979. IF_NOTOK_RETURN(status=1)
  1980. case default
  1981. write (gol,'("unsupported nw `",a,"` xxx")') nw; call goErr
  1982. TRACEBACK; status=1; return
  1983. end select
  1984. ! sds attributes:
  1985. call WriteAttribute( sds, 'lm', levi%nlev, status, knd=iknd )
  1986. IF_NOTOK_RETURN(status=1)
  1987. call WriteAttribute( sds, 'at', levi%a , status, knd=rknd )
  1988. IF_NOTOK_RETURN(status=1)
  1989. call WriteAttribute( sds, 'bt', levi%b , status, knd=rknd )
  1990. IF_NOTOK_RETURN(status=1)
  1991. end if
  1992. ! *** data compression
  1993. call Compress( sds, compression, status, deflate_level=deflate_level )
  1994. IF_NOTOK_RETURN(status=1)
  1995. ! *** end
  1996. ! ok
  1997. status = 0
  1998. end subroutine WriteSdsHeader
  1999. ! ***
  2000. subroutine WriteStatus( mf, msg, status )
  2001. ! --- in/out -------------------------------
  2002. type(TMeteoFile_hdf), intent(inout) :: mf
  2003. character(len=*), intent(in) :: msg
  2004. integer, intent(out) :: status
  2005. ! --- const --------------------------------------
  2006. character(len=*), parameter :: rname = mname//'/WriteStatus'
  2007. ! --- local ------------------------------
  2008. integer :: fu
  2009. logical :: opened
  2010. ! --- begin ---------------------------------
  2011. ! select unused file unit:
  2012. fu = 1234
  2013. do
  2014. inquire( unit=fu, opened=opened )
  2015. if ( .not. opened ) exit
  2016. fu = fu + 1
  2017. end do
  2018. ! open:
  2019. open( fu, file=trim(mf%fname)//'.status', form='formatted', iostat=status )
  2020. if (status/=0) then
  2021. write (gol,'("opening status file:")'); call goErr
  2022. write (gol,'(" file : ",a)') trim(mf%fname); call goErr
  2023. TRACEBACK; status=1; return
  2024. end if
  2025. ! write message:
  2026. write (fu,'(a)',iostat=status) msg
  2027. if (status/=0) then
  2028. write (gol,'("writing status:")'); call goErr
  2029. write (gol,'(" file : ",a)') trim(mf%fname); call goErr
  2030. write (gol,'(" msg : ",a)') msg; call goErr
  2031. TRACEBACK; status=1; return
  2032. end if
  2033. ! done:
  2034. close( fu, iostat=status )
  2035. if (status/=0) then
  2036. write (gol,'("closing status file:")'); call goErr
  2037. write (gol,'(" file : ",a)') trim(mf%fname); call goErr
  2038. TRACEBACK; status=1; return
  2039. end if
  2040. ! ok
  2041. status = 0
  2042. end subroutine WriteStatus
  2043. ! ***
  2044. subroutine AddOutputName( mf, name, status )
  2045. ! --- in/out -------------------------------
  2046. type(TMeteoFile_hdf), intent(inout) :: mf
  2047. character(len=*), intent(in) :: name
  2048. integer, intent(out) :: status
  2049. ! --- const --------------------------------------
  2050. character(len=*), parameter :: rname = mname//'/AddOuputName'
  2051. ! --- local ------------------------------
  2052. integer :: iname
  2053. ! --- begin ---------------------------------
  2054. ! if not present yet, add name
  2055. iname = 1
  2056. do
  2057. ! add ?
  2058. if ( iname > mf%output_nname ) then
  2059. ! place to store ?
  2060. if ( iname > size(mf%output_names) ) then
  2061. write (gol,'("length of mf%output_names array too small:")'); call goErr
  2062. do iname = 1, size(mf%output_names)
  2063. write (gol,'(" ",i3," ",a)') iname, trim(mf%output_names(iname)); call goErr
  2064. end do
  2065. TRACEBACK; status=1; return
  2066. end if
  2067. ! long enough for name ?
  2068. if ( len(mf%output_names(iname)) < len(name) ) then
  2069. write (gol,'("length of mf%output_names too small:")'); call goErr
  2070. write (gol,'(" len(mf%output_names(i)) : ",i4)') len(mf%output_names(iname)); call goErr
  2071. write (gol,'(" len(mname) : ",i4)') len(name); call goErr
  2072. TRACEBACK; status=1; return
  2073. end if
  2074. ! store:
  2075. mf%output_names(iname) = name
  2076. ! increase counter:
  2077. mf%output_nname = iname
  2078. ! leave:
  2079. exit
  2080. end if
  2081. ! found ? then leave loop
  2082. if ( mf%output_names(iname) == name ) exit
  2083. ! next index
  2084. iname = iname + 1
  2085. end do
  2086. ! ok
  2087. status = 0
  2088. end subroutine AddOutputName
  2089. ! ***
  2090. subroutine mf_WriteRecord_2d( mf, tmi, paramkey, unit, tref, t1, t2, &
  2091. lli, nuv, ll, status )
  2092. use GO , only : TDate
  2093. use Grid , only : TllGridInfo
  2094. use file_hdf, only : TSds, WriteData
  2095. use file_hdf_base, only : Init, Done ! needed on aster
  2096. use tmm_info, only : TMeteoInfo
  2097. ! --- in/out -------------------------------
  2098. type(TMeteoFile_hdf), intent(inout) :: mf
  2099. type(TMeteoInfo), intent(in) :: tmi
  2100. character(len=*), intent(in) :: paramkey, unit
  2101. type(TDate), intent(in) :: tref, t1, t2
  2102. type(TllGridInfo), intent(in) :: lli
  2103. character(len=1), intent(in) :: nuv
  2104. real, intent(in) :: ll(:,:)
  2105. integer, intent(out) :: status
  2106. ! --- const --------------------------------------
  2107. character(len=*), parameter :: rname = mname//'/mf_WriteRecord_2d'
  2108. ! --- local ------------------------------
  2109. type(TSds) :: sds
  2110. ! --- begin ---------------------------------
  2111. ! output ?
  2112. if ( mf%io /= 'o' ) then
  2113. write (gol,'("file should have been opened for output, but io=",a)') mf%io; call goErr
  2114. TRACEBACK; status=1; return
  2115. end if
  2116. ! new or existing ?
  2117. if ( .not. mf%output_initialised ) then
  2118. ! open new file, destroy old:
  2119. call Init( mf%hdf, trim(mf%fname), 'create', status )
  2120. IF_NOTOK_RETURN(status=1)
  2121. ! write file header:
  2122. call WriteHeader( mf, lli, status )
  2123. IF_NOTOK_RETURN(status=1)
  2124. ! status new
  2125. call WriteStatus( mf, 'in-progress', status )
  2126. IF_NOTOK_RETURN(status=1)
  2127. ! no records written yet:
  2128. mf%output_nrec = 0
  2129. ! now the file is initialised
  2130. mf%output_initialised = .true.
  2131. else
  2132. ! re-open file:
  2133. call Init( mf%hdf, trim(mf%fname), 'write', status )
  2134. IF_NOTOK_RETURN(status=1)
  2135. endif
  2136. ! *** data set
  2137. ! add record name:
  2138. call AddOutputName( mf, paramkey, status )
  2139. IF_NOTOK_RETURN(status=1)
  2140. ! init data set:
  2141. call Init( sds, mf%hdf, paramkey, shape(ll), 'real', status, knd=rknd_ds )
  2142. IF_NOTOK_RETURN(status=1)
  2143. ! write unit, time, and grid info:
  2144. call WriteSdsHeader( sds, tmi, unit, tref, t1, t2, lli, nuv, status )
  2145. IF_NOTOK_RETURN(status=1)
  2146. ! write grid
  2147. call WriteData( sds, ll, status )
  2148. IF_NOTOK_RETURN(status=1)
  2149. ! done:
  2150. call Done( sds, status )
  2151. IF_NOTOK_RETURN(status=1)
  2152. ! *** completed ?
  2153. ! next record has been written:
  2154. mf%output_nrec = mf%output_nrec + 1
  2155. ! completed ?
  2156. if ( mf%output_nrec == mf%output_ntrec*mf%output_nname ) then
  2157. ! re-write status file:
  2158. call WriteStatus( mf, 'completed', status )
  2159. IF_NOTOK_RETURN(status=1)
  2160. ! ensure that new file is initialized ...
  2161. mf%output_initialised = .false.
  2162. end if
  2163. ! *** close
  2164. call Done( mf%hdf, status )
  2165. IF_NOTOK_RETURN(status=1)
  2166. ! ok
  2167. status = 0
  2168. end subroutine mf_WriteRecord_2d
  2169. ! ***
  2170. subroutine mf_WriteRecord_3d( mf, tmi, spname, paramkey, unit, tref, t1, t2, &
  2171. lli, nuv, levi, nw, ps, ll, status )
  2172. use GO , only : TDate
  2173. use Grid , only : TllGridInfo, TLevelInfo
  2174. use file_hdf, only : TSds, WriteData
  2175. use file_hdf_base, only : Init, Done !needed on aster
  2176. use tmm_info, only : TMeteoInfo
  2177. ! --- in/out -------------------------------
  2178. type(TMeteoFile_hdf), intent(inout) :: mf
  2179. type(TMeteoInfo), intent(in) :: tmi
  2180. character(len=*), intent(in) :: spname, paramkey, unit
  2181. type(TDate), intent(in) :: tref, t1, t2
  2182. type(TllGridInfo), intent(in) :: lli
  2183. character(len=1), intent(in) :: nuv
  2184. type(TLevelInfo), intent(in) :: levi
  2185. character(len=1), intent(in) :: nw
  2186. real, intent(in) :: ps(:,:)
  2187. real, intent(in) :: ll(:,:,:)
  2188. integer, intent(out) :: status
  2189. ! --- const --------------------------------------
  2190. character(len=*), parameter :: rname = mname//'/mf_WriteRecord_3d'
  2191. ! --- local ------------------------------
  2192. type(TSds) :: sds
  2193. integer :: iname
  2194. ! --- begin ---------------------------------
  2195. ! output ?
  2196. if ( mf%io /= 'o' ) then
  2197. write (gol,'("file should have been opened for output, but io=",a)') mf%io; call goErr
  2198. TRACEBACK; status=1; return
  2199. end if
  2200. ! new or existing ?
  2201. if ( .not. mf%output_initialised ) then
  2202. ! open new file, destroy old:
  2203. call Init( mf%hdf, trim(mf%fname), 'create', status )
  2204. IF_NOTOK_RETURN(status=1)
  2205. ! write file header:
  2206. call WriteHeader( mf, lli, status, levi )
  2207. IF_NOTOK_RETURN(status=1)
  2208. ! status new
  2209. call WriteStatus( mf, 'in-progress', status )
  2210. IF_NOTOK_RETURN(status=1)
  2211. ! no records written yet:
  2212. mf%output_nrec = 0
  2213. ! now the file is initialised
  2214. mf%output_initialised = .true.
  2215. else
  2216. ! re-open file:
  2217. call Init( mf%hdf, trim(mf%fname), 'write', status )
  2218. IF_NOTOK_RETURN(status=1)
  2219. endif
  2220. ! *** data set
  2221. ! add record name:
  2222. call AddOutputName( mf, paramkey, status )
  2223. IF_NOTOK_RETURN(status=1)
  2224. ! init data set:
  2225. call Init( sds, mf%hdf, paramkey, shape(ll), 'real', status, knd=rknd_ds )
  2226. IF_NOTOK_RETURN(status=1)
  2227. ! write unit, time, and grid info:
  2228. call WriteSdsHeader( sds, tmi, unit, tref, t1, t2, lli, nuv, status, levi, nw )
  2229. IF_NOTOK_RETURN(status=1)
  2230. ! write grid
  2231. call WriteData( sds, ll, status )
  2232. IF_NOTOK_RETURN(status=1)
  2233. ! done:
  2234. call Done( sds, status )
  2235. IF_NOTOK_RETURN(status=1)
  2236. ! *** surface pressure
  2237. ! init data set:
  2238. call Init( sds, mf%hdf, spname, shape(ps), 'real', status, knd=rknd_ds )
  2239. IF_NOTOK_RETURN(status=1)
  2240. ! write unit, time, and grid info:
  2241. call WriteSdsHeader( sds, tmi, 'Pa', tref, t1, t2, lli, nuv, status )
  2242. IF_NOTOK_RETURN(status=1)
  2243. ! write grid
  2244. call WriteData( sds, ps, status )
  2245. IF_NOTOK_RETURN(status=1)
  2246. ! done:
  2247. call Done( sds, status )
  2248. IF_NOTOK_RETURN(status=1)
  2249. ! *** completed ?
  2250. ! next record has been written:
  2251. mf%output_nrec = mf%output_nrec + 1
  2252. ! completed ?
  2253. if ( mf%output_nrec == mf%output_ntrec*mf%output_nname ) then
  2254. ! re-write status file:
  2255. call WriteStatus( mf, 'completed', status )
  2256. IF_NOTOK_RETURN(status=1)
  2257. ! ensure that new file is initialized ...
  2258. mf%output_initialised = .false.
  2259. end if
  2260. ! *** close
  2261. call Done( mf%hdf, status )
  2262. IF_NOTOK_RETURN(status=1)
  2263. ! ok
  2264. status = 0
  2265. end subroutine mf_WriteRecord_3d
  2266. end module tmm_mf_hdf