gentooboontoo-gphys 0.6.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (401) hide show
  1. checksums.yaml +7 -0
  2. data/ChangeLog +1255 -0
  3. data/README +32 -0
  4. data/bin/gdir_client +9 -0
  5. data/bin/gdir_server +123 -0
  6. data/bin/gpaop +134 -0
  7. data/bin/gpcat +140 -0
  8. data/bin/gpcut +94 -0
  9. data/bin/gpedit +196 -0
  10. data/bin/gplist +67 -0
  11. data/bin/gpmath +114 -0
  12. data/bin/gpmaxmin +127 -0
  13. data/bin/gpprint +57 -0
  14. data/bin/gpvect +657 -0
  15. data/bin/gpview +603 -0
  16. data/bin/grads2nc_with_gphys +56 -0
  17. data/doc/attribute.html +19 -0
  18. data/doc/attributenetcdf.html +15 -0
  19. data/doc/axis.html +368 -0
  20. data/doc/coordmapping.html +111 -0
  21. data/doc/coordtransform.html +36 -0
  22. data/doc/derivative/gphys-derivative.html +80 -0
  23. data/doc/derivative/index.html +21 -0
  24. data/doc/derivative/index.rd +14 -0
  25. data/doc/derivative/math-doc/document/document.css +30 -0
  26. data/doc/derivative/math-doc/document/document.html +57 -0
  27. data/doc/derivative/math-doc/document/images.aux +1 -0
  28. data/doc/derivative/math-doc/document/images.log +385 -0
  29. data/doc/derivative/math-doc/document/images.pl +186 -0
  30. data/doc/derivative/math-doc/document/images.tex +364 -0
  31. data/doc/derivative/math-doc/document/img1.png +0 -0
  32. data/doc/derivative/math-doc/document/img10.png +0 -0
  33. data/doc/derivative/math-doc/document/img11.png +0 -0
  34. data/doc/derivative/math-doc/document/img12.png +0 -0
  35. data/doc/derivative/math-doc/document/img13.png +0 -0
  36. data/doc/derivative/math-doc/document/img14.png +0 -0
  37. data/doc/derivative/math-doc/document/img15.png +0 -0
  38. data/doc/derivative/math-doc/document/img16.png +0 -0
  39. data/doc/derivative/math-doc/document/img17.png +0 -0
  40. data/doc/derivative/math-doc/document/img18.png +0 -0
  41. data/doc/derivative/math-doc/document/img19.png +0 -0
  42. data/doc/derivative/math-doc/document/img2.png +0 -0
  43. data/doc/derivative/math-doc/document/img20.png +0 -0
  44. data/doc/derivative/math-doc/document/img21.png +0 -0
  45. data/doc/derivative/math-doc/document/img22.png +0 -0
  46. data/doc/derivative/math-doc/document/img23.png +0 -0
  47. data/doc/derivative/math-doc/document/img24.png +0 -0
  48. data/doc/derivative/math-doc/document/img25.png +0 -0
  49. data/doc/derivative/math-doc/document/img26.png +0 -0
  50. data/doc/derivative/math-doc/document/img27.png +0 -0
  51. data/doc/derivative/math-doc/document/img28.png +0 -0
  52. data/doc/derivative/math-doc/document/img29.png +0 -0
  53. data/doc/derivative/math-doc/document/img3.png +0 -0
  54. data/doc/derivative/math-doc/document/img30.png +0 -0
  55. data/doc/derivative/math-doc/document/img4.png +0 -0
  56. data/doc/derivative/math-doc/document/img5.png +0 -0
  57. data/doc/derivative/math-doc/document/img6.png +0 -0
  58. data/doc/derivative/math-doc/document/img7.png +0 -0
  59. data/doc/derivative/math-doc/document/img8.png +0 -0
  60. data/doc/derivative/math-doc/document/img9.png +0 -0
  61. data/doc/derivative/math-doc/document/index.html +57 -0
  62. data/doc/derivative/math-doc/document/labels.pl +13 -0
  63. data/doc/derivative/math-doc/document/next.png +0 -0
  64. data/doc/derivative/math-doc/document/next_g.png +0 -0
  65. data/doc/derivative/math-doc/document/node1.html +238 -0
  66. data/doc/derivative/math-doc/document/node2.html +75 -0
  67. data/doc/derivative/math-doc/document/prev.png +0 -0
  68. data/doc/derivative/math-doc/document/prev_g.png +0 -0
  69. data/doc/derivative/math-doc/document/up.png +0 -0
  70. data/doc/derivative/math-doc/document/up_g.png +0 -0
  71. data/doc/derivative/math-doc/document.pdf +0 -0
  72. data/doc/derivative/math-doc/document.tex +158 -0
  73. data/doc/derivative/numru-derivative.html +129 -0
  74. data/doc/ep_flux/ep_flux.html +469 -0
  75. data/doc/ep_flux/ggraph_on_merdional_section.html +71 -0
  76. data/doc/ep_flux/index.html +31 -0
  77. data/doc/ep_flux/index.rd +24 -0
  78. data/doc/ep_flux/math-doc/document/WARNINGS +1 -0
  79. data/doc/ep_flux/math-doc/document/contents.png +0 -0
  80. data/doc/ep_flux/math-doc/document/crossref.png +0 -0
  81. data/doc/ep_flux/math-doc/document/document.css +30 -0
  82. data/doc/ep_flux/math-doc/document/document.html +101 -0
  83. data/doc/ep_flux/math-doc/document/images.aux +1 -0
  84. data/doc/ep_flux/math-doc/document/images.log +1375 -0
  85. data/doc/ep_flux/math-doc/document/images.pl +1328 -0
  86. data/doc/ep_flux/math-doc/document/images.tex +1471 -0
  87. data/doc/ep_flux/math-doc/document/img1.png +0 -0
  88. data/doc/ep_flux/math-doc/document/img10.png +0 -0
  89. data/doc/ep_flux/math-doc/document/img100.png +0 -0
  90. data/doc/ep_flux/math-doc/document/img101.png +0 -0
  91. data/doc/ep_flux/math-doc/document/img102.png +0 -0
  92. data/doc/ep_flux/math-doc/document/img103.png +0 -0
  93. data/doc/ep_flux/math-doc/document/img104.png +0 -0
  94. data/doc/ep_flux/math-doc/document/img105.png +0 -0
  95. data/doc/ep_flux/math-doc/document/img106.png +0 -0
  96. data/doc/ep_flux/math-doc/document/img107.png +0 -0
  97. data/doc/ep_flux/math-doc/document/img108.png +0 -0
  98. data/doc/ep_flux/math-doc/document/img109.png +0 -0
  99. data/doc/ep_flux/math-doc/document/img11.png +0 -0
  100. data/doc/ep_flux/math-doc/document/img110.png +0 -0
  101. data/doc/ep_flux/math-doc/document/img111.png +0 -0
  102. data/doc/ep_flux/math-doc/document/img112.png +0 -0
  103. data/doc/ep_flux/math-doc/document/img113.png +0 -0
  104. data/doc/ep_flux/math-doc/document/img114.png +0 -0
  105. data/doc/ep_flux/math-doc/document/img115.png +0 -0
  106. data/doc/ep_flux/math-doc/document/img116.png +0 -0
  107. data/doc/ep_flux/math-doc/document/img117.png +0 -0
  108. data/doc/ep_flux/math-doc/document/img118.png +0 -0
  109. data/doc/ep_flux/math-doc/document/img119.png +0 -0
  110. data/doc/ep_flux/math-doc/document/img12.png +0 -0
  111. data/doc/ep_flux/math-doc/document/img120.png +0 -0
  112. data/doc/ep_flux/math-doc/document/img121.png +0 -0
  113. data/doc/ep_flux/math-doc/document/img122.png +0 -0
  114. data/doc/ep_flux/math-doc/document/img123.png +0 -0
  115. data/doc/ep_flux/math-doc/document/img124.png +0 -0
  116. data/doc/ep_flux/math-doc/document/img125.png +0 -0
  117. data/doc/ep_flux/math-doc/document/img126.png +0 -0
  118. data/doc/ep_flux/math-doc/document/img127.png +0 -0
  119. data/doc/ep_flux/math-doc/document/img128.png +0 -0
  120. data/doc/ep_flux/math-doc/document/img129.png +0 -0
  121. data/doc/ep_flux/math-doc/document/img13.png +0 -0
  122. data/doc/ep_flux/math-doc/document/img130.png +0 -0
  123. data/doc/ep_flux/math-doc/document/img131.png +0 -0
  124. data/doc/ep_flux/math-doc/document/img132.png +0 -0
  125. data/doc/ep_flux/math-doc/document/img133.png +0 -0
  126. data/doc/ep_flux/math-doc/document/img134.png +0 -0
  127. data/doc/ep_flux/math-doc/document/img135.png +0 -0
  128. data/doc/ep_flux/math-doc/document/img136.png +0 -0
  129. data/doc/ep_flux/math-doc/document/img137.png +0 -0
  130. data/doc/ep_flux/math-doc/document/img138.png +0 -0
  131. data/doc/ep_flux/math-doc/document/img139.png +0 -0
  132. data/doc/ep_flux/math-doc/document/img14.png +0 -0
  133. data/doc/ep_flux/math-doc/document/img140.png +0 -0
  134. data/doc/ep_flux/math-doc/document/img141.png +0 -0
  135. data/doc/ep_flux/math-doc/document/img142.png +0 -0
  136. data/doc/ep_flux/math-doc/document/img143.png +0 -0
  137. data/doc/ep_flux/math-doc/document/img144.png +0 -0
  138. data/doc/ep_flux/math-doc/document/img145.png +0 -0
  139. data/doc/ep_flux/math-doc/document/img146.png +0 -0
  140. data/doc/ep_flux/math-doc/document/img147.png +0 -0
  141. data/doc/ep_flux/math-doc/document/img148.png +0 -0
  142. data/doc/ep_flux/math-doc/document/img149.png +0 -0
  143. data/doc/ep_flux/math-doc/document/img15.png +0 -0
  144. data/doc/ep_flux/math-doc/document/img150.png +0 -0
  145. data/doc/ep_flux/math-doc/document/img151.png +0 -0
  146. data/doc/ep_flux/math-doc/document/img152.png +0 -0
  147. data/doc/ep_flux/math-doc/document/img153.png +0 -0
  148. data/doc/ep_flux/math-doc/document/img154.png +0 -0
  149. data/doc/ep_flux/math-doc/document/img155.png +0 -0
  150. data/doc/ep_flux/math-doc/document/img156.png +0 -0
  151. data/doc/ep_flux/math-doc/document/img157.png +0 -0
  152. data/doc/ep_flux/math-doc/document/img158.png +0 -0
  153. data/doc/ep_flux/math-doc/document/img159.png +0 -0
  154. data/doc/ep_flux/math-doc/document/img16.png +0 -0
  155. data/doc/ep_flux/math-doc/document/img160.png +0 -0
  156. data/doc/ep_flux/math-doc/document/img161.png +0 -0
  157. data/doc/ep_flux/math-doc/document/img162.png +0 -0
  158. data/doc/ep_flux/math-doc/document/img163.png +0 -0
  159. data/doc/ep_flux/math-doc/document/img164.png +0 -0
  160. data/doc/ep_flux/math-doc/document/img165.png +0 -0
  161. data/doc/ep_flux/math-doc/document/img166.png +0 -0
  162. data/doc/ep_flux/math-doc/document/img167.png +0 -0
  163. data/doc/ep_flux/math-doc/document/img168.png +0 -0
  164. data/doc/ep_flux/math-doc/document/img169.png +0 -0
  165. data/doc/ep_flux/math-doc/document/img17.png +0 -0
  166. data/doc/ep_flux/math-doc/document/img170.png +0 -0
  167. data/doc/ep_flux/math-doc/document/img171.png +0 -0
  168. data/doc/ep_flux/math-doc/document/img172.png +0 -0
  169. data/doc/ep_flux/math-doc/document/img173.png +0 -0
  170. data/doc/ep_flux/math-doc/document/img174.png +0 -0
  171. data/doc/ep_flux/math-doc/document/img175.png +0 -0
  172. data/doc/ep_flux/math-doc/document/img176.png +0 -0
  173. data/doc/ep_flux/math-doc/document/img177.png +0 -0
  174. data/doc/ep_flux/math-doc/document/img178.png +0 -0
  175. data/doc/ep_flux/math-doc/document/img179.png +0 -0
  176. data/doc/ep_flux/math-doc/document/img18.png +0 -0
  177. data/doc/ep_flux/math-doc/document/img180.png +0 -0
  178. data/doc/ep_flux/math-doc/document/img181.png +0 -0
  179. data/doc/ep_flux/math-doc/document/img182.png +0 -0
  180. data/doc/ep_flux/math-doc/document/img183.png +0 -0
  181. data/doc/ep_flux/math-doc/document/img184.png +0 -0
  182. data/doc/ep_flux/math-doc/document/img185.png +0 -0
  183. data/doc/ep_flux/math-doc/document/img186.png +0 -0
  184. data/doc/ep_flux/math-doc/document/img187.png +0 -0
  185. data/doc/ep_flux/math-doc/document/img188.png +0 -0
  186. data/doc/ep_flux/math-doc/document/img189.png +0 -0
  187. data/doc/ep_flux/math-doc/document/img19.png +0 -0
  188. data/doc/ep_flux/math-doc/document/img190.png +0 -0
  189. data/doc/ep_flux/math-doc/document/img191.png +0 -0
  190. data/doc/ep_flux/math-doc/document/img192.png +0 -0
  191. data/doc/ep_flux/math-doc/document/img193.png +0 -0
  192. data/doc/ep_flux/math-doc/document/img194.png +0 -0
  193. data/doc/ep_flux/math-doc/document/img195.png +0 -0
  194. data/doc/ep_flux/math-doc/document/img196.png +0 -0
  195. data/doc/ep_flux/math-doc/document/img197.png +0 -0
  196. data/doc/ep_flux/math-doc/document/img198.png +0 -0
  197. data/doc/ep_flux/math-doc/document/img199.png +0 -0
  198. data/doc/ep_flux/math-doc/document/img2.png +0 -0
  199. data/doc/ep_flux/math-doc/document/img20.png +0 -0
  200. data/doc/ep_flux/math-doc/document/img200.png +0 -0
  201. data/doc/ep_flux/math-doc/document/img21.png +0 -0
  202. data/doc/ep_flux/math-doc/document/img22.png +0 -0
  203. data/doc/ep_flux/math-doc/document/img23.png +0 -0
  204. data/doc/ep_flux/math-doc/document/img24.png +0 -0
  205. data/doc/ep_flux/math-doc/document/img25.png +0 -0
  206. data/doc/ep_flux/math-doc/document/img26.png +0 -0
  207. data/doc/ep_flux/math-doc/document/img27.png +0 -0
  208. data/doc/ep_flux/math-doc/document/img28.png +0 -0
  209. data/doc/ep_flux/math-doc/document/img29.png +0 -0
  210. data/doc/ep_flux/math-doc/document/img3.png +0 -0
  211. data/doc/ep_flux/math-doc/document/img30.png +0 -0
  212. data/doc/ep_flux/math-doc/document/img31.png +0 -0
  213. data/doc/ep_flux/math-doc/document/img32.png +0 -0
  214. data/doc/ep_flux/math-doc/document/img33.png +0 -0
  215. data/doc/ep_flux/math-doc/document/img34.png +0 -0
  216. data/doc/ep_flux/math-doc/document/img35.png +0 -0
  217. data/doc/ep_flux/math-doc/document/img36.png +0 -0
  218. data/doc/ep_flux/math-doc/document/img37.png +0 -0
  219. data/doc/ep_flux/math-doc/document/img38.png +0 -0
  220. data/doc/ep_flux/math-doc/document/img39.png +0 -0
  221. data/doc/ep_flux/math-doc/document/img4.png +0 -0
  222. data/doc/ep_flux/math-doc/document/img40.png +0 -0
  223. data/doc/ep_flux/math-doc/document/img41.png +0 -0
  224. data/doc/ep_flux/math-doc/document/img42.png +0 -0
  225. data/doc/ep_flux/math-doc/document/img43.png +0 -0
  226. data/doc/ep_flux/math-doc/document/img44.png +0 -0
  227. data/doc/ep_flux/math-doc/document/img45.png +0 -0
  228. data/doc/ep_flux/math-doc/document/img46.png +0 -0
  229. data/doc/ep_flux/math-doc/document/img47.png +0 -0
  230. data/doc/ep_flux/math-doc/document/img48.png +0 -0
  231. data/doc/ep_flux/math-doc/document/img49.png +0 -0
  232. data/doc/ep_flux/math-doc/document/img5.png +0 -0
  233. data/doc/ep_flux/math-doc/document/img50.png +0 -0
  234. data/doc/ep_flux/math-doc/document/img51.png +0 -0
  235. data/doc/ep_flux/math-doc/document/img52.png +0 -0
  236. data/doc/ep_flux/math-doc/document/img53.png +0 -0
  237. data/doc/ep_flux/math-doc/document/img54.png +0 -0
  238. data/doc/ep_flux/math-doc/document/img55.png +0 -0
  239. data/doc/ep_flux/math-doc/document/img56.png +0 -0
  240. data/doc/ep_flux/math-doc/document/img57.png +0 -0
  241. data/doc/ep_flux/math-doc/document/img58.png +0 -0
  242. data/doc/ep_flux/math-doc/document/img59.png +0 -0
  243. data/doc/ep_flux/math-doc/document/img6.png +0 -0
  244. data/doc/ep_flux/math-doc/document/img60.png +0 -0
  245. data/doc/ep_flux/math-doc/document/img61.png +0 -0
  246. data/doc/ep_flux/math-doc/document/img62.png +0 -0
  247. data/doc/ep_flux/math-doc/document/img63.png +0 -0
  248. data/doc/ep_flux/math-doc/document/img64.png +0 -0
  249. data/doc/ep_flux/math-doc/document/img65.png +0 -0
  250. data/doc/ep_flux/math-doc/document/img66.png +0 -0
  251. data/doc/ep_flux/math-doc/document/img67.png +0 -0
  252. data/doc/ep_flux/math-doc/document/img68.png +0 -0
  253. data/doc/ep_flux/math-doc/document/img69.png +0 -0
  254. data/doc/ep_flux/math-doc/document/img7.png +0 -0
  255. data/doc/ep_flux/math-doc/document/img70.png +0 -0
  256. data/doc/ep_flux/math-doc/document/img71.png +0 -0
  257. data/doc/ep_flux/math-doc/document/img72.png +0 -0
  258. data/doc/ep_flux/math-doc/document/img73.png +0 -0
  259. data/doc/ep_flux/math-doc/document/img74.png +0 -0
  260. data/doc/ep_flux/math-doc/document/img75.png +0 -0
  261. data/doc/ep_flux/math-doc/document/img76.png +0 -0
  262. data/doc/ep_flux/math-doc/document/img77.png +0 -0
  263. data/doc/ep_flux/math-doc/document/img78.png +0 -0
  264. data/doc/ep_flux/math-doc/document/img79.png +0 -0
  265. data/doc/ep_flux/math-doc/document/img8.png +0 -0
  266. data/doc/ep_flux/math-doc/document/img80.png +0 -0
  267. data/doc/ep_flux/math-doc/document/img81.png +0 -0
  268. data/doc/ep_flux/math-doc/document/img82.png +0 -0
  269. data/doc/ep_flux/math-doc/document/img83.png +0 -0
  270. data/doc/ep_flux/math-doc/document/img84.png +0 -0
  271. data/doc/ep_flux/math-doc/document/img85.png +0 -0
  272. data/doc/ep_flux/math-doc/document/img86.png +0 -0
  273. data/doc/ep_flux/math-doc/document/img87.png +0 -0
  274. data/doc/ep_flux/math-doc/document/img88.png +0 -0
  275. data/doc/ep_flux/math-doc/document/img89.png +0 -0
  276. data/doc/ep_flux/math-doc/document/img9.png +0 -0
  277. data/doc/ep_flux/math-doc/document/img90.png +0 -0
  278. data/doc/ep_flux/math-doc/document/img91.png +0 -0
  279. data/doc/ep_flux/math-doc/document/img92.png +0 -0
  280. data/doc/ep_flux/math-doc/document/img93.png +0 -0
  281. data/doc/ep_flux/math-doc/document/img94.png +0 -0
  282. data/doc/ep_flux/math-doc/document/img95.png +0 -0
  283. data/doc/ep_flux/math-doc/document/img96.png +0 -0
  284. data/doc/ep_flux/math-doc/document/img97.png +0 -0
  285. data/doc/ep_flux/math-doc/document/img98.png +0 -0
  286. data/doc/ep_flux/math-doc/document/img99.png +0 -0
  287. data/doc/ep_flux/math-doc/document/index.html +101 -0
  288. data/doc/ep_flux/math-doc/document/internals.pl +258 -0
  289. data/doc/ep_flux/math-doc/document/labels.pl +265 -0
  290. data/doc/ep_flux/math-doc/document/next.png +0 -0
  291. data/doc/ep_flux/math-doc/document/next_g.png +0 -0
  292. data/doc/ep_flux/math-doc/document/node1.html +104 -0
  293. data/doc/ep_flux/math-doc/document/node10.html +164 -0
  294. data/doc/ep_flux/math-doc/document/node11.html +86 -0
  295. data/doc/ep_flux/math-doc/document/node12.html +166 -0
  296. data/doc/ep_flux/math-doc/document/node13.html +897 -0
  297. data/doc/ep_flux/math-doc/document/node14.html +1065 -0
  298. data/doc/ep_flux/math-doc/document/node15.html +72 -0
  299. data/doc/ep_flux/math-doc/document/node16.html +81 -0
  300. data/doc/ep_flux/math-doc/document/node2.html +82 -0
  301. data/doc/ep_flux/math-doc/document/node3.html +91 -0
  302. data/doc/ep_flux/math-doc/document/node4.html +149 -0
  303. data/doc/ep_flux/math-doc/document/node5.html +330 -0
  304. data/doc/ep_flux/math-doc/document/node6.html +99 -0
  305. data/doc/ep_flux/math-doc/document/node7.html +98 -0
  306. data/doc/ep_flux/math-doc/document/node8.html +83 -0
  307. data/doc/ep_flux/math-doc/document/node9.html +140 -0
  308. data/doc/ep_flux/math-doc/document/prev.png +0 -0
  309. data/doc/ep_flux/math-doc/document/prev_g.png +0 -0
  310. data/doc/ep_flux/math-doc/document/up.png +0 -0
  311. data/doc/ep_flux/math-doc/document/up_g.png +0 -0
  312. data/doc/ep_flux/math-doc/document.pdf +0 -0
  313. data/doc/ep_flux/math-doc/document.tex +2018 -0
  314. data/doc/gdir.html +412 -0
  315. data/doc/gdir_client.html +16 -0
  316. data/doc/gdir_connect_ftp-like.html +61 -0
  317. data/doc/gdir_server.html +33 -0
  318. data/doc/ggraph.html +1332 -0
  319. data/doc/gpcat.html +27 -0
  320. data/doc/gpcut.html +27 -0
  321. data/doc/gphys.html +501 -0
  322. data/doc/gphys_fft.html +183 -0
  323. data/doc/gphys_grads_io.html +69 -0
  324. data/doc/gphys_grib_io.html +82 -0
  325. data/doc/gphys_io.html +96 -0
  326. data/doc/gphys_io_common.html +18 -0
  327. data/doc/gphys_netcdf_io.html +283 -0
  328. data/doc/gplist.html +23 -0
  329. data/doc/gpmath.html +34 -0
  330. data/doc/gpmaxmin.html +30 -0
  331. data/doc/gpprint.html +32 -0
  332. data/doc/gpview.html +187 -0
  333. data/doc/grads2nc_with_gphys.html +23 -0
  334. data/doc/grads_gridded.html +307 -0
  335. data/doc/grib.html +101 -0
  336. data/doc/grid.html +240 -0
  337. data/doc/index.html +125 -0
  338. data/doc/index.rd +121 -0
  339. data/doc/netcdf_convention.html +136 -0
  340. data/doc/unumeric.html +127 -0
  341. data/doc/update +64 -0
  342. data/doc/varray.html +293 -0
  343. data/doc/varraycomposite.html +67 -0
  344. data/lib/numru/dclext_datetime_ax.rb +220 -0
  345. data/lib/numru/derivative.rb +298 -0
  346. data/lib/numru/gdir.rb +1038 -0
  347. data/lib/numru/gdir_connect_ftp-like.rb +149 -0
  348. data/lib/numru/ggraph.rb +4604 -0
  349. data/lib/numru/ggraph_on_merdional_section.rb +178 -0
  350. data/lib/numru/gphys/attribute.rb +130 -0
  351. data/lib/numru/gphys/attributenetcdf.rb +80 -0
  352. data/lib/numru/gphys/axis.rb +958 -0
  353. data/lib/numru/gphys/coordmapping.rb +286 -0
  354. data/lib/numru/gphys/coordtransform.rb +209 -0
  355. data/lib/numru/gphys/derivative.rb +297 -0
  356. data/lib/numru/gphys/ep_flux.rb +868 -0
  357. data/lib/numru/gphys/gpcommon.rb +52 -0
  358. data/lib/numru/gphys/gphys.rb +1121 -0
  359. data/lib/numru/gphys/gphys_fft.rb +538 -0
  360. data/lib/numru/gphys/gphys_grads_io.rb +212 -0
  361. data/lib/numru/gphys/gphys_grib_io.rb +214 -0
  362. data/lib/numru/gphys/gphys_io.rb +363 -0
  363. data/lib/numru/gphys/gphys_io_common.rb +126 -0
  364. data/lib/numru/gphys/gphys_netcdf_io.rb +767 -0
  365. data/lib/numru/gphys/gphys_nusdas_io.rb +78 -0
  366. data/lib/numru/gphys/grads_gridded.rb +1539 -0
  367. data/lib/numru/gphys/grib.rb +2005 -0
  368. data/lib/numru/gphys/grib_params.rb +1270 -0
  369. data/lib/numru/gphys/grid.rb +602 -0
  370. data/lib/numru/gphys/netcdf_convention.rb +366 -0
  371. data/lib/numru/gphys/subsetmapping.rb +332 -0
  372. data/lib/numru/gphys/unumeric.rb +452 -0
  373. data/lib/numru/gphys/varray.rb +1079 -0
  374. data/lib/numru/gphys/varraycomposite.rb +415 -0
  375. data/lib/numru/gphys/varraygrads.rb +225 -0
  376. data/lib/numru/gphys/varraygrib.rb +177 -0
  377. data/lib/numru/gphys/varraynetcdf.rb +348 -0
  378. data/lib/numru/gphys/varraynusdas.rb +59 -0
  379. data/lib/numru/gphys.rb +7 -0
  380. data/lib/numru/htdir.rb +170 -0
  381. data/lib/numru/vizshot.rb +697 -0
  382. data/sample/cira86_to_nc.rb +122 -0
  383. data/sample/druby_cli1.rb +21 -0
  384. data/sample/druby_cli2.rb +34 -0
  385. data/sample/druby_serv1.rb +30 -0
  386. data/sample/druby_serv2.rb +64 -0
  387. data/sample/ep_flux/demo_NCEP_1.rb +48 -0
  388. data/sample/ep_flux/demo_NCEP_2.rb +57 -0
  389. data/sample/ep_flux/demo_NCEP_3.rb +81 -0
  390. data/sample/ggraph_latlon_labelling_dr002690.rb +159 -0
  391. data/sample/ggraph_mapfit-axes_dr002687.rb +131 -0
  392. data/sample/map_projection.rb +121 -0
  393. data/test/test_ep_flux.rb +533 -0
  394. data/testdata/T.jan.ctl +12 -0
  395. data/testdata/T.jan.dat +0 -0
  396. data/testdata/T.jan.grib +0 -0
  397. data/testdata/T.jan.nc +0 -0
  398. data/testdata/T.jan.packed.withmiss.nc +0 -0
  399. data/testdata/UV.jan.nc +0 -0
  400. data/testdata/cira86.dat +1332 -0
  401. metadata +527 -0
@@ -0,0 +1,2005 @@
1
+ =begin
2
+ =Status
3
+ * only a Lon-Lat coordinate is supported
4
+ * only simple pakking is supported
5
+ * variable list is not complete for NCEP and ECMWF
6
+ =end
7
+ require "narray_miss"
8
+ require "date"
9
+ require "time"
10
+
11
+ module NumRu
12
+ module GribUtils
13
+ require "numru/gphys/grib_params"
14
+ private
15
+ def str2uint1(str)
16
+ return nil if str.length==0
17
+ return str[0]
18
+ end
19
+ def str2uint2(str)
20
+ return nil if str.length==0
21
+ return (str[0]<<8)+str[1]
22
+ end
23
+ def str2uint3(str)
24
+ return nil if str.length==0
25
+ return (str[0]<<16)+(str[1]<<8)+str[2]
26
+ end
27
+ =begin
28
+ def str2uint(str)
29
+ return nil until str
30
+ return str.unpack("H*")[0].hex
31
+ end
32
+ =end
33
+ def str2int1(str)
34
+ n = str2uint1(str)
35
+ return n && n > 127 ? 128-n : n
36
+ end
37
+ def str2int2(str)
38
+ n = str2uint2(str)
39
+ return n && n > 32767 ? 32768-n : n
40
+ end
41
+ def str2int3(str)
42
+ n = str2uint3(str)
43
+ return n && n > 8388607 ? 8388608-n : n
44
+ end
45
+ =begin
46
+ def str2int(str)
47
+ return nil if str.length==0
48
+ ary = str.unpack("H*")
49
+ top = ary[0]
50
+ fact = 1
51
+ if top[0,1]>"7"
52
+ ary[0][0] = (top[0,1].hex-8).to_s
53
+ fact = -1
54
+ end
55
+ return ary.join("").hex*fact
56
+ end
57
+ =end
58
+ def uint2str(i,len)
59
+ str = [sprintf("%0#{len*2}x",i)].pack("H*")
60
+ str.length==len || raise("str length is not valid")
61
+ return str
62
+ end
63
+ def int2str(i,len)
64
+ flag = i<0
65
+ i = -i if flag
66
+ str = sprintf("%0#{len*2}x",i)
67
+ str[0..0] = sprintf("%x",str[0..0].hex+8) if flag
68
+ str = [str].pack("H*")
69
+ str.length==len || raise("str length is not valid")
70
+ return str
71
+ end
72
+ def float_value( str )
73
+ str.length==4 || raise("str length must be 4")
74
+ sa = str2int1( str[0,1] )
75
+ s = (sa<0) ? -1 : 1
76
+ a = sa.abs
77
+ b = str2uint3( str[1,3] )
78
+ return s*(2.0)**(-24.0)*b*(16.0)**(a-64.0)
79
+ end
80
+ def get_bits( str, nstep, nbits, sbu, ebu, type )
81
+ len = str.length
82
+ bx = NArray.to_na(str,NArray::BYTE)
83
+ nb = nbits/nstep
84
+ y = NArray.new(type,nb).indgen(nb-1,-1)
85
+ if nstep==8
86
+ x = bx.to_type(type)
87
+ y = 256**y
88
+ elsif nstep==4
89
+ x = NArray.new(type,2,len)
90
+ x[0,true] = (bx&240)/16
91
+ x[1,true] = bx&15
92
+ x.reshape!(len*2)
93
+ y = 16**y
94
+ elsif nstep==2
95
+ x = NArray.new(type,4,len)
96
+ x[0,true] = (bx&192)/64
97
+ x[1,true] = (bx&48)/16
98
+ x[2,true] = (bx&12)/4
99
+ x[3,true] = bx&3
100
+ x.reshape!(len*4)
101
+ y = 4**y
102
+ else
103
+ x = NArray.new(type,8,len)
104
+ x[0,true] = (bx&128)/128
105
+ x[1,true] = (bx&64)/64
106
+ x[2,true] = (bx&32)/32
107
+ x[3,true] = (bx&16)/16
108
+ x[4,true] = (bx&8)/8
109
+ x[5,true] = (bx&4)/4
110
+ x[6,true] = (bx&2)/2
111
+ x[7,true] = bx&1
112
+ x.reshape!(len*8)
113
+ y = 2**y
114
+ end
115
+ x = x[sbu..-1-ebu]
116
+ x.reshape!(nb,x.length/nb)
117
+ return (x*y).sum(0)
118
+ end
119
+ def data2str(data, nstep, nbits)
120
+ len = data.length
121
+ data.reshape!(len)
122
+ nb = nbits/nstep
123
+ x = NArray.byte(nb,len)
124
+ nb.times{|n|
125
+ x[nb-n-1,true] = (data/2**(n*nstep))&(2**nstep-1)
126
+ }
127
+ nb2 = 8/nstep
128
+ y = NArray.byte(nb2).indgen(nb2-1,-1)
129
+ y = (2**nstep)**y
130
+ ebu = nb2-x.length%nb2
131
+ ebu = 0 if ebu==nb2
132
+ x2 = NArray.byte(x.length+ebu)
133
+ x2[0..-1-ebu] = x.reshape!(x.length)
134
+ x2.reshape!(nb2,x2.length/nb2)
135
+ x2 = (x2*y).sum(0)
136
+ return [x2.to_s,ebu*nstep]
137
+ end
138
+
139
+ def gausslat(ny)
140
+ # this method was written by Y.Kitamura
141
+ # and modified by S.Nishizawa
142
+ glat = NArray.sfloat(ny)
143
+ gweight = NArray.sfloat(ny)
144
+
145
+ eps = 1.0
146
+ while (eps + 1.0 != 1.0)
147
+ eps = eps/2.0
148
+ end
149
+ eps = eps*16.0
150
+
151
+ 0.upto(ny/2-1) do |i|
152
+ y = Math::sin(Math::PI*(ny + 1.0 - 2.0*(i+1.0))/(2.0*ny + 1.0))
153
+ tmp = 1.0
154
+ while ((tmp/y).abs > eps)
155
+ p0 = 0.0
156
+ p1 = 1.0
157
+ 1.step(ny-1, 2) do |j|
158
+ p0 = ((2*j-1)*y*p1 - (j-1)*p0)/j
159
+ p1 = ((2*j+1)*y*p0 - j*p1)/(j+1)
160
+ end
161
+ p2 = ny*(p0 - y*p1)/(1.0 - y*y)
162
+ tmp = p1/p2
163
+ y = y - tmp
164
+ end
165
+ glat[i] = y
166
+ glat[ny-i-1] = -y
167
+ gweight[i] = 1.0/(p2*p2*(1.0 - glat[i]*glat[i]))
168
+ gweight[ny-i-1] = gweight[i]
169
+ end
170
+ return NMath::asin(glat)*180/Math::PI
171
+ end
172
+
173
+ def get_time(ary)
174
+ d = (ary[0]-D19000101).to_i
175
+ h,m = ary[1]
176
+ return d*24+h+m/60
177
+ end
178
+
179
+ end
180
+
181
+ class Grib
182
+ private
183
+ class GribSegment
184
+ class << self
185
+ include GribUtils
186
+ def create(file)
187
+ obj = GribSegment.new
188
+ obj.file = file
189
+ obj.is = GribIS.new(obj)
190
+ obj.pds = GribPDS.new(obj)
191
+ obj.gds = GribGDS.new(obj)
192
+ obj.bms = GribBMS.new(obj)
193
+ obj.bds = GribBDS.new(obj)
194
+ obj.es = GribES.new(obj)
195
+ obj.is.update_total_length
196
+ return obj
197
+ end
198
+ def parse(file)
199
+ obj = GribSegment.new
200
+ obj.file = file
201
+ obj.pos = file.pos
202
+
203
+ is = GribIS.new(obj,file.read(8))
204
+ unless is.grib?
205
+ raise "This file is not Grib file (INITIAL SECTION)"
206
+ end
207
+ obj.is = is
208
+
209
+ pds = GribPDS.new(obj,file.read(str2uint3(file.read(3))-3))
210
+ obj.pds = pds
211
+
212
+ str = pds.gds? ? file.read(str2uint3(file.read(3))-3) : nil
213
+ gds = GribGDS.new(obj,str)
214
+ obj.gds = gds
215
+
216
+ str = pds.bms? ? file.read(str2uint3(file.read(3))-3) : nil
217
+ bms = GribBMS.new(obj,str)
218
+ obj.bms = bms
219
+
220
+ len = str2uint3(file.read(3))
221
+ bds = GribBDS.new(obj,file.pos,len)
222
+ obj.bds = bds
223
+ file.seek(len-3,IO::SEEK_CUR)
224
+
225
+ es = GribES.new(obj,file.read(4))
226
+ unless es.grib?
227
+ raise "This file is not Grib file (END SECTION)"
228
+ end
229
+ obj.es = es
230
+
231
+ if is.total_length!=is.length+pds.length+gds.length+bms.length+bds.length+es.length
232
+ raise "total length is not equal to the sum of each section"
233
+ end
234
+
235
+ return obj
236
+ end
237
+ end
238
+ attr_accessor :file, :pos
239
+ attr_accessor :is, :pds, :gds, :bms, :bds, :es
240
+ def set_xy(x,y)
241
+ pds.set_gds(true)
242
+ if x.att("long_name").downcase=="longitude" && y.att("long_name").downcase=="latitude"
243
+ xv = x.val
244
+ yv = y.val
245
+ rel = false
246
+ if (xv[1]-xv[0])==(xv[-1]-xv[-2]) && (yv[1]-yv[0])==(yv[-1]-yv[-2])
247
+ id = 0
248
+ else
249
+ raise "not defined yet"
250
+ end
251
+ elsif y.att("long_name").downcase=="longitude" && x.att("long_name").downcase=="latitude"
252
+ xv = y.val
253
+ yv = x.val
254
+ rel = true
255
+ if (xv[1]-xv[0])==(xv[-1]-xv[-2]) && (yv[1]-yv[0])==(yv[-1]-yv[-2])
256
+ id = 0
257
+ else
258
+ raise "not defined yet"
259
+ end
260
+ else
261
+ raise "not defined yet"
262
+ end
263
+ gds.set_grid(id,xv,yv,rel)
264
+ end
265
+ def set_level(z)
266
+ if Array===z
267
+ id = Z_TYPES.invert[Z_TYPES.values.assoc(z[0])]
268
+ id = 100 if id.nil?
269
+ pds.set_z_id(id)
270
+ pds.set_z_value(z[1])
271
+ else
272
+ id = Z_TYPES.invert[Z_TYPES.values.assoc(z)]
273
+ pds.set_z_id(id)
274
+ end
275
+ end
276
+ def set_time(t)
277
+ if String===t
278
+ ye,mo,da,ho,mi, = Time.parse(t).to_a.reverse![4..-2]
279
+ else
280
+ if t.nil?
281
+ ye = 0
282
+ mo = 1
283
+ da = 1
284
+ ho = 0
285
+ mi = 0
286
+ else
287
+ d = D19000101 + t/24
288
+ ye = d.year
289
+ mo = d.month
290
+ da = d.day
291
+ ho = t%24
292
+ mi = 0
293
+ end
294
+ end
295
+ pds.set_initial(ye,mo,da,ho,mi)
296
+ end
297
+ def set_var(var,name,units)
298
+ is.set_version(1)
299
+ pds.set_version(2)
300
+ pds.set_center_id(0)
301
+ pds.set_pid(0)
302
+ id = PARAMS_2.invert[NAMES_UNITS.invert[NAMES_UNITS.values.assoc(name)]]
303
+ id = 000 if id.nil?
304
+ pds.set_name_id(id)
305
+ pds.set_time_unit_id(0)
306
+ pds.set_p1(0)
307
+ pds.set_p2(0)
308
+ pds.set_time_range_id(1)
309
+ pds.set_ave(0)
310
+ pds.set_miss(0)
311
+ pds.set_sub_center_id(0)
312
+ pds.set_dfact(0)
313
+ if NArrayMiss===var
314
+ mask = var.get_mask!
315
+ if mask.count_false>0
316
+ pds.set_bms(true)
317
+ bms.set_map_number(0)
318
+ bms.set_map(mask)
319
+ end
320
+ end
321
+ bds.set_grid(true)
322
+ bds.set_simple(true)
323
+ if units && pds.unit
324
+ f,o = Units[units].factor_and_offset(Units[pds.unit])
325
+ var = var*f+o
326
+ end
327
+ if var.typecode==NArray::SINT || var.typecode==NArray::INT
328
+ bds.set_ingeger(true)
329
+ else
330
+ bds.set_float(true)
331
+ end
332
+ bds.set_value(var)
333
+ end
334
+ def write
335
+ tlen = is.update_total_length
336
+ len = 0
337
+ len += @file.write(is.get)
338
+ len += @file.write(pds.get)
339
+ len += @file.write(gds.get)
340
+ len += @file.write(bms.get)
341
+ len += @file.write(bds.get)
342
+ len += @file.write(es.get)
343
+ tlen==len || raise("length is not correct")
344
+ end
345
+ end # end definition of class GribSegment
346
+ class GribIS
347
+ include GribUtils
348
+ def initialize(sgm,str=nil)
349
+ @sgm = sgm
350
+ @is = str || "GRIB"+uint2str(8,3)+uint2str(2,1)
351
+ end
352
+ def length
353
+ return 8
354
+ end
355
+ def grib?
356
+ return @is[0..3]=="GRIB"
357
+ end
358
+ def total_length
359
+ return str2uint3( @is[4,3] )
360
+ end
361
+ def update_total_length
362
+ len = self.length+@sgm.pds.length+@sgm.gds.length+@sgm.bms.length+@sgm.bds.length+@sgm.es.length
363
+ @is[4..6] = uint2str(len,3)
364
+ return len
365
+ end
366
+ def varsion
367
+ return str2uint1( @is[7,1] )
368
+ end
369
+ def set_version(ver)
370
+ @is[7..7] = uint2str(ver,1)
371
+ return ver
372
+ end
373
+ alias :version= :set_version
374
+ def get
375
+ @is
376
+ end
377
+ end # end definition of class GribIS
378
+ class GribPDS
379
+ include GribUtils
380
+ private
381
+ def param
382
+ nid = str2uint1(@pds[5,1])
383
+ params = nil
384
+ case version
385
+ when 0
386
+ params = PARAMS_0
387
+ when 1
388
+ params = PARAMS_1
389
+ when 2,3
390
+ if nid<128
391
+ params = PARAMS_2
392
+ else
393
+ if cid==7 # NCEP
394
+ params = PARAMS_NCEP_2
395
+ end
396
+ end
397
+ else
398
+ if cid==98 # ECMWF
399
+ if version==128
400
+ params = PARAMS_ECMWF_128
401
+ elsif version == 162
402
+ params = PARAMS_ECMWF_162
403
+ end
404
+ end
405
+ end
406
+ if params
407
+ if para_id = params[nid]
408
+ if para = NAMES_UNITS[para_id]
409
+ return para
410
+ else
411
+ $stderr.printf "parameter ID #{nid} in version #{version} has not defined yet\n"
412
+ end
413
+ else
414
+ $stderr.printf "parameter ID #{nid} in version #{version} has not defined yet\n"
415
+ end
416
+ else
417
+ $stderr.printf "parameter table version #{version} has not defined yet\n"
418
+ end
419
+ return ["unknown (#{nid})", nid.to_s, "-", nil]
420
+ end
421
+ def cid
422
+ return str2uint1(@pds[1,1])
423
+ end
424
+ def initialize(sgm,str=nil)
425
+ @sgm = sgm
426
+ @pds = str || "\000"*25
427
+ end
428
+ public
429
+ def length
430
+ @pds.length+3
431
+ end
432
+ def version
433
+ return str2uint1( @pds[0,1] )
434
+ end
435
+ def set_version(ver)
436
+ @pds[0..0] = uint2str(ver,1)
437
+ return ver
438
+ end
439
+ alias :version= :set_version
440
+ def center
441
+ return CENTERS[cid]
442
+ end
443
+ def set_center_id(id)
444
+ @pds[1..1] = uint2str(id,1)
445
+ end
446
+ alias :center_id= :set_center_id
447
+ def pid
448
+ return str2uint1( @pds[2,1] )
449
+ end
450
+ def set_pid(id)
451
+ @pds[2..2] = uint2str(id,1)
452
+ return id
453
+ end
454
+ alias :pid= :set_pid
455
+ def gid
456
+ return str2uint1( @pds[3,1] )
457
+ end
458
+ def set_gid(id)
459
+ @pds[3..3] = uint2str(id,1)
460
+ return id
461
+ end
462
+ alias :gid= :set_gid
463
+ def gds?
464
+ flag = str2uint1( @pds[4,1] )
465
+ return (flag>>7)&1==1
466
+ end
467
+ def set_gds(gds)
468
+ flag = bms? ? 64 : 0
469
+ if gds
470
+ flag += 128
471
+ @pds[4..4] = uint2str(flag,1)
472
+ @sgm.gds.exist
473
+ set_gid(255)
474
+ return true
475
+ else
476
+ @pds[4..4] = uint2str(flag,1)
477
+ @sgm.gds.not_exist
478
+ return false
479
+ end
480
+ end
481
+ alias :gds= :set_gds
482
+ def bms?
483
+ flag = str2uint1( @pds[4,1] )
484
+ return (flag>>6)&1==1
485
+ end
486
+ def set_bms(bms)
487
+ flag = gds? ? 128 : 0
488
+ if bms
489
+ flag += 64
490
+ @pds[4..4] = uint2str(flag,1)
491
+ @sgm.bms.exist
492
+ return true
493
+ else
494
+ @pds[4..4] = uint2str(flag,1)
495
+ @sgm.bms.not_exist
496
+ return false
497
+ end
498
+ end
499
+ alias :bms= :set_bms
500
+ def name
501
+ return param[0]
502
+ end
503
+ def standard_name
504
+ return param[3]
505
+ end
506
+ def set_name_id(id)
507
+ @pds[5..5] = uint2str(id,1)
508
+ return id
509
+ end
510
+ alias :name_id= :set_name_id
511
+ def sname
512
+ zid = str2uint1( @pds[6,1] )
513
+ sn = param[1]
514
+ zt = Z_TYPES[zid]
515
+ zn = zt ? zt[1] : zid.to_s
516
+ return zn=="level" ? sn : sn+"_"+zn
517
+ end
518
+ def unit
519
+ return param[2]
520
+ end
521
+ def z_type
522
+ zid = str2uint1( @pds[6,1] )
523
+ zt = Z_TYPES[zid]
524
+ if zt
525
+ return zt[0]
526
+ else
527
+ $stderr.printf "z type (#{zid}) is not defined yet\n"
528
+ return zid.to_s
529
+ end
530
+ end
531
+ def set_z_id(id)
532
+ @pds[6..6] = uint2str(id,1)
533
+ return id
534
+ end
535
+ alias :z_id= :set_z_id
536
+ def z_sname
537
+ zid = str2uint1( @pds[6,1] )
538
+ if zn = Z_TYPES[zid]
539
+ return zn[1]
540
+ else
541
+ $stderr.printf "z type (#{zid}) is not defined yet\n"
542
+ return "unknown_#{zid}"
543
+ end
544
+ end
545
+ def z_value
546
+ type = str2uint1( @pds[6,1] )
547
+ str = @pds[7,2]
548
+ ary = Z_LEVELS[type]
549
+ if ary.nil?
550
+ ary = []
551
+ else
552
+ ary = ary.dup
553
+ end
554
+ if ary.length==1
555
+ ary[0] = ary[0].dup.update( {"value"=> str2uint2(str)} )
556
+ elsif ary.length==2
557
+ ary[0] = ary[0].dup.update( {"value"=> str2uint1(str[0,1])} )
558
+ ary[1] = ary[1].dup.update( {"value"=> str2uint1(str[1,1])} )
559
+ end
560
+ return ary
561
+ end
562
+ def set_z_value(val)
563
+ type = str2uint1( @pds[6,1] )
564
+ ary = Z_LEVELS[type]
565
+ val.length==ary.length || raise("length of val is not collect")
566
+ if val.length==1
567
+ @pds[7,2] = uint2str(val[0],2)
568
+ elsif val.length==2
569
+ @pds[7,1] = uint2str(val[0],1)
570
+ @pds[8,1] = uint2str(val[1],1)
571
+ else
572
+ raise "length of val is too large"
573
+ end
574
+ return val
575
+ end
576
+ alias :z_value= :set_z_value
577
+ def initial
578
+ return [str2uint1( @pds[21,1] ), str2uint1( @pds[9,1] ), str2uint1( @pds[10,1] ), str2uint1( @pds[11,1] ), str2uint1( @pds[12,1] ), str2uint1( @pds[13,1] )]
579
+ end
580
+ def set_initial(year,month,day,hour,min)
581
+ cent = year/100+1
582
+ year = year%100
583
+ @pds[21,1] = uint2str(cent,1)
584
+ @pds[9,1] = uint2str(year,1)
585
+ @pds[10,1] = uint2str(month,1)
586
+ @pds[11,1] = uint2str(day,1)
587
+ @pds[12,1] = uint2str(hour,1)
588
+ @pds[13,1] = uint2str(min,1)
589
+ return initial
590
+ end
591
+ alias :initial= :set_initial
592
+ def date
593
+ d = Date.new((str2uint1( @pds[21,1] )-1)*100+str2uint1( @pds[9,1] ),
594
+ str2uint1( @pds[10,1] ),
595
+ str2uint1( @pds[11,1] ) )
596
+ h = [str2uint1( @pds[12,1] ),str2uint1( @pds[13,1] )]
597
+ return [d,h]
598
+ end
599
+ def time_unit
600
+ return TIME_UNITS[ str2uint1( @pds[14,1] ) ]
601
+ end
602
+ def set_time_unit_id(id)
603
+ @pds[14,1] = uint2str(id,1)
604
+ return id
605
+ end
606
+ alias :time_unit_id= :set_time_unit_id
607
+ def p1
608
+ return str2uint1( @pds[15,1] )
609
+ end
610
+ def set_p1(i)
611
+ @pds[15,1] = uint2str(i,1)
612
+ return i
613
+ end
614
+ alias :p1= :set_p1
615
+ def p2
616
+ return str2uint1( @pds[16,1] )
617
+ end
618
+ def set_p2(i)
619
+ @pds[16,1] = uint2str(i,1)
620
+ return i
621
+ end
622
+ alias :p2= :set_p2
623
+ def time_range
624
+ return str2uint1( @pds[17,1] )
625
+ end
626
+ def set_time_range_id(id)
627
+ @pds[17,1] = uint2str(id,1)
628
+ return id
629
+ end
630
+ alias :time_range_id= :set_time_range_id
631
+ def ave
632
+ return str2uint2( @pds[18,2] )
633
+ end
634
+ def set_ave(val)
635
+ @pds[18,2] = uint2str(val,2)
636
+ return val
637
+ end
638
+ alias :ave= :set_ave
639
+ def miss
640
+ return str2uint1( @pds[20,1] )
641
+ end
642
+ def set_miss(val)
643
+ @pds[20,1] = uint2str(val,1)
644
+ return val
645
+ end
646
+ alias :miss= :set_miss
647
+ def sub_center
648
+ return str2uint1( @pds[22,1] )
649
+ end
650
+ def set_sub_center_id(id)
651
+ @pds[22,1] = uint2str(id,1)
652
+ return id
653
+ end
654
+ alias :sub_center_id= :set_sub_center_id
655
+ def dfact
656
+ return str2int2( @pds[23,2] )
657
+ end
658
+ def set_dfact(val)
659
+ @pds[23..24] = int2str(val,2)
660
+ return val
661
+ end
662
+ alias :dfact= :set_dfact
663
+ def get
664
+ uint2str(length,3)<<@pds
665
+ end
666
+ end # end definition of class GribPDS
667
+ class GribGDS
668
+ include GribUtils
669
+ private
670
+ def gtype
671
+ return str2uint1( @gds[2,1] )
672
+ end
673
+ def get_x_y(grid)
674
+ case gtype
675
+ when 0,4
676
+ #lon_lat (+GussLat)
677
+ flag = str2uint1( grid[10,1] )
678
+ flag_inc = (flag>>7)&1
679
+ flag = str2uint1( grid[21,1] )
680
+ flag_scani = (flag>>7)&1
681
+ flag_scanj = (flag>>6)&1
682
+ flag_ij = (flag>>5)&1
683
+
684
+ lon = Hash.new
685
+ lon["short_name"] = "lon"
686
+ lon["long_name"] = "longitude"
687
+ lon["units"] = "degrees_east"
688
+ nlon = str2uint2( grid[0,2] )
689
+ nlon=="ffff".hex && raise("not defined yet")
690
+ lo1 = str2int3( grid[7,3] )
691
+ lo2 = str2int3( grid[14,3] )
692
+ dlon = str2uint2( grid[17,2] )
693
+ if (!flag_inc)&&dlon==-"7fff".hex
694
+ dlon = (lo2-lo1)/(nlon-1)
695
+ else
696
+ if lo1>lo2
697
+ if dlon*(nlon-1)!=lo1-lo2
698
+ lo2 += 360000
699
+ else
700
+ dlon = -dlon
701
+ end
702
+ end
703
+ end
704
+ dlon2 = (lo2-lo1).to_f/(nlon-1)
705
+ dlon2.round==dlon.round || $stderr.print("Warning: dlon is not same: #{dlon2/1000} != #{dlon.to_f/1000}\n")
706
+ vlon = NArray.sfloat(nlon).indgen*dlon2+lo1
707
+ if flag_scani==1
708
+ vlon = vlon[-1..0]
709
+ end
710
+ lon["value"] = vlon/1000
711
+ lon["length"] = vlon.length
712
+
713
+ lat = Hash.new
714
+ lat["short_name"] = "lat"
715
+ lat["long_name"] = "latitude"
716
+ lat["units"] = "degrees_north"
717
+ nlat = str2uint2( grid[2,2] )
718
+ nlat=="ffff".hex && raise("not defined yet")
719
+ la1 = str2int3( grid[4,3] )
720
+ la2 = str2int3( grid[11,3] )
721
+ dlat = str2uint2( grid[19,2] )
722
+ if gtype==0
723
+ if (!flag_inc)&&dlat==-"7fff".hex
724
+ dlat = (la2-la1)/(nlat-1)
725
+ else
726
+ dlat = -dlat if la1>la2
727
+ end
728
+ dlat2 = (la2-la1).to_f/(nlat-1)
729
+ dlat2.round==dlat.round || raise("dlat is not same: #{dlat2/1000} != #{dlat.to_f/1000}\n")
730
+ vlat = NArray.sfloat(nlat).indgen*dlat2+la1
731
+ vlat = vlat/1000
732
+ elsif gtype==4
733
+ j = NArray.sfloat(dlat*2).indgen(1)
734
+ # glat = NMath::asin(NMath::cos((j-0.5)*Math::PI/dlat/2))*180/Math::PI
735
+ glat = gausslat(dlat*2)
736
+ glat = glat[-1..0] if la1>la2
737
+ tmp = (glat-la1.to_f/1000).abs
738
+ is = tmp.eq(tmp.min).where[0]
739
+ tmp = (glat-la2.to_f/1000).abs
740
+ ie = tmp.eq(tmp.min).where[0]
741
+ vlat = glat[is..ie]
742
+ vlat.length==nlat || raise("length of latitude is not same: #{vlat.length} != #{nlat}")
743
+ (vlat[0]*1000).round==la1.round || $stderr.printf("Warning: first of latitude is not same: #{vlat[0]} != #{la1.to_f/1000}\n")
744
+ (vlat[-1]*1000).round==la2.round || $stderr.printf("Warning: last of latitude is not same: #{vlat[-1]} != #{la2.to_f/1000}\n")
745
+ lat["type"] = "Gaussian latitude"
746
+ lat["number_of_latitude_circles"] = NArray[dlat*2]
747
+ end
748
+ if flag_scanj==1
749
+ vlat = vlat[-1..0]
750
+ end
751
+ lat["value"] = vlat
752
+ lat["length"] = vlat.length
753
+
754
+ if flag_ij==0
755
+ lon["ij"] = 0
756
+ lat["ij"] = 1
757
+ else
758
+ lon["ij"] = 1
759
+ lat["ij"] = 0
760
+ end
761
+ return [lon,lat]
762
+ when 1
763
+ #mercator
764
+ raise "not defined yet"
765
+ when 3
766
+ #lambert
767
+ raise "not defined yet"
768
+ when 5
769
+ #polar
770
+ raise "not defined yet"
771
+ when 50
772
+ #spherical
773
+ raise "not defined yet"
774
+ when 90
775
+ #space
776
+ raise "not defined yet"
777
+ else
778
+ raise "not defined yet"
779
+ end
780
+ end
781
+ def grid2str(gtype,x,y,rev=false)
782
+ case gtype
783
+ when 0,4
784
+ #lat_lon
785
+ grid = "\000"*26
786
+ nlon = x.length
787
+ nlat = y.length
788
+ grid[0,2] = uint2str(nlon,2)
789
+ grid[2,2] = uint2str(nlat,2)
790
+ vlon = x*1000
791
+ vlat = y*1000
792
+ grid[4,3] = int2str(vlat[0],3)
793
+ grid[7,3] = int2str(vlon[0],3)
794
+ flag = 1<<7
795
+ grid[10,1] = uint2str(flag,1)
796
+ grid[11,3] = int2str(vlat[-1],3)
797
+ grid[14,3] = int2str(vlon[-1],3)
798
+ dlon = ((vlon[-1]-vlon[0])/(nlon-1)).abs
799
+ grid[17,2] = uint2str(dlon,2)
800
+ if gtype==0
801
+ dlat = ((vlat[0]-vlat[-1])/(nlat-1)).abs
802
+ grid[19,2] = uint2str(dlat,2)
803
+ else
804
+ raise "not defined yet"
805
+ end
806
+ if rev
807
+ flag=1<<5
808
+ else
809
+ flag=0
810
+ end
811
+ grid[21,1] = uint2str(flag,1)
812
+ return grid
813
+ when 1
814
+ #mercator
815
+ raise "not defined yet"
816
+ when 3
817
+ #lambert
818
+ raise "not defined yet"
819
+ when 5
820
+ #polar
821
+ raise "not defined yet"
822
+ when 50
823
+ #spherical
824
+ raise "not defined yet"
825
+ when 90
826
+ #space
827
+ raise "not defined yet"
828
+ else
829
+ raise "not defined yet"
830
+ end
831
+ end
832
+ def initialize(sgm,str=nil)
833
+ @sgm = sgm
834
+ @gds = str
835
+ end
836
+
837
+ public
838
+ def exist
839
+ @gds = "\000"*41
840
+ @gds[1,1] = uint2str(255,1)
841
+ @sgm.is.update_total_length
842
+ end
843
+ def not_exist
844
+ @gds = nil
845
+ @sgm.is.update_total_length
846
+ end
847
+ def length
848
+ if @gds
849
+ return @gds.length+3
850
+ else
851
+ return 0
852
+ end
853
+ end
854
+ def nv
855
+ return str2uint1( @gds[0,1] )
856
+ end
857
+ def pv
858
+ pv = str2uint1( @gds[1,1] )
859
+ return nil if pv==255 || nv==0
860
+ return pv
861
+ end
862
+ def pl
863
+ pl = str2uint1( @gds[1,1] )
864
+ return nil if pl==255
865
+ return nv*4+pl
866
+ end
867
+ def grid_type
868
+ return GRID_TYPES[ gtype ]
869
+ end
870
+ def grid
871
+ if gtype==3||gtype==1
872
+ grid = @gds[3..38]
873
+ elsif gtype==90
874
+ grid = @gds[3..40]
875
+ else
876
+ grid = @gds[3..28]
877
+ end
878
+ return get_x_y(grid)
879
+ end
880
+ def set_grid(id,x,y,rev)
881
+ @gds[2..2] = uint2str(id,1)
882
+ if id==3||id==1
883
+ str = grid2str(id,x,y,rev)
884
+ str.length==36 || raise("length is not correct")
885
+ @gds[3..38] = str
886
+ @sgm.is.update_total_length
887
+ elsif id==90
888
+ str = grid2str(id,x,y,rev)
889
+ str.length==38 || raise("length is not correct")
890
+ @gds[3..40] = str
891
+ @sgm.is.update_total_length
892
+ else
893
+ str = grid2str(id,x,y,rev)
894
+ str.length==26 || raise("length is not correct")
895
+ @gds[3..28] = str
896
+ @sgm.is.update_total_length
897
+ end
898
+ return [id,x,y]
899
+ end
900
+ def list_pv
901
+ return nil unless pv
902
+ list = NArray.float(nv)
903
+ nv.times{|n|
904
+ list[n] = float_value( @gds[pv-4+n*4...pv-4+(n+1)*4] )
905
+ }
906
+ return list
907
+ end
908
+ def set_list_pv(list)
909
+ nv = list.length/4
910
+ @gds[0..0] = uint2str(nv,1)
911
+ raise "not defined yet"
912
+ if gtype==3||gtype==1
913
+ pv = 43
914
+ elsif gtype==90
915
+ pv = 45
916
+ else
917
+ pv = 33
918
+ end
919
+ @gds[1..1] = uint2str(pv,1)
920
+ @gds[pv-4..-1] = list
921
+ return true
922
+ end
923
+ alias :list_pv= :set_list_pv
924
+ def list_pl
925
+ return @gds[pl-4..-1] if pl
926
+ return nil
927
+ end
928
+ def set_list_pl(list)
929
+ raise "not defined yet"
930
+ pl = nv*4+pv
931
+ @gds[1..1] = uint2str(pl,1)
932
+ @gds[pl-4..-1] = list
933
+ return true
934
+ end
935
+ alias :list_pv= :set_list_pv
936
+ def eq?(str)
937
+ @gds==str
938
+ end
939
+ def ==(other)
940
+ if GribGDS===other
941
+ return other.eq?(@gds)
942
+ else
943
+ return false
944
+ end
945
+ end
946
+ def get
947
+ @gds && uint2str(length,3)<<@gds
948
+ end
949
+ end # end definition of class GribGDS
950
+ class GribBMS
951
+ include GribUtils
952
+ def initialize(sgm,str=nil)
953
+ @sgm = sgm
954
+ @bms = str
955
+ end
956
+ def exist
957
+ @bms = "\000"*3
958
+ @sgm.is.update_total_length
959
+ end
960
+ def not_exist
961
+ @bms = nil
962
+ @sgm.is.update_total_length
963
+ end
964
+ def length
965
+ if @bms
966
+ return @bms.length+3
967
+ else
968
+ return 0
969
+ end
970
+ end
971
+ def map_number
972
+ nmap = str2uint2( @bms[1,2] )
973
+ nmap = false if nmap==0
974
+ return nmap
975
+ end
976
+ def set_map_number(n)
977
+ @bms[1..2] = uint2str(n,2)
978
+ return n
979
+ end
980
+ alias :map_number= :set_map_number
981
+ def has_map?
982
+ return nil if @bms.nil?
983
+ return !map_number
984
+ end
985
+ def map
986
+ return nil unless has_map?
987
+ return get_bits( @bms[3..-1], 1,1, 0,str2uint1(@bms[0,1]), NArray::BYTE )
988
+ end
989
+ def set_map(mask)
990
+ map,n = data2str(mask,1,1)
991
+ @bms[0..0] = uint2str(n,1)
992
+ @bms = @bms[0,3]<<map
993
+ @sgm.is.update_total_length
994
+ return true
995
+ end
996
+ def get
997
+ @bms && uint2str(length,3)<<@bms
998
+ end
999
+ end # end definition of class GribBMS
1000
+ class GribBDS
1001
+ include GribUtils
1002
+ private
1003
+ def oct4
1004
+ return @oct4 if @oct4
1005
+ @sgm.file.seek(@pos, IO::SEEK_SET)
1006
+ @oct4 = str2uint1( @sgm.file.read(1) )
1007
+ return @oct4
1008
+ end
1009
+ def oct14
1010
+ return nil if flag4==0
1011
+ return @oct14 if @oct14
1012
+ @sgm.file.seek(@pos+10, IO::SEEK_SET)
1013
+ @oct14 = str2uint1( @sgm.file.read(1) )
1014
+ return @oct14
1015
+ end
1016
+ def flag1
1017
+ return (oct4>>7)&1
1018
+ end
1019
+ def flag2
1020
+ return (oct4>>6)&1
1021
+ end
1022
+ def flag3
1023
+ return (oct4>>5)&1
1024
+ end
1025
+ def flag4
1026
+ return (oct4>>4)&1
1027
+ end
1028
+ def flag6
1029
+ return oct14 && (oct14>>6)&1
1030
+ end
1031
+ def flag7
1032
+ return oct14 && (oct14>>5)&1
1033
+ end
1034
+ def flag8
1035
+ return oct14 && (oct14>>4)&1
1036
+ end
1037
+ def initialize(sgm,pos=nil,len=nil)
1038
+ @sgm = sgm
1039
+ @pos = pos
1040
+ if @pos.nil?
1041
+ @bds = "\000"*8
1042
+ @oct4 = 0
1043
+ @oct14 = 0
1044
+ else
1045
+ @length = len
1046
+ end
1047
+ end
1048
+ def get_value(file,pos,sb,eb,nbits,nstep)
1049
+ sbu = (sb%8)/nstep
1050
+ sb = sb/8
1051
+ ebu = eb%8
1052
+ ebu = (8-eb%8)/nstep unless ebu==0
1053
+ eb = (eb+7)/8
1054
+ return NArray.float(0) if (eb-sb)==0
1055
+ file.seek(pos+sb,IO::SEEK_SET)
1056
+ str = file.read(eb-sb)
1057
+ return get_bits(str,nstep,nbits,sbu,ebu,NArray::FLOAT)
1058
+ end
1059
+
1060
+ public
1061
+ def length
1062
+ if @pos
1063
+ return @length
1064
+ else
1065
+ return @bds.length+3
1066
+ end
1067
+ end
1068
+ def grid?
1069
+ return flag1==0
1070
+ end
1071
+ def set_grid(l)
1072
+ @oct4 = oct4&"7f".hex
1073
+ @oct4 += 128 unless l
1074
+ @bds[0,1] = uint2str(@oct4,1)
1075
+ return l
1076
+ end
1077
+ def spectrum?
1078
+ return flag1==1
1079
+ end
1080
+ def set_spectrum(l)
1081
+ @oct4 = oct4&"7f".hex
1082
+ @oct4 += 128 if l
1083
+ @bds[0,1] = uint2str(@oct4,1)
1084
+ return l
1085
+ end
1086
+ def simple?
1087
+ return flag2==0
1088
+ end
1089
+ def set_simple(l)
1090
+ @oct4 = oct4&"bf".hex
1091
+ @oct4 += 64 unless l
1092
+ @bds[0,1] = uint2str(@oct4,1)
1093
+ return l
1094
+ end
1095
+ def complex?
1096
+ return flag2==1
1097
+ end
1098
+ def set_complex(l)
1099
+ @oct4 = oct4&"bf".hex
1100
+ @oct4 += 64 if l
1101
+ @bds[0,1] = uint2str(@oct4,1)
1102
+ return l
1103
+ end
1104
+ def float?
1105
+ return flag3==0
1106
+ end
1107
+ def set_float(l)
1108
+ @oct4 = oct4&"df".hex
1109
+ @oct4 += 32 unless l
1110
+ @bds[0,1] = uint2str(@oct4,1)
1111
+ return l
1112
+ end
1113
+ def integer?
1114
+ return flag3==1
1115
+ end
1116
+ def set_integer(l)
1117
+ @oct4 = oct4&"df".hex
1118
+ @oct4 += 32 if l
1119
+ @bds[0,1] = uint2str(@oct4,1)
1120
+ return l
1121
+ end
1122
+ def single?
1123
+ return flag6 && flag6==0
1124
+ end
1125
+ def set_single(l)
1126
+ @oct14 = oct14&"7f".hex
1127
+ @oct14 += 128 unless l
1128
+ @oct4 = (oct4&"ef".hex)+16
1129
+ @bds[0,1] = uint2str(@oct4,1)
1130
+ @bds[10,1] = uint2str(@oct14,1)
1131
+ return l
1132
+ end
1133
+ def matrix?
1134
+ return flag6 && flag6==1
1135
+ end
1136
+ def set_matrix(l)
1137
+ @oct14 = oct14&"7f".hex
1138
+ @oct14 += 128 if l
1139
+ @oct4 = (oct4&"ef".hex)+16
1140
+ @bds[0,1] = uint2str(@oct4,1)
1141
+ @bds[10,1] = uint2str(@oct14,1)
1142
+ return l
1143
+ end
1144
+ def bit_maps?
1145
+ return flag7 && flag7==1
1146
+ end
1147
+ def set_bit_map(l)
1148
+ @oct14 = oct14&"bf".hex
1149
+ @oct14 += 64 if l
1150
+ @oct4 = (oct4&"ef".hex)+16
1151
+ @bds[0,1] = uint2str(@oct4,1)
1152
+ @bds[10,1] = uint2str(@oct14,1)
1153
+ return l
1154
+ end
1155
+ def constant?
1156
+ return flag8 && flag8==0
1157
+ end
1158
+ def set_constant(l)
1159
+ @oct14 = oct14&"df".hex
1160
+ @oct14 += 32 unless l
1161
+ @oct4 = (oct4&"ef".hex)+16
1162
+ @bds[0,1] = uint2str(@oct4,1)
1163
+ @bds[10,1] = uint2str(@oct14,1)
1164
+ return l
1165
+ end
1166
+ def offset
1167
+ return @offset if @offset
1168
+ @sgm.file.seek(@pos+3, IO::SEEK_SET)
1169
+ @offset = float_value(@sgm.file.read(4))
1170
+ return @offset
1171
+ end
1172
+ def efactor
1173
+ return @efactor if @efactor
1174
+ @sgm.file.seek(@pos+1, IO::SEEK_SET)
1175
+ @efactor = 2.0**str2int2( @sgm.file.read(2) )
1176
+ return @efactor
1177
+ end
1178
+ def value(shape,*arg)
1179
+ nbits_unuse = oct4&15
1180
+ @sgm.file.seek(@pos+7, IO::SEEK_SET)
1181
+ nbits_pack = str2uint1( @sgm.file.read(1) )
1182
+ if (nbits_pack%8) == 0
1183
+ nstep = 8
1184
+ elsif (nbits_pack%4) == 0
1185
+ nstep = 4
1186
+ elsif (nbits_pack%2) == 0
1187
+ nstep = 2
1188
+ else
1189
+ nstep = 1
1190
+ end
1191
+ r = offset
1192
+ e = efactor
1193
+ map = @sgm.bms.map
1194
+ nmiss = map ? map.count_false : 0
1195
+ if flag4==0
1196
+ nlen = ((length-3-8)*8-nbits_unuse)/nbits_pack
1197
+ nlon,nlat = shape
1198
+ (nlon*nlat)==nlen+nmiss || raise("length is not collect")
1199
+ if arg.length!=0
1200
+ index, shape2 = arg
1201
+ index = index.collect{|el| Fixnum===el ? el..el : el }
1202
+ j = nil
1203
+ i = nil
1204
+ if map
1205
+ var = NArrayMiss.float(*shape2)
1206
+ map.reshape!(nlon,nlat)
1207
+ mask = map[*index]
1208
+ index[1].each{|j|
1209
+ jj = j-index[1].first
1210
+ sb = j*nlon+index[0].first
1211
+ sb = sb-map[true,0..jj-1].count_false if jj>0
1212
+ sb = sb*nbits_pack
1213
+ eb = sb+mask[true,j].count_true*nbits_pack
1214
+ if sb!=eb
1215
+ var[mask[true,j].where,jj] = get_value(@sgm.file,@pos+8,sb,eb,nbits_pack,nstep)
1216
+ end
1217
+ }
1218
+ else
1219
+ var = NArray.float(*shape2)
1220
+ index[1].each{|j|
1221
+ sb = (j*nlon+index[0].first)*nbits_pack
1222
+ eb = (j*nlon+index[0].end+1)*nbits_pack
1223
+ jj = j-index[1].first
1224
+ var[true,jj] = get_value(@sgm.file,@pos+8,sb,eb,nbits_pack,nstep)
1225
+ }
1226
+ end
1227
+ else
1228
+ if map
1229
+ eb = nlen*nbits_pack
1230
+ var = NArrayMiss.float(nlon,nlat)
1231
+ var[map.where] = get_value(@sgm.file,@pos+8,0,eb,nbits_pack,nstep)
1232
+ else
1233
+ eb = nlen*nbits_pack
1234
+ var = get_value(@sgm.file,@pos+8,0,eb,nbits_pack,nstep)
1235
+ var.reshape!(nlon,nlat)
1236
+ end
1237
+ end
1238
+ var = var*e+r
1239
+ return var
1240
+ else
1241
+ raise "not defined yet"
1242
+ n1 = str2uint2( @file.read(2) )
1243
+ @sgm.file.seek(1, IO::SEEK_CUR)
1244
+ n2 = str2uint2( @sgm.file.read(2) )
1245
+ p1 = str2uint2( @sgm.file.read(2) )
1246
+ p2 = str2uint2( @sgm.file.read(2) ) # @bds[15..16]
1247
+ # width = str2uint( @bds[18..??] )
1248
+ # bitmap = str2uint( @bds[??+1..n1-4] )
1249
+ end
1250
+ end
1251
+ def set_value(val)
1252
+ val = val.reshape!(val.length)
1253
+ if NArrayMiss===val
1254
+ val = val.get_array![val.get_mask!.where]
1255
+ end
1256
+ dfact = @sgm.pds.dfact
1257
+ val = val*10**dfact
1258
+ ref = val.min
1259
+ val = val-ref
1260
+ max = val.max
1261
+ nbits = 16
1262
+ e = (Math::log(max)/Math::log(2)).ceil-nbits
1263
+ val = val*2**(-e)
1264
+ if (nbits%8) == 0
1265
+ nstep = 8
1266
+ elsif (nbits%4) == 0
1267
+ nstep = 4
1268
+ elsif (nbits%2) == 0
1269
+ nstep == 2
1270
+ else
1271
+ nstep == 1
1272
+ end
1273
+ str, bu = data2str(val.to_type(NArray::INT),nstep,nbits)
1274
+ @oct4 = (@oct4&15)+bu*16
1275
+ @bds[0,1] = uint2str(@oct4,1)
1276
+ @bds[1,2] = int2str(e,2)
1277
+ s = (ref<0) ? -1 : 1
1278
+ ref = ref.abs
1279
+ a = (Math::log(ref)/Math::log(16)).ceil+64
1280
+ a<0 && raise("invalid range")
1281
+ a = 127 if a>127
1282
+ b = ref*2**24*16**(64-a)
1283
+ a = a*s
1284
+ @bds[3,4] = int2str(a,1)<<uint2str(b,3)
1285
+ @bds[7,1] = uint2str(nbits,1)
1286
+ @bds = @bds[0,8]<<str
1287
+ @sgm.is.update_total_length
1288
+ end
1289
+ def get
1290
+ uint2str(length,3)<<@bds
1291
+ end
1292
+ end # end definition of class GribBDS
1293
+ class GribES
1294
+ def initialize(sgm,str=nil)
1295
+ @sgm = sgm
1296
+ @es = str || "7777"
1297
+ end
1298
+ def length
1299
+ return 4
1300
+ end
1301
+ def grib?
1302
+ @es=="7777"
1303
+ end
1304
+ def get
1305
+ @es
1306
+ end
1307
+ end # end definition of class GribES
1308
+
1309
+ def initialize(fname,mode="r")
1310
+ case mode
1311
+ when "r","rb"
1312
+ mode = "rb"
1313
+ when "w","wb"
1314
+ mode = "wb"
1315
+ else
1316
+ raise "Unsupported file mode '#{mode}'. Use 'r' or 'w'."
1317
+ end
1318
+ @file = File.open(fname, mode)
1319
+ @vars = Hash.new
1320
+ @attr = Hash.new
1321
+ end
1322
+
1323
+ public
1324
+ =begin
1325
+ =NumRu::Grib -- a class for Grib datasets
1326
+
1327
+ ==Class Methods
1328
+ ---Grib.new(filename, mode="r")
1329
+ make a new Grib object.
1330
+
1331
+ ARGUMENTS
1332
+ * filename (String): name of the file to open
1333
+ * mode (String): IO mode. "r" (read only) or "w" (write only).
1334
+
1335
+ ---Grib.open(filename)
1336
+ open a Grib file.
1337
+
1338
+ ---Grib.create(filename)
1339
+ create a Grib file.
1340
+
1341
+ ---Grib.is_aGrib?(filename)
1342
+ return true when file is a Grib dataset
1343
+
1344
+ ==Methods
1345
+ ---close
1346
+ ---parse
1347
+ ---path
1348
+ ---var_names
1349
+ ---var( name )
1350
+ ---def_var( name )
1351
+ ---enddef
1352
+ ---write
1353
+ =end
1354
+ class << self
1355
+ def is_a_Grib?(fname)
1356
+ file = nil
1357
+ begin
1358
+ file = File.open(fname,"rb")
1359
+ is = (file.read(4) == "GRIB")
1360
+ ensure
1361
+ file.close if file
1362
+ end
1363
+ return defined?(is) && is
1364
+ end
1365
+ def open(fname)
1366
+ f = Grib.new(fname,"r")
1367
+ f.parse
1368
+ return f
1369
+ end
1370
+ def create(fname)
1371
+ Grib.new(fname,"w")
1372
+ end
1373
+ end
1374
+
1375
+ def close
1376
+ @grib_vars = nil
1377
+ @vars = nil
1378
+ @attr = nil
1379
+ @file.close
1380
+ end
1381
+ def parse
1382
+ @file.rewind
1383
+ while true
1384
+ @file.read(1)=="\000" && next
1385
+ @file.eof? && break
1386
+ @file.seek(-1, IO::SEEK_CUR)
1387
+ sgm = GribSegment.parse(@file)
1388
+ name = sgm.pds.sname
1389
+ if @vars.has_key?(name)
1390
+ @vars[name].push(sgm)
1391
+ else
1392
+ @vars[name] = [sgm]
1393
+ end
1394
+ end
1395
+ return self
1396
+ end
1397
+ def path
1398
+ @file.path
1399
+ end
1400
+ def var_names
1401
+ @vars.keys
1402
+ end
1403
+ def var(name)
1404
+ var = @vars[name]
1405
+ return nil if var.nil?
1406
+ return GribVar.parse(self,var,name)
1407
+ end
1408
+ def def_var(name)
1409
+ until @file.stat.writable?
1410
+ raise("File #{@file.path} is not writable.")
1411
+ end
1412
+ if !String===name
1413
+ raise "def_var(String)"
1414
+ end
1415
+ raise "#{name} is already defined" if @vars.has_key?(name)
1416
+ var = GribVar.new(@file,name)
1417
+ @vars[name] = var
1418
+ return var
1419
+ end
1420
+ def att_names
1421
+ @attr.keys
1422
+ end
1423
+ def att(name)
1424
+ @attr[name]
1425
+ end
1426
+ def write
1427
+ iz=0
1428
+ it=0
1429
+ izmax = 0
1430
+ vn = var_names
1431
+ @file.rewind
1432
+ while (vn.length>0)
1433
+ vn.dup.each{|name|
1434
+ var = @vars[name]
1435
+ sgm = nil
1436
+ if var.rank==2
1437
+ sgm = GribSegment.create(@file)
1438
+ val = [var.get,var.att("long_name"),var.att("units")]
1439
+ z = var.att("level")
1440
+ t = var.att("time")
1441
+ vn.delete(name)
1442
+ elsif var.rank==4
1443
+ sha = var.shape
1444
+ izmax < sha[2] && izmax = sha[2]
1445
+ if iz<sha[2]&&it<sha[3]
1446
+ sgm = GribSegment.create(@file)
1447
+ val = [var[true,true,iz,it],var.att("long_name"),var.att("units")]
1448
+ zd = var.dim(2)
1449
+ zv = zd.get
1450
+ if Array===zv
1451
+ zv = zv.collect{|a| a["value"][iz] }
1452
+ else
1453
+ zv = [zv[iz]]
1454
+ end
1455
+ z = [zd.att("long_name"), zv]
1456
+ t = var.dim(3)[it]
1457
+ elsif it==sha[3]
1458
+ vn.delete(name)
1459
+ end
1460
+ elsif !var.dim_names.include?("time")
1461
+ sha = var.shape
1462
+ izmax < sha[2] && izmax = sha[2]
1463
+ if iz<sha[2]
1464
+ sgm = GribSegment.create(@file)
1465
+ val = [var[true,true,iz],var.att("long_name"),var.att("units")]
1466
+ zd = var.dim(2)
1467
+ zv = zd.get
1468
+ if Array===zv
1469
+ zv = zv.collect{|a| a["value"][iz] }
1470
+ else
1471
+ zv = [zv[iz]]
1472
+ end
1473
+ z = [zd.att("long_name"), zv]
1474
+ t = var.att("time")
1475
+ end
1476
+ vn.delete(name) if iz==sha[2]-1
1477
+ else
1478
+ sha = var.shape
1479
+ if it<sha[2]
1480
+ sgm = GribSegment.create(@file)
1481
+ val = [var[true,true,it],var.att("long_name"),var.att("units")]
1482
+ z = var.att("level")
1483
+ t = var.dim(2)[it]
1484
+ else
1485
+ vn.delete(name)
1486
+ end
1487
+ end
1488
+ if sgm
1489
+ sgm.set_xy(var.dim(0),var.dim(1))
1490
+ sgm.set_level(z)
1491
+ sgm.set_time(t)
1492
+ sgm.set_var(*val)
1493
+ sgm.write
1494
+ end
1495
+ if iz==izmax-1
1496
+ iz = 0
1497
+ it += 1
1498
+ else
1499
+ iz += 1
1500
+ end
1501
+ }
1502
+ end
1503
+ end
1504
+ def inspect
1505
+ "Grib: #{path}"
1506
+ end
1507
+ end # end of definition of class Grib
1508
+
1509
+ =begin
1510
+ =NumRu::GribDim
1511
+
1512
+ ==Class Methods
1513
+ ---new( vat, name, length )
1514
+
1515
+ ==Methods
1516
+ ---var
1517
+ ---length
1518
+ ---name
1519
+ ---typecode
1520
+ ---get
1521
+ ---[](indices)
1522
+ ---put_att(key,val)
1523
+ ---set_att(key,val)
1524
+ ---att(key)
1525
+ ---att_names
1526
+ ---inspect
1527
+
1528
+ =end
1529
+ class GribDim
1530
+ def initialize(var,name)
1531
+ @var = var
1532
+ @name = name
1533
+ @attr = Hash.new
1534
+ end
1535
+ def var
1536
+ @var
1537
+ end
1538
+ def length
1539
+ @length
1540
+ end
1541
+ alias :total :length
1542
+ def name
1543
+ @name
1544
+ end
1545
+ def get
1546
+ @ary
1547
+ end
1548
+ def typecode
1549
+ if NArray===@ary
1550
+ @ary.typecode
1551
+ elsif Array===@ary
1552
+ @ary[0]["value"].typecode
1553
+ end
1554
+ end
1555
+ def val
1556
+ if Array===@ary
1557
+ if att("long_name")=="Hybrid level"
1558
+ return @ary[0]["value"]
1559
+ else
1560
+ return @ary[1]["value"]
1561
+ end
1562
+ else
1563
+ return @ary
1564
+ end
1565
+ end
1566
+ def [](*ind)
1567
+ return val[*ind]
1568
+ end
1569
+ def put(ary)
1570
+ @ary = ary
1571
+ @length = val.length
1572
+ return @ary
1573
+ end
1574
+ def put_att(key,val)
1575
+ @attr[key]=val
1576
+ end
1577
+ alias :set_att :put_att
1578
+ def att(key)
1579
+ @attr[key]
1580
+ end
1581
+ def att_names
1582
+ @attr.keys
1583
+ end
1584
+ def inspect
1585
+ "GribDim: #{name}"
1586
+ end
1587
+ end
1588
+
1589
+ =begin
1590
+ =NumRu::GribVar
1591
+
1592
+ ==Class Methods
1593
+ ---new( file, name, obj, dims )
1594
+
1595
+ ==Methods
1596
+ ---file
1597
+ ---name
1598
+ ---rank
1599
+ ---total
1600
+ ---set_var
1601
+ ---set_miss
1602
+ ---dim_names
1603
+ ---dim( index )
1604
+ ---ndims
1605
+ ---def_dim(name,index)
1606
+ ---put_att( key, value )
1607
+ ---set_att( key, value )
1608
+ ---att( key )
1609
+ ---att_names
1610
+ ---shape
1611
+ ---typecode
1612
+ ---get( indics )
1613
+ ---[]( indics )
1614
+ ---inspect
1615
+
1616
+ =end
1617
+ class GribVar
1618
+ include GribUtils
1619
+ class << self
1620
+ include GribUtils
1621
+ private
1622
+ def vars_same?(var1,var2)
1623
+ pds1 = var1.pds
1624
+ pds2 = var2.pds
1625
+ if pds1.center!=pds2.center
1626
+ $stderr.printf("center is not same: #{pds1.center} != #{pds2.center}\n")
1627
+ return false
1628
+ end
1629
+ if pds1.gid!=pds2.gid
1630
+ $stderr.printf("gid is not same: #{pds1.gid} != #{pds2.gid}\n")
1631
+ return false
1632
+ end
1633
+ if pds1.unit!=pds2.unit
1634
+ $stderr.printf("unit is not same: #{pds1.unit} != #{pds2.unit}\n")
1635
+ return false
1636
+ end
1637
+ zt1 = pds1.z_type
1638
+ zt2 = pds2.z_type
1639
+ if zt1 != zt2
1640
+ if zt1.nil? || zt2.nil?
1641
+ $stderr.printf("z type is not same: #{zt1 ? zt1 : "nil"} != #{zt2 ? zt2 : "nil"}\n")
1642
+ else
1643
+ $stderr.printf("z type is not same: #{zt1} != #{zt2}\n")
1644
+ return false
1645
+ end
1646
+ end
1647
+ =begin
1648
+ if pds1.time_range!=pds2.time_range
1649
+ $stderr.printf("time range is not same: #{pds1.time_range} != #{pds2.time_range}\n")
1650
+ return true
1651
+ # return false
1652
+ end
1653
+ =end
1654
+ if pds1.sub_center!=pds2.sub_center
1655
+ $stderr.printf("sub center is not same: #{pds1.sub_center} != #{pds2.sub_center}\n")
1656
+ return false
1657
+ end
1658
+ if var1.gds!=var2.gds
1659
+ $stderr.printf("gds is not same\n")
1660
+ return false
1661
+ end
1662
+ return true
1663
+ end
1664
+
1665
+ public
1666
+ def parse(file,sgms,name)
1667
+ miss = false
1668
+ sgms.each{|sgm|
1669
+ pds = sgm.pds
1670
+ if !vars_same?(sgms[0],sgm)
1671
+ raise "coordinate is not same"
1672
+ end
1673
+ miss = miss | pds.bms?
1674
+ }
1675
+ pds = sgms[0].pds
1676
+ gds = sgms[0].gds
1677
+ va = GribVar.new(file,name)
1678
+ va.set_sgms(sgms)
1679
+ va.put_att("long_name",pds.name)
1680
+ std_name = pds.standard_name
1681
+ va.put_att("standard_name",std_name) if std_name
1682
+ va.put_att("units",pds.unit) if pds.unit
1683
+ va.set_miss(miss)
1684
+ vdim = Array.new
1685
+ x,y = gds.grid
1686
+ x_sname = x["short_name"]
1687
+ d = va.def_dim(x_sname,x["ij"])
1688
+ d.put(x["value"])
1689
+ x.each{|k,v|
1690
+ if k!="value"&&k!="ij"&&k!="length"
1691
+ d.put_att(k,v)
1692
+ end
1693
+ }
1694
+ y_sname = y["short_name"]
1695
+ d = va.def_dim(y_sname,y["ij"])
1696
+ d.put(y["value"])
1697
+ y.each{|k,v|
1698
+ if k!="value"&&k!="ij"&&k!="length"
1699
+ d.put_att(k,v)
1700
+ end
1701
+ }
1702
+ if sgms.length>=1
1703
+ nz = pds.z_value.length
1704
+ if nz!=0
1705
+ z = Array.new(nz).collect{Array.new}
1706
+ n=nil
1707
+ m=nil
1708
+ sgms.each{|sgm|
1709
+ zv = sgm.pds.z_value
1710
+ nz.times{|m|
1711
+ if zv[m]
1712
+ z[m].push( zv[m]["value"] )
1713
+ else
1714
+ z[m].push(m)
1715
+ end
1716
+ }
1717
+ }
1718
+ nz.times{|m|
1719
+ z[m].uniq!
1720
+ z[m].length==z[0].length || raise("length is not same")
1721
+ }
1722
+ if z[0].length>1
1723
+ d = va.def_dim(pds.z_sname,2)
1724
+ d.put_att("long_name",pds.z_type)
1725
+ if pds.z_type=="Hybrid level"
1726
+ list_pv = gds.list_pv
1727
+ zval = pds.z_value[0]
1728
+ tmp = Array.new
1729
+ z[0].each{|n|
1730
+ tmp += [n-1,n]
1731
+ }
1732
+ tmp.uniq!
1733
+ tmp.sort!
1734
+ ap = list_pv[0...list_pv.length/2]
1735
+ b = list_pv[list_pv.length/2..-1]
1736
+ z[0] = {"value"=>NArray.to_na(z[0]),"name"=>zval["name"]}
1737
+ z[1] = {"value"=>ap[tmp], "name"=>"ap_half_lev", "long_name"=>"hybrid ap at half levels", "units"=>"Pa"}
1738
+ z[2] = {"value"=>b[tmp], "name"=>"b_half_lev", "long_name"=>"hybrid b at half levels", "units"=>"1"}
1739
+ elsif nz==1
1740
+ zval = pds.z_value[0]
1741
+ z = NArray.to_na(z[0])
1742
+ d.put_att("units",zval["units"])
1743
+ d.put_att("value_type",zval["name"])
1744
+ else
1745
+ nz.times{|mm|
1746
+ m = nz-m-1
1747
+ zval = pds.z_value[m]
1748
+ z[m+1] = {"value"=>NArray.to_na(z[m]),"name"=>zval["name"],"units"=>zval["units"]}
1749
+ }
1750
+ z[0] = {"value"=>NArray.sint(z[0].length).indgen,"name"=>"level number"}
1751
+ end
1752
+ d.put(z)
1753
+ else
1754
+ va.put_att("level", pds.z_type)
1755
+ pds.z_value.each{|zz|
1756
+ va.put_att(zz["name"].gsub(/\s/,"_"), "#{zz["value"]} #{zz["units"]}")
1757
+ }
1758
+ end
1759
+ else
1760
+ va.put_att("level", pds.z_type)
1761
+ end
1762
+ len = sgms.length
1763
+ time = Array.new(len)
1764
+ len.times{|i|
1765
+ time[i] = get_time(sgms[i].pds.date)
1766
+ }
1767
+ # sgms.each{|sgm|
1768
+ # time.push( get_time(sgm.pds.date) )
1769
+ # }
1770
+ time.uniq!
1771
+ if time.length>1
1772
+ time = NArray.to_na(time)
1773
+ d = va.def_dim("time",-1)
1774
+ d.put(time)
1775
+ d.put_att("long_name","time")
1776
+ d.put_att("units","hours since 1900-01-01 00:00:0.0")
1777
+ else
1778
+ date = pds.date
1779
+ va.put_att("time","#{date[0]} #{"%02d"%date[1][0]}:#{"%02d"%date[1][1]}:0.0")
1780
+ end
1781
+ end
1782
+ return va
1783
+ end
1784
+ end # end definition of class methods GribVar
1785
+
1786
+ def initialize(file,name)
1787
+ @file = file
1788
+ @name = name
1789
+ @attr = Hash.new
1790
+ @miss = false
1791
+ @dims = Array.new
1792
+ end
1793
+ def file
1794
+ @file
1795
+ end
1796
+ def name
1797
+ @name
1798
+ end
1799
+ def set_sgms(sgms)
1800
+ @obj = sgms
1801
+ end
1802
+ def set_miss(miss)
1803
+ @miss = miss
1804
+ end
1805
+ def rank
1806
+ dim_names.length
1807
+ end
1808
+ def total
1809
+ total = 1
1810
+ ndims.times{|i|
1811
+ total = total*dim(i).length
1812
+ }
1813
+ total
1814
+ end
1815
+ def dim_names
1816
+ @dims.collect{|d| d.name }
1817
+ end
1818
+ def dim(index)
1819
+ index = dim_names.index(index) if String===index
1820
+ return nil if index.nil?
1821
+ @dims[index]
1822
+ end
1823
+ def ndims
1824
+ @dims.length
1825
+ end
1826
+ def def_dim(name,index)
1827
+ d = GribDim.new(self,name)
1828
+ if index==-1
1829
+ @dims.push(d)
1830
+ else
1831
+ @dims[index] = d
1832
+ end
1833
+ return d
1834
+ end
1835
+ def put_att(key,val)
1836
+ @attr[key]=val
1837
+ end
1838
+ alias :set_att :put_att
1839
+ def att(key)
1840
+ @attr[key]
1841
+ end
1842
+ def att_names
1843
+ @attr.keys
1844
+ end
1845
+ def shape
1846
+ @dims.collect{|d| d.length }
1847
+ end
1848
+ def typecode
1849
+ if @obj.nil?
1850
+ nil
1851
+ elsif Array===@obj
1852
+ NArray::FLOAT
1853
+ else
1854
+ @obj.typecode
1855
+ end
1856
+ end
1857
+ def get(*indices)
1858
+ if @obj.nil?
1859
+ return nil
1860
+ elsif NArray===@obj||NArrayMiss===@obj
1861
+ return @obj[*indices]
1862
+ else
1863
+ sha = shape
1864
+ if indices.length!=0
1865
+ if indices[0] == false
1866
+ indices[0] = [true]*(sha.length-indices.length+1)
1867
+ elsif indices[-1] == false
1868
+ indices[-1] = [true]*(sha.length-indices.length+1)
1869
+ elsif indices.include?(false)
1870
+ raise "invalid indices"
1871
+ elsif sha.length!=indices.length
1872
+ raise "invalid indices"
1873
+ end
1874
+ sha.length.times{|n|
1875
+ ind = indices[n]
1876
+ if ind==true
1877
+ indices[n] = 0..sha[n]-1
1878
+ next
1879
+ elsif Fixnum===ind
1880
+ sha[n] = 1
1881
+ next
1882
+ elsif Range===ind
1883
+ f = ind.first
1884
+ e = ind.end
1885
+ e = sha[n]-1 if e==-1
1886
+ e -= 1 if ind.exclude_end?
1887
+ sha[n] = e-f+1
1888
+ indices[n] = f..e
1889
+ next
1890
+ else
1891
+ raise "invalid indices"
1892
+ end
1893
+ }
1894
+ if rank>2
1895
+ mask = NArray.byte(*shape[2..-1])
1896
+ mask[*indices[2..-1]]= 1
1897
+ first = Array.new(indices.length-2)
1898
+ first.length.times{|i|
1899
+ ind = indices[2+i]
1900
+ if Fixnum===ind
1901
+ first[i] = ind < 0 ? shape[2+i]+ind : ind
1902
+ elsif Range===ind
1903
+ first[i] = ind.first
1904
+ else
1905
+ raise "invalid indices"
1906
+ end
1907
+ }
1908
+ else
1909
+ mask = true
1910
+ end
1911
+ else
1912
+ mask = true
1913
+ end
1914
+ value = @miss ? NArrayMiss.float(*sha) : NArray.float(*sha)
1915
+ if rank==2
1916
+ vz = nil
1917
+ vt = nil
1918
+ index = []
1919
+ elsif rank==4
1920
+ vz = dim(2).val
1921
+ vt = dim(3).val
1922
+ index = Array.new(2)
1923
+ elsif !dim_names.include?("time")
1924
+ vz = dim(2).val
1925
+ vt = nil
1926
+ index = Array.new(1)
1927
+ else
1928
+ vt = dim(2).val
1929
+ vz = nil
1930
+ index = Array.new(1)
1931
+ end
1932
+ @obj.each{|sgm|
1933
+ pds = sgm.pds
1934
+ if vz
1935
+ index[0] = vz.eq(pds.z_value[0]["value"]).where[0]
1936
+ end
1937
+ if vt
1938
+ index[-1] = vt.eq(get_time(pds.date)).where[0]
1939
+ end
1940
+ next if (mask!=true && mask[*index]==0)
1941
+ bds = sgm.bds
1942
+ if indices.length==0 || (indices[0]==true&&indices[1]==true)
1943
+ val = bds.value(shape[0..1])
1944
+ else
1945
+ val = bds.value(shape[0..1],indices[0..1],sha[0..1])
1946
+ end
1947
+ d = pds.dfact
1948
+ val = val*10.0**(-d)
1949
+ if mask!=true
1950
+ index.length==first.length || raise("invalide indices")
1951
+ index.length.times{|i|
1952
+ index[i] = index[i]-first[i]
1953
+ }
1954
+ end
1955
+ value[true,true,*index] = val
1956
+ }
1957
+ sha.delete(1)
1958
+ value.reshape!(*sha)
1959
+ return value
1960
+ end
1961
+ end
1962
+ alias :[] :get
1963
+ alias :val :get
1964
+ def put(val)
1965
+ @obj = val
1966
+ end
1967
+ def inspect
1968
+ "GribVar: #{@file.path}?var=#{@name}"
1969
+ end
1970
+ end
1971
+
1972
+ end
1973
+
1974
+
1975
+ #####################################################
1976
+ if $0 == __FILE__
1977
+
1978
+ include NumRu
1979
+
1980
+ if ARGV.length>0
1981
+ infname = ARGV.shift
1982
+ else
1983
+ infname = "../../../testdata/T.jan.grib"
1984
+ end
1985
+
1986
+
1987
+ Grib.is_a_Grib?(infname) || raise("file is not a Grib dataset")
1988
+ p grib = Grib.open(infname)
1989
+
1990
+
1991
+
1992
+ print "\nVars\n"
1993
+ grib.var_names.each{|vn|
1994
+ p v = grib.var(vn)
1995
+ p v.dim_names
1996
+ v.dim_names.each{|dn| p dn; p v.dim(dn).get }
1997
+ p v.shape
1998
+ v.att_names.each{|an| print an, " => ", v.att(an), "\n" }
1999
+ puts "\n"
2000
+ }
2001
+
2002
+
2003
+
2004
+
2005
+ end