gphys 1.1.1a

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (428) hide show
  1. data/ChangeLog +1777 -0
  2. data/LICENSE.txt +34 -0
  3. data/README +33 -0
  4. data/Rakefile +57 -0
  5. data/TODO_ep_flux +6 -0
  6. data/bin/gdir_client +27 -0
  7. data/bin/gdir_server +129 -0
  8. data/bin/gpaop +146 -0
  9. data/bin/gpcat +148 -0
  10. data/bin/gpcut +102 -0
  11. data/bin/gpedit +228 -0
  12. data/bin/gplist +68 -0
  13. data/bin/gpmath +120 -0
  14. data/bin/gpmaxmin +128 -0
  15. data/bin/gpprint +60 -0
  16. data/bin/gpvect +706 -0
  17. data/bin/gpview +704 -0
  18. data/bin/grads2nc_with_gphys +61 -0
  19. data/doc/attribute.html +19 -0
  20. data/doc/attributenetcdf.html +15 -0
  21. data/doc/axis.html +376 -0
  22. data/doc/coordmapping.html +111 -0
  23. data/doc/coordtransform.html +36 -0
  24. data/doc/derivative/gphys-derivative.html +80 -0
  25. data/doc/derivative/index.html +21 -0
  26. data/doc/derivative/index.rd +14 -0
  27. data/doc/derivative/math-doc/document/document.css +30 -0
  28. data/doc/derivative/math-doc/document/document.html +57 -0
  29. data/doc/derivative/math-doc/document/images.aux +1 -0
  30. data/doc/derivative/math-doc/document/images.log +385 -0
  31. data/doc/derivative/math-doc/document/images.pl +186 -0
  32. data/doc/derivative/math-doc/document/images.tex +364 -0
  33. data/doc/derivative/math-doc/document/img1.png +0 -0
  34. data/doc/derivative/math-doc/document/img10.png +0 -0
  35. data/doc/derivative/math-doc/document/img11.png +0 -0
  36. data/doc/derivative/math-doc/document/img12.png +0 -0
  37. data/doc/derivative/math-doc/document/img13.png +0 -0
  38. data/doc/derivative/math-doc/document/img14.png +0 -0
  39. data/doc/derivative/math-doc/document/img15.png +0 -0
  40. data/doc/derivative/math-doc/document/img16.png +0 -0
  41. data/doc/derivative/math-doc/document/img17.png +0 -0
  42. data/doc/derivative/math-doc/document/img18.png +0 -0
  43. data/doc/derivative/math-doc/document/img19.png +0 -0
  44. data/doc/derivative/math-doc/document/img2.png +0 -0
  45. data/doc/derivative/math-doc/document/img20.png +0 -0
  46. data/doc/derivative/math-doc/document/img21.png +0 -0
  47. data/doc/derivative/math-doc/document/img22.png +0 -0
  48. data/doc/derivative/math-doc/document/img23.png +0 -0
  49. data/doc/derivative/math-doc/document/img24.png +0 -0
  50. data/doc/derivative/math-doc/document/img25.png +0 -0
  51. data/doc/derivative/math-doc/document/img26.png +0 -0
  52. data/doc/derivative/math-doc/document/img27.png +0 -0
  53. data/doc/derivative/math-doc/document/img28.png +0 -0
  54. data/doc/derivative/math-doc/document/img29.png +0 -0
  55. data/doc/derivative/math-doc/document/img3.png +0 -0
  56. data/doc/derivative/math-doc/document/img30.png +0 -0
  57. data/doc/derivative/math-doc/document/img4.png +0 -0
  58. data/doc/derivative/math-doc/document/img5.png +0 -0
  59. data/doc/derivative/math-doc/document/img6.png +0 -0
  60. data/doc/derivative/math-doc/document/img7.png +0 -0
  61. data/doc/derivative/math-doc/document/img8.png +0 -0
  62. data/doc/derivative/math-doc/document/img9.png +0 -0
  63. data/doc/derivative/math-doc/document/index.html +57 -0
  64. data/doc/derivative/math-doc/document/labels.pl +13 -0
  65. data/doc/derivative/math-doc/document/next.png +0 -0
  66. data/doc/derivative/math-doc/document/next_g.png +0 -0
  67. data/doc/derivative/math-doc/document/node1.html +238 -0
  68. data/doc/derivative/math-doc/document/node2.html +75 -0
  69. data/doc/derivative/math-doc/document/prev.png +0 -0
  70. data/doc/derivative/math-doc/document/prev_g.png +0 -0
  71. data/doc/derivative/math-doc/document/up.png +0 -0
  72. data/doc/derivative/math-doc/document/up_g.png +0 -0
  73. data/doc/derivative/math-doc/document.pdf +0 -0
  74. data/doc/derivative/math-doc/document.tex +158 -0
  75. data/doc/derivative/numru-derivative.html +129 -0
  76. data/doc/ep_flux/ep_flux.html +469 -0
  77. data/doc/ep_flux/ggraph_on_merdional_section.html +71 -0
  78. data/doc/ep_flux/index.html +31 -0
  79. data/doc/ep_flux/index.rd +24 -0
  80. data/doc/ep_flux/math-doc/document/WARNINGS +1 -0
  81. data/doc/ep_flux/math-doc/document/contents.png +0 -0
  82. data/doc/ep_flux/math-doc/document/crossref.png +0 -0
  83. data/doc/ep_flux/math-doc/document/document.css +30 -0
  84. data/doc/ep_flux/math-doc/document/document.html +101 -0
  85. data/doc/ep_flux/math-doc/document/images.aux +1 -0
  86. data/doc/ep_flux/math-doc/document/images.log +1375 -0
  87. data/doc/ep_flux/math-doc/document/images.pl +1328 -0
  88. data/doc/ep_flux/math-doc/document/images.tex +1471 -0
  89. data/doc/ep_flux/math-doc/document/img1.png +0 -0
  90. data/doc/ep_flux/math-doc/document/img10.png +0 -0
  91. data/doc/ep_flux/math-doc/document/img100.png +0 -0
  92. data/doc/ep_flux/math-doc/document/img101.png +0 -0
  93. data/doc/ep_flux/math-doc/document/img102.png +0 -0
  94. data/doc/ep_flux/math-doc/document/img103.png +0 -0
  95. data/doc/ep_flux/math-doc/document/img104.png +0 -0
  96. data/doc/ep_flux/math-doc/document/img105.png +0 -0
  97. data/doc/ep_flux/math-doc/document/img106.png +0 -0
  98. data/doc/ep_flux/math-doc/document/img107.png +0 -0
  99. data/doc/ep_flux/math-doc/document/img108.png +0 -0
  100. data/doc/ep_flux/math-doc/document/img109.png +0 -0
  101. data/doc/ep_flux/math-doc/document/img11.png +0 -0
  102. data/doc/ep_flux/math-doc/document/img110.png +0 -0
  103. data/doc/ep_flux/math-doc/document/img111.png +0 -0
  104. data/doc/ep_flux/math-doc/document/img112.png +0 -0
  105. data/doc/ep_flux/math-doc/document/img113.png +0 -0
  106. data/doc/ep_flux/math-doc/document/img114.png +0 -0
  107. data/doc/ep_flux/math-doc/document/img115.png +0 -0
  108. data/doc/ep_flux/math-doc/document/img116.png +0 -0
  109. data/doc/ep_flux/math-doc/document/img117.png +0 -0
  110. data/doc/ep_flux/math-doc/document/img118.png +0 -0
  111. data/doc/ep_flux/math-doc/document/img119.png +0 -0
  112. data/doc/ep_flux/math-doc/document/img12.png +0 -0
  113. data/doc/ep_flux/math-doc/document/img120.png +0 -0
  114. data/doc/ep_flux/math-doc/document/img121.png +0 -0
  115. data/doc/ep_flux/math-doc/document/img122.png +0 -0
  116. data/doc/ep_flux/math-doc/document/img123.png +0 -0
  117. data/doc/ep_flux/math-doc/document/img124.png +0 -0
  118. data/doc/ep_flux/math-doc/document/img125.png +0 -0
  119. data/doc/ep_flux/math-doc/document/img126.png +0 -0
  120. data/doc/ep_flux/math-doc/document/img127.png +0 -0
  121. data/doc/ep_flux/math-doc/document/img128.png +0 -0
  122. data/doc/ep_flux/math-doc/document/img129.png +0 -0
  123. data/doc/ep_flux/math-doc/document/img13.png +0 -0
  124. data/doc/ep_flux/math-doc/document/img130.png +0 -0
  125. data/doc/ep_flux/math-doc/document/img131.png +0 -0
  126. data/doc/ep_flux/math-doc/document/img132.png +0 -0
  127. data/doc/ep_flux/math-doc/document/img133.png +0 -0
  128. data/doc/ep_flux/math-doc/document/img134.png +0 -0
  129. data/doc/ep_flux/math-doc/document/img135.png +0 -0
  130. data/doc/ep_flux/math-doc/document/img136.png +0 -0
  131. data/doc/ep_flux/math-doc/document/img137.png +0 -0
  132. data/doc/ep_flux/math-doc/document/img138.png +0 -0
  133. data/doc/ep_flux/math-doc/document/img139.png +0 -0
  134. data/doc/ep_flux/math-doc/document/img14.png +0 -0
  135. data/doc/ep_flux/math-doc/document/img140.png +0 -0
  136. data/doc/ep_flux/math-doc/document/img141.png +0 -0
  137. data/doc/ep_flux/math-doc/document/img142.png +0 -0
  138. data/doc/ep_flux/math-doc/document/img143.png +0 -0
  139. data/doc/ep_flux/math-doc/document/img144.png +0 -0
  140. data/doc/ep_flux/math-doc/document/img145.png +0 -0
  141. data/doc/ep_flux/math-doc/document/img146.png +0 -0
  142. data/doc/ep_flux/math-doc/document/img147.png +0 -0
  143. data/doc/ep_flux/math-doc/document/img148.png +0 -0
  144. data/doc/ep_flux/math-doc/document/img149.png +0 -0
  145. data/doc/ep_flux/math-doc/document/img15.png +0 -0
  146. data/doc/ep_flux/math-doc/document/img150.png +0 -0
  147. data/doc/ep_flux/math-doc/document/img151.png +0 -0
  148. data/doc/ep_flux/math-doc/document/img152.png +0 -0
  149. data/doc/ep_flux/math-doc/document/img153.png +0 -0
  150. data/doc/ep_flux/math-doc/document/img154.png +0 -0
  151. data/doc/ep_flux/math-doc/document/img155.png +0 -0
  152. data/doc/ep_flux/math-doc/document/img156.png +0 -0
  153. data/doc/ep_flux/math-doc/document/img157.png +0 -0
  154. data/doc/ep_flux/math-doc/document/img158.png +0 -0
  155. data/doc/ep_flux/math-doc/document/img159.png +0 -0
  156. data/doc/ep_flux/math-doc/document/img16.png +0 -0
  157. data/doc/ep_flux/math-doc/document/img160.png +0 -0
  158. data/doc/ep_flux/math-doc/document/img161.png +0 -0
  159. data/doc/ep_flux/math-doc/document/img162.png +0 -0
  160. data/doc/ep_flux/math-doc/document/img163.png +0 -0
  161. data/doc/ep_flux/math-doc/document/img164.png +0 -0
  162. data/doc/ep_flux/math-doc/document/img165.png +0 -0
  163. data/doc/ep_flux/math-doc/document/img166.png +0 -0
  164. data/doc/ep_flux/math-doc/document/img167.png +0 -0
  165. data/doc/ep_flux/math-doc/document/img168.png +0 -0
  166. data/doc/ep_flux/math-doc/document/img169.png +0 -0
  167. data/doc/ep_flux/math-doc/document/img17.png +0 -0
  168. data/doc/ep_flux/math-doc/document/img170.png +0 -0
  169. data/doc/ep_flux/math-doc/document/img171.png +0 -0
  170. data/doc/ep_flux/math-doc/document/img172.png +0 -0
  171. data/doc/ep_flux/math-doc/document/img173.png +0 -0
  172. data/doc/ep_flux/math-doc/document/img174.png +0 -0
  173. data/doc/ep_flux/math-doc/document/img175.png +0 -0
  174. data/doc/ep_flux/math-doc/document/img176.png +0 -0
  175. data/doc/ep_flux/math-doc/document/img177.png +0 -0
  176. data/doc/ep_flux/math-doc/document/img178.png +0 -0
  177. data/doc/ep_flux/math-doc/document/img179.png +0 -0
  178. data/doc/ep_flux/math-doc/document/img18.png +0 -0
  179. data/doc/ep_flux/math-doc/document/img180.png +0 -0
  180. data/doc/ep_flux/math-doc/document/img181.png +0 -0
  181. data/doc/ep_flux/math-doc/document/img182.png +0 -0
  182. data/doc/ep_flux/math-doc/document/img183.png +0 -0
  183. data/doc/ep_flux/math-doc/document/img184.png +0 -0
  184. data/doc/ep_flux/math-doc/document/img185.png +0 -0
  185. data/doc/ep_flux/math-doc/document/img186.png +0 -0
  186. data/doc/ep_flux/math-doc/document/img187.png +0 -0
  187. data/doc/ep_flux/math-doc/document/img188.png +0 -0
  188. data/doc/ep_flux/math-doc/document/img189.png +0 -0
  189. data/doc/ep_flux/math-doc/document/img19.png +0 -0
  190. data/doc/ep_flux/math-doc/document/img190.png +0 -0
  191. data/doc/ep_flux/math-doc/document/img191.png +0 -0
  192. data/doc/ep_flux/math-doc/document/img192.png +0 -0
  193. data/doc/ep_flux/math-doc/document/img193.png +0 -0
  194. data/doc/ep_flux/math-doc/document/img194.png +0 -0
  195. data/doc/ep_flux/math-doc/document/img195.png +0 -0
  196. data/doc/ep_flux/math-doc/document/img196.png +0 -0
  197. data/doc/ep_flux/math-doc/document/img197.png +0 -0
  198. data/doc/ep_flux/math-doc/document/img198.png +0 -0
  199. data/doc/ep_flux/math-doc/document/img199.png +0 -0
  200. data/doc/ep_flux/math-doc/document/img2.png +0 -0
  201. data/doc/ep_flux/math-doc/document/img20.png +0 -0
  202. data/doc/ep_flux/math-doc/document/img200.png +0 -0
  203. data/doc/ep_flux/math-doc/document/img21.png +0 -0
  204. data/doc/ep_flux/math-doc/document/img22.png +0 -0
  205. data/doc/ep_flux/math-doc/document/img23.png +0 -0
  206. data/doc/ep_flux/math-doc/document/img24.png +0 -0
  207. data/doc/ep_flux/math-doc/document/img25.png +0 -0
  208. data/doc/ep_flux/math-doc/document/img26.png +0 -0
  209. data/doc/ep_flux/math-doc/document/img27.png +0 -0
  210. data/doc/ep_flux/math-doc/document/img28.png +0 -0
  211. data/doc/ep_flux/math-doc/document/img29.png +0 -0
  212. data/doc/ep_flux/math-doc/document/img3.png +0 -0
  213. data/doc/ep_flux/math-doc/document/img30.png +0 -0
  214. data/doc/ep_flux/math-doc/document/img31.png +0 -0
  215. data/doc/ep_flux/math-doc/document/img32.png +0 -0
  216. data/doc/ep_flux/math-doc/document/img33.png +0 -0
  217. data/doc/ep_flux/math-doc/document/img34.png +0 -0
  218. data/doc/ep_flux/math-doc/document/img35.png +0 -0
  219. data/doc/ep_flux/math-doc/document/img36.png +0 -0
  220. data/doc/ep_flux/math-doc/document/img37.png +0 -0
  221. data/doc/ep_flux/math-doc/document/img38.png +0 -0
  222. data/doc/ep_flux/math-doc/document/img39.png +0 -0
  223. data/doc/ep_flux/math-doc/document/img4.png +0 -0
  224. data/doc/ep_flux/math-doc/document/img40.png +0 -0
  225. data/doc/ep_flux/math-doc/document/img41.png +0 -0
  226. data/doc/ep_flux/math-doc/document/img42.png +0 -0
  227. data/doc/ep_flux/math-doc/document/img43.png +0 -0
  228. data/doc/ep_flux/math-doc/document/img44.png +0 -0
  229. data/doc/ep_flux/math-doc/document/img45.png +0 -0
  230. data/doc/ep_flux/math-doc/document/img46.png +0 -0
  231. data/doc/ep_flux/math-doc/document/img47.png +0 -0
  232. data/doc/ep_flux/math-doc/document/img48.png +0 -0
  233. data/doc/ep_flux/math-doc/document/img49.png +0 -0
  234. data/doc/ep_flux/math-doc/document/img5.png +0 -0
  235. data/doc/ep_flux/math-doc/document/img50.png +0 -0
  236. data/doc/ep_flux/math-doc/document/img51.png +0 -0
  237. data/doc/ep_flux/math-doc/document/img52.png +0 -0
  238. data/doc/ep_flux/math-doc/document/img53.png +0 -0
  239. data/doc/ep_flux/math-doc/document/img54.png +0 -0
  240. data/doc/ep_flux/math-doc/document/img55.png +0 -0
  241. data/doc/ep_flux/math-doc/document/img56.png +0 -0
  242. data/doc/ep_flux/math-doc/document/img57.png +0 -0
  243. data/doc/ep_flux/math-doc/document/img58.png +0 -0
  244. data/doc/ep_flux/math-doc/document/img59.png +0 -0
  245. data/doc/ep_flux/math-doc/document/img6.png +0 -0
  246. data/doc/ep_flux/math-doc/document/img60.png +0 -0
  247. data/doc/ep_flux/math-doc/document/img61.png +0 -0
  248. data/doc/ep_flux/math-doc/document/img62.png +0 -0
  249. data/doc/ep_flux/math-doc/document/img63.png +0 -0
  250. data/doc/ep_flux/math-doc/document/img64.png +0 -0
  251. data/doc/ep_flux/math-doc/document/img65.png +0 -0
  252. data/doc/ep_flux/math-doc/document/img66.png +0 -0
  253. data/doc/ep_flux/math-doc/document/img67.png +0 -0
  254. data/doc/ep_flux/math-doc/document/img68.png +0 -0
  255. data/doc/ep_flux/math-doc/document/img69.png +0 -0
  256. data/doc/ep_flux/math-doc/document/img7.png +0 -0
  257. data/doc/ep_flux/math-doc/document/img70.png +0 -0
  258. data/doc/ep_flux/math-doc/document/img71.png +0 -0
  259. data/doc/ep_flux/math-doc/document/img72.png +0 -0
  260. data/doc/ep_flux/math-doc/document/img73.png +0 -0
  261. data/doc/ep_flux/math-doc/document/img74.png +0 -0
  262. data/doc/ep_flux/math-doc/document/img75.png +0 -0
  263. data/doc/ep_flux/math-doc/document/img76.png +0 -0
  264. data/doc/ep_flux/math-doc/document/img77.png +0 -0
  265. data/doc/ep_flux/math-doc/document/img78.png +0 -0
  266. data/doc/ep_flux/math-doc/document/img79.png +0 -0
  267. data/doc/ep_flux/math-doc/document/img8.png +0 -0
  268. data/doc/ep_flux/math-doc/document/img80.png +0 -0
  269. data/doc/ep_flux/math-doc/document/img81.png +0 -0
  270. data/doc/ep_flux/math-doc/document/img82.png +0 -0
  271. data/doc/ep_flux/math-doc/document/img83.png +0 -0
  272. data/doc/ep_flux/math-doc/document/img84.png +0 -0
  273. data/doc/ep_flux/math-doc/document/img85.png +0 -0
  274. data/doc/ep_flux/math-doc/document/img86.png +0 -0
  275. data/doc/ep_flux/math-doc/document/img87.png +0 -0
  276. data/doc/ep_flux/math-doc/document/img88.png +0 -0
  277. data/doc/ep_flux/math-doc/document/img89.png +0 -0
  278. data/doc/ep_flux/math-doc/document/img9.png +0 -0
  279. data/doc/ep_flux/math-doc/document/img90.png +0 -0
  280. data/doc/ep_flux/math-doc/document/img91.png +0 -0
  281. data/doc/ep_flux/math-doc/document/img92.png +0 -0
  282. data/doc/ep_flux/math-doc/document/img93.png +0 -0
  283. data/doc/ep_flux/math-doc/document/img94.png +0 -0
  284. data/doc/ep_flux/math-doc/document/img95.png +0 -0
  285. data/doc/ep_flux/math-doc/document/img96.png +0 -0
  286. data/doc/ep_flux/math-doc/document/img97.png +0 -0
  287. data/doc/ep_flux/math-doc/document/img98.png +0 -0
  288. data/doc/ep_flux/math-doc/document/img99.png +0 -0
  289. data/doc/ep_flux/math-doc/document/index.html +101 -0
  290. data/doc/ep_flux/math-doc/document/internals.pl +258 -0
  291. data/doc/ep_flux/math-doc/document/labels.pl +265 -0
  292. data/doc/ep_flux/math-doc/document/next.png +0 -0
  293. data/doc/ep_flux/math-doc/document/next_g.png +0 -0
  294. data/doc/ep_flux/math-doc/document/node1.html +104 -0
  295. data/doc/ep_flux/math-doc/document/node10.html +164 -0
  296. data/doc/ep_flux/math-doc/document/node11.html +86 -0
  297. data/doc/ep_flux/math-doc/document/node12.html +166 -0
  298. data/doc/ep_flux/math-doc/document/node13.html +897 -0
  299. data/doc/ep_flux/math-doc/document/node14.html +1065 -0
  300. data/doc/ep_flux/math-doc/document/node15.html +72 -0
  301. data/doc/ep_flux/math-doc/document/node16.html +81 -0
  302. data/doc/ep_flux/math-doc/document/node2.html +82 -0
  303. data/doc/ep_flux/math-doc/document/node3.html +91 -0
  304. data/doc/ep_flux/math-doc/document/node4.html +149 -0
  305. data/doc/ep_flux/math-doc/document/node5.html +330 -0
  306. data/doc/ep_flux/math-doc/document/node6.html +99 -0
  307. data/doc/ep_flux/math-doc/document/node7.html +98 -0
  308. data/doc/ep_flux/math-doc/document/node8.html +83 -0
  309. data/doc/ep_flux/math-doc/document/node9.html +140 -0
  310. data/doc/ep_flux/math-doc/document/prev.png +0 -0
  311. data/doc/ep_flux/math-doc/document/prev_g.png +0 -0
  312. data/doc/ep_flux/math-doc/document/up.png +0 -0
  313. data/doc/ep_flux/math-doc/document/up_g.png +0 -0
  314. data/doc/ep_flux/math-doc/document.pdf +0 -0
  315. data/doc/ep_flux/math-doc/document.tex +2018 -0
  316. data/doc/gdir.html +412 -0
  317. data/doc/gdir_client.html +16 -0
  318. data/doc/gdir_connect_ftp-like.html +61 -0
  319. data/doc/gdir_server.html +45 -0
  320. data/doc/ggraph.html +1615 -0
  321. data/doc/gpcat.html +44 -0
  322. data/doc/gpcut.html +41 -0
  323. data/doc/gphys.html +532 -0
  324. data/doc/gphys_fft.html +324 -0
  325. data/doc/gphys_grads_io.html +69 -0
  326. data/doc/gphys_grib_io.html +82 -0
  327. data/doc/gphys_io.html +120 -0
  328. data/doc/gphys_io_common.html +18 -0
  329. data/doc/gphys_netcdf_io.html +283 -0
  330. data/doc/gplist.html +24 -0
  331. data/doc/gpmath.html +51 -0
  332. data/doc/gpmaxmin.html +31 -0
  333. data/doc/gpprint.html +34 -0
  334. data/doc/gpview.html +270 -0
  335. data/doc/grads2nc_with_gphys.html +21 -0
  336. data/doc/grads_gridded.html +307 -0
  337. data/doc/grib.html +144 -0
  338. data/doc/grid.html +212 -0
  339. data/doc/index.html +133 -0
  340. data/doc/index.rd +127 -0
  341. data/doc/netcdf_convention.html +136 -0
  342. data/doc/unumeric.html +176 -0
  343. data/doc/update +64 -0
  344. data/doc/varray.html +299 -0
  345. data/doc/varraycomposite.html +67 -0
  346. data/ext_coord.c +209 -0
  347. data/ext_init.c +7 -0
  348. data/extconf.rb +42 -0
  349. data/install.rb +130 -0
  350. data/interpo.c +497 -0
  351. data/lib/numru/dcl_mouse.rb +71 -0
  352. data/lib/numru/dclext_datetime_ax.rb +220 -0
  353. data/lib/numru/derivative.rb +348 -0
  354. data/lib/numru/ganalysis/covariance.rb +154 -0
  355. data/lib/numru/ganalysis/eof.rb +298 -0
  356. data/lib/numru/ganalysis/histogram.rb +252 -0
  357. data/lib/numru/ganalysis/met.rb +317 -0
  358. data/lib/numru/ganalysis/planet.rb +182 -0
  359. data/lib/numru/ganalysis.rb +7 -0
  360. data/lib/numru/gdir.rb +1038 -0
  361. data/lib/numru/gdir_connect_ftp-like.rb +149 -0
  362. data/lib/numru/ggraph.rb +5838 -0
  363. data/lib/numru/ggraph_on_merdional_section.rb +178 -0
  364. data/lib/numru/gphys/assoccoords.rb +359 -0
  365. data/lib/numru/gphys/attribute.rb +129 -0
  366. data/lib/numru/gphys/attributenetcdf.rb +80 -0
  367. data/lib/numru/gphys/axis.rb +963 -0
  368. data/lib/numru/gphys/coordmapping.rb +286 -0
  369. data/lib/numru/gphys/coordtransform.rb +209 -0
  370. data/lib/numru/gphys/derivative.rb +314 -0
  371. data/lib/numru/gphys/ep_flux.rb +868 -0
  372. data/lib/numru/gphys/gpcommon.rb +52 -0
  373. data/lib/numru/gphys/gphys.rb +1207 -0
  374. data/lib/numru/gphys/gphys_fft.rb +886 -0
  375. data/lib/numru/gphys/gphys_grads_io.rb +212 -0
  376. data/lib/numru/gphys/gphys_grib_io.rb +214 -0
  377. data/lib/numru/gphys/gphys_gtool3_io.rb +162 -0
  378. data/lib/numru/gphys/gphys_hdfeos5_io.rb +672 -0
  379. data/lib/numru/gphys/gphys_io.rb +452 -0
  380. data/lib/numru/gphys/gphys_io_common.rb +126 -0
  381. data/lib/numru/gphys/gphys_netcdf_io.rb +800 -0
  382. data/lib/numru/gphys/gphys_nusdas_io.rb +132 -0
  383. data/lib/numru/gphys/grads_gridded.rb +1638 -0
  384. data/lib/numru/gphys/grib.rb +2049 -0
  385. data/lib/numru/gphys/grib_params.rb +1465 -0
  386. data/lib/numru/gphys/grid.rb +723 -0
  387. data/lib/numru/gphys/gtool3.rb +771 -0
  388. data/lib/numru/gphys/interpolate.rb +854 -0
  389. data/lib/numru/gphys/narray_ext.rb +34 -0
  390. data/lib/numru/gphys/netcdf_convention.rb +406 -0
  391. data/lib/numru/gphys/subsetmapping.rb +332 -0
  392. data/lib/numru/gphys/unumeric.rb +522 -0
  393. data/lib/numru/gphys/varray.rb +1109 -0
  394. data/lib/numru/gphys/varraycomposite.rb +415 -0
  395. data/lib/numru/gphys/varraygrads.rb +225 -0
  396. data/lib/numru/gphys/varraygrib.rb +177 -0
  397. data/lib/numru/gphys/varraygtool3.rb +226 -0
  398. data/lib/numru/gphys/varrayhdfeos5.rb +451 -0
  399. data/lib/numru/gphys/varraynetcdf.rb +350 -0
  400. data/lib/numru/gphys/varraynusdas.rb +59 -0
  401. data/lib/numru/gphys.rb +9 -0
  402. data/lib/numru/htdir.rb +170 -0
  403. data/multibitIO.c +567 -0
  404. data/sample/cira86_to_nc.rb +122 -0
  405. data/sample/druby_cli1.rb +21 -0
  406. data/sample/druby_cli2.rb +34 -0
  407. data/sample/druby_serv1.rb +30 -0
  408. data/sample/druby_serv2.rb +64 -0
  409. data/sample/ep_flux/demo_NCEP_1.rb +48 -0
  410. data/sample/ep_flux/demo_NCEP_2.rb +57 -0
  411. data/sample/ep_flux/demo_NCEP_3.rb +81 -0
  412. data/sample/ggraph_latlon_labelling_dr002690.rb +159 -0
  413. data/sample/ggraph_mapfit-axes_dr002687.rb +131 -0
  414. data/sample/map_projection.rb +121 -0
  415. data/sample/ncep_theta_coord.rb +79 -0
  416. data/test/eof_slp.rb +28 -0
  417. data/test/mltbit.dat +0 -0
  418. data/test/test_ep_flux.rb +533 -0
  419. data/test/test_multibitIO.rb +19 -0
  420. data/testdata/T.jan.ctl +12 -0
  421. data/testdata/T.jan.dat +0 -0
  422. data/testdata/T.jan.grib +0 -0
  423. data/testdata/T.jan.nc +0 -0
  424. data/testdata/T.jan.packed.withmiss.nc +0 -0
  425. data/testdata/UV.jan.nc +0 -0
  426. data/testdata/assoc_crds.nc +0 -0
  427. data/testdata/cira86.dat +1332 -0
  428. metadata +621 -0
@@ -0,0 +1,1638 @@
1
+ =begin
2
+ = NumRu::GrADS_Gridded -- a class for GrADS gridded datasets
3
+
4
+ by T Horinouchi and R Mizuta
5
+
6
+ ==Overview
7
+
8
+ a GrADS_Gridded object corresponds to a GrADS control file,
9
+ through which the users can also access its binary data file(s).
10
+
11
+ ==Current Limitations
12
+
13
+ * option 365_day_calendar is not interpreted
14
+ * Partial support of the "template" option
15
+ (only %y2,%y4,%m1,%m2,%d1,%d2,%h1,%h2,%n2)
16
+ (Time is assumed to be increasing monotonically).
17
+
18
+ ==Class Methods
19
+
20
+ ---GrADS_Gridded.new(ctlfilename, mode="r")
21
+ same as GrADS_Gridded.open
22
+
23
+ ---GrADS_Gridded.open(ctlfilename, mode="r")
24
+ make a new GrADS_Gridded object.
25
+
26
+ ARGUMENTS
27
+ * ctlfilename (String): name of the control file to open
28
+ * mode (String): IO mode. "r" (read only) or "w" (write only).
29
+
30
+ REMARK
31
+ * You can modify the object through instance methods even if mode=="r".
32
+ In that case, the modification will not be written in the original
33
+ control file.
34
+
35
+ ---GrADS_Gridded.create(ctlfilename, noclobber=false, share=false)
36
+ make a new GrADS_Gridded object with creating a new control file
37
+
38
+ REMARK
39
+ * It is used with writing methods, but currently writing methods
40
+ does not work.
41
+
42
+ ==Methods
43
+ ---ndims
44
+ returns the number of dimensions in the file (always 4).
45
+
46
+ ---nvars
47
+ returns the number of variables in the file.
48
+
49
+ ---natts
50
+ returns the number of attributes of the variable.
51
+
52
+ ---path
53
+ returns the path of the control file.
54
+
55
+ ---put_att( attname, value )
56
+ set global attribute
57
+
58
+ ARGUMENTS
59
+ * attrname (String): name of an attribute
60
+ * value (String): value of an attribute
61
+
62
+ ---def_var(name="noname",nlev=0,option="99",description="")
63
+ define a variable
64
+
65
+ ARGUMENTS
66
+ * name (String): name of the variable
67
+ * nlev (Integer): number of vertical levels
68
+ * option (String): variable placement option
69
+ ("99": normal, "-1,30": transpose lon and lat)
70
+
71
+ ---var( varname=nil )
72
+ opens an existing variable in the file.
73
+
74
+ ARGUMENTS
75
+ * varname (String): name of the variable to open
76
+
77
+ RETURN VALUE
78
+ * a GrADSVar object.
79
+
80
+ ---vars( names=nil )
81
+ opens existing variables in the file.
82
+
83
+ ARGUMENTS
84
+ * names (Array): names(String) of the variable to open
85
+
86
+ RETURN VALUE
87
+ * Array of GrADSVar objects.
88
+ returns all variables if names==nil
89
+
90
+ ---get_att( key=nil )
91
+ returns tha value of the global attribute
92
+
93
+ ---dim_names
94
+ returns the names of all dimensions in the control file.
95
+
96
+ ---var_names
97
+ returns the names of all variables in the control file.
98
+
99
+ ---att_names
100
+ returns the names of all the global attributes.
101
+
102
+ ---to_ctl
103
+ returns the contents of the corresponding control file as a String.
104
+
105
+ REMARK
106
+ * The contents is reconstructed from the internal data of the object.
107
+ Therefore, even when the object is based on a read-only control file,
108
+ it is not necessarily the same as the original one. It is especially
109
+ true when the object was modified after it is opened.
110
+
111
+ ---get(name, z, t)
112
+ reads the binary data and returns as a NArray.
113
+
114
+ ARGUMENTS
115
+ * name (String): name of the variable to read
116
+ * z (Integer, currently): vertical level to read (0,1,2,...; starting
117
+ from 0). Currently only one vertical levels must be chosen, but in the
118
+ future, it is planned to support multiple levels.
119
+ * t (Integer, currently): time to read (0,1,2,...; starting
120
+ from 0). Currently only one time must be chosen, but in the
121
+ future, it is planned to support multiple times.
122
+
123
+ ---put(ary)
124
+ writes the NArray on the binary data file.
125
+
126
+ ARGUMENTS
127
+ * ary (NArray): data to write.
128
+
129
+ ---varnames
130
+ Returns names of the variable in the GrADS file as an Array in the order
131
+ placed.
132
+
133
+ ---dimensions
134
+ Returns info on the four dimensions.
135
+
136
+ RETURN VALUE
137
+ * an Array of 4 elements: dimension[0] for x, dimension[1] for y,
138
+ dimension[2] for z, and dimension[3] for t. Each of them is a
139
+ Hash like the following:
140
+ {:name=>"x",
141
+ :len=>132,
142
+ :flag=>"LINEAR",
143
+ :spec=>"-0.7500 1.5000",
144
+ :start=>-0.75, :increment=>1.5,
145
+ :description=>"longitude",
146
+ :units=>"degrees_east"}
147
+ Here, :len, :flag, and :spec are directly from the control file, while
148
+ others are derived properties for internal use.
149
+
150
+ WARNING
151
+ * Each elements of the return value is not a clone but is a direct
152
+ association to an internal object of the object. Therefore, to
153
+ modify it is to modify the object. That is, dimensions[0][:len]=10
154
+ would actually change the internal variable, while dimensions[0]=nil
155
+ has no effect (the former is a substitution IN a Hash, while the latter
156
+ is a substitution OF the Hash).
157
+
158
+ ---get_dim(dim)
159
+ returns positions of a dimension as an NArray.
160
+
161
+ ARGUMENTS
162
+ * dim (String): a dimension name
163
+
164
+ RETURN VALUE
165
+ * an NArray
166
+
167
+
168
+ ---title
169
+ ---title=
170
+ get/set the title
171
+
172
+ ---undef
173
+ ---undef=
174
+ get/set the undef value
175
+
176
+ ---dset
177
+ ---dset=
178
+ get/set the dset string
179
+
180
+
181
+
182
+ = GrADSVar -- a class for a variable of GrADS gridded datasets
183
+
184
+ by R Mizuta
185
+
186
+ ==Overview
187
+
188
+ a GrADSVar object corresponds to one variable in a GrADS control file.
189
+ It is intended to behave as a correspondent of a NetCDFVar object.
190
+
191
+ ==Current Limitations
192
+
193
+ * Only a part of the methods can work.
194
+ * Writing methods are not supported.
195
+
196
+ ==Class Methods
197
+
198
+ ---GrADSVar.new(file, varname)
199
+ make a new GrADSVar object.
200
+
201
+ ARGUMENTS
202
+ * file (GrADS_Gridded or String): a GrADS_Gridded object or
203
+ a name of the control file to open
204
+ * varname (String): name of the variable to open
205
+
206
+
207
+ ==Methods
208
+
209
+ ---shape_ul0
210
+ returns the shape of the variable, but the length of the unlimited
211
+ dimension is set to zero.
212
+
213
+ RETURN VALUE
214
+ * Array. [length of 0th dim, length of 1st dim,.. ]
215
+
216
+ ---shape_current
217
+ returns the current shape of the variable.
218
+
219
+ RETURN VALUE
220
+ * Array. [length of 0th dim, length of 1st dim,.. ]
221
+
222
+ ---dim_names
223
+ returns the names of all dimensions of the variable.
224
+
225
+ ---att_names
226
+ returns the names of all attributes of the variable.
227
+
228
+ ---name
229
+ returns the name of the variable.
230
+
231
+ ---ndims
232
+ returns the number of dimensions in the file (always 4).
233
+
234
+ ---rank
235
+ alias of ndims
236
+
237
+ ---vartype
238
+ returns "sfloat" in order to behave as NetCDFVar#vartype.
239
+
240
+ ---natts
241
+ returns the number of attributes of the variable.
242
+
243
+ ---file
244
+ returns the file name that controls the variable.
245
+
246
+ ---get_att( name=nil )
247
+ returns tha value of the attribute of the variable.
248
+
249
+ ---put_att( name, value )
250
+ set an attribute of the variable.
251
+
252
+ ARGUMENTS
253
+ * name (String): name of an attribute
254
+ * value (String): value of an attribute
255
+
256
+ ---get(hash=nil)
257
+ returns values of the variable.
258
+
259
+ ARGUMENTS
260
+ * hash (Hash) : Optional argument to limit the portion of the
261
+ variable to output values. If omitted, the whole variable is
262
+ subject to the output. This argument accepts a Hash whose keys
263
+ contain either "index" or a combination of "start","end", and
264
+ "stride". The value of "index" points the index of a scalar
265
+ portion of the variable. The other case is used to designate a
266
+ regularly ordered subset, where "start" and "end" specifies
267
+ bounds in each dimension and "stride" specifies intervals in
268
+ it. As in Array "start", "end", and "index" can take negative
269
+ values to specify index backward from the end. However,
270
+ "stride" has to be positive, so reversing the array must be
271
+ done afterwards if you like.
272
+
273
+ RETURN VALUE
274
+ * an NArray object
275
+
276
+ REMARK
277
+ "stride","index" is not supported yet.
278
+
279
+ ---[]
280
+ Same as GrADSVar#get but a subset is specified as in the method []
281
+ of NArray.
282
+
283
+
284
+ =end
285
+
286
+ require "date"
287
+ require "narray_miss"
288
+ require "numru/gphys/attribute"
289
+ require "numru/gphys/unumeric"
290
+ include Math
291
+
292
+ module NumRu
293
+ class GrADS_Gridded
294
+
295
+ class << self
296
+ alias open new
297
+
298
+ def create(ctlfilename,noclobber=false,share=false)
299
+ #if(noclobber)
300
+ # raise "noclobber = true is not supported."
301
+ #end
302
+ if(share)
303
+ raise "share = true is not supported."
304
+ end
305
+ #if (File.exists?(ctlfilename))
306
+ if(noclobber && File.exists?(ctlfilename))
307
+ print "#{ctlfilename} already exists.\n"
308
+ print "overwrite #{ctlfilename} (y/n)? "
309
+ ans = gets[0].chr
310
+ if ans != "y"
311
+ raise "#{ctlfilename} already exists."
312
+ end
313
+ end
314
+
315
+ # GrADS_Gridded.new(ctlfilename, "w+")
316
+ GrADS_Gridded.new(ctlfilename, "w")
317
+ end
318
+ end
319
+
320
+ def initialize(ctlfilename, mode="r")
321
+
322
+ case(mode)
323
+ when /^r/
324
+ @mode = 'rb'
325
+ when /^w/
326
+ @mode = 'wb'
327
+ else
328
+ raise ArgumentError, "Unsupported IO mode: #{mode}"
329
+ end
330
+
331
+ # @ctlfile = File.open(ctlfilename, mode)
332
+ @options = { # initialization
333
+ "yrev"=>nil,
334
+ "zrev"=>nil,
335
+ "sequential"=>nil,
336
+ "byteswapped"=>nil,
337
+ "template"=>nil,
338
+ "big_endian"=>nil,
339
+ "little_endian"=>nil,
340
+ "cray_32bit_ieee"=>nil,
341
+ "365_day_calendar"=>nil,
342
+ "pdef"=>nil,
343
+ }
344
+
345
+ case(@mode)
346
+ when('rb')
347
+ if (File.exists?(ctlfilename))
348
+ @ctlfile = File.open(ctlfilename, mode)
349
+ parse_ctl
350
+ else
351
+ raise "File #{ctlfilename} does not exist."
352
+ end
353
+ when('wb')
354
+ @ctlfile = File.open(ctlfilename, mode)
355
+
356
+ @dimensions = []
357
+ @variables = []
358
+
359
+ #<attributes>
360
+ @dset = nil
361
+ # @title = nil
362
+ @title = ""
363
+ @undef = nil
364
+ @fileheader_len = 0
365
+
366
+ #<internal control parameters>
367
+ @define_mode = true
368
+ @ctl_dumped = false
369
+ else
370
+ raise ArgumentError, "Unsupported IO mode: #{@mode}"
371
+ end
372
+ end
373
+
374
+ def close
375
+ @ctlfile.close
376
+ end
377
+
378
+ def path
379
+ @ctlfile.path
380
+ end
381
+
382
+ def ndims
383
+ 4
384
+ end
385
+
386
+ def nvars
387
+ @variables.length
388
+ end
389
+
390
+ def natts
391
+ 2
392
+ end
393
+
394
+ def put_att(key,value)
395
+ case key
396
+ when "dset"
397
+ @dset = value
398
+ when "title"
399
+ @title = value
400
+ when "undef"
401
+ @undef = value
402
+ else
403
+ if ! (value.is_a?(TrueClass) || value.is_a?(NilClass) )
404
+ raise ArgumentError, "2nd arg: not a true nor nil"
405
+ end
406
+ if (@options.has_key?(key))
407
+ @options[key] = value
408
+ else
409
+ raise "Invalid/unsupported option: "+key
410
+ end
411
+ end
412
+ end
413
+
414
+ def def_var(name="noname",nlev=0,option="99",description="")
415
+ @variables.push({:name=>name.to_s, :nlev=>nlev.to_s,
416
+ :option=>option.to_s, :description=>description.to_s})
417
+ end
418
+
419
+ def var( varname=nil )
420
+ GrADSVar.new(self,varname)
421
+ end
422
+
423
+ def vars( names=nil ) # return all if names==nil
424
+ # if names == nil
425
+ # vars = (0..nvars()-1).collect{ |varid| id2var(varid) }
426
+ # else
427
+ raise TypeError, "names is not an array" if ! names.is_a?(Array)
428
+ vars = names.collect{|name| var(name)}
429
+ raise ArgumentError, "One or more variables do not exist" if vars.include?(nil)
430
+ # end
431
+ vars
432
+ end
433
+
434
+ # def att
435
+ def get_att( key=nil )
436
+ case(key)
437
+ when("dset")
438
+ att = @dset
439
+ when("title")
440
+ att = @title
441
+ when "undef"
442
+ att = @undef
443
+ else
444
+ if (@options.has_key?(key))
445
+ att = @options[key]
446
+ else
447
+ raise "Invalid/unsupported option: "+key
448
+ end
449
+ end
450
+ att
451
+ end
452
+
453
+ # def fill=
454
+ # def each_dim
455
+ # def each_var
456
+ # def each_att
457
+
458
+ def dim_names
459
+ ary = Array.new()
460
+ @dimensions.each{|dim| ary.push(dim[:name])}
461
+ ary
462
+ end
463
+
464
+ def var_names
465
+ ary = Array.new()
466
+ @variables.each{|dim| ary.push(dim[:name])}
467
+ ary
468
+ end
469
+
470
+ def att_names
471
+ ary = ["dset","title","undef"]
472
+ ary
473
+ end
474
+
475
+ def to_ctl
476
+ if( !@dimensions[3][:spec] )
477
+ start = generate_starttime(@dimensions[3][:startdatetime])
478
+ increment = generate_timeincrement(@dimensions[3][:increment],@dimensions[3][:increment_units])
479
+ @dimensions[3][:spec] = "#{start} #{increment}"
480
+ end
481
+ @title = "<no title>" if @title==""
482
+ @undef = -999.0 if @undef==nil
483
+ return <<EOS
484
+ DSET #{if @dset[0]=="/" then @dset else "^"+@dset end}
485
+ TITLE #{@title}
486
+ UNDEF #{@undef}
487
+ OPTIONS #{op=""; @options.each{|key,val| op += key+" " if(val)}; op}
488
+ XDEF #{@dimensions[0][:len]} #{@dimensions[0][:flag]} #{@dimensions[0][:spec]}
489
+ YDEF #{@dimensions[1][:len]} #{@dimensions[1][:flag]} #{@dimensions[1][:spec]}
490
+ ZDEF #{@dimensions[2][:len]} #{@dimensions[2][:flag]} #{@dimensions[2][:spec]}
491
+ TDEF #{@dimensions[3][:len]} #{@dimensions[3][:flag]} #{@dimensions[3][:spec]}
492
+ VARS #{nvars}
493
+ #{@variables.collect{|i| i[:name]+" "+i[:nlev].to_s+" "+i[:option].to_s+
494
+ " "+i[:description]}.join("\n")}
495
+ ENDVARS
496
+ EOS
497
+ end
498
+
499
+ def inspect
500
+ return <<EOS
501
+ #{self.class}
502
+ file: #{@ctlfile.path}
503
+ DSET #{@dset}
504
+ OPTIONS #{@options.inspect}
505
+ XDIM #{@dimensions[0].inspect}
506
+ YDIM #{@dimensions[1].inspect}
507
+ ZDIM #{@dimensions[2].inspect}
508
+ TDIM #{@dimensions[3].inspect}
509
+ VARS
510
+ #{@variables.collect{|i| " "+i[:name]+"\t"+i[:nlev].to_s+"\t"+i[:option].to_s+
511
+ "\t"+i[:description]}.join("\n")}
512
+ ENDVARS
513
+ EOS
514
+ end
515
+
516
+ def put(ary)
517
+
518
+ if( ary.class == NArrayMiss )
519
+ raise "UNDEF is not specified" if @undef == nil
520
+ ary = ary.to_na(@undef)
521
+ end
522
+
523
+ ary = convert_endian_write(ary)
524
+
525
+ raise "DSET is not specified" if @dset == nil
526
+
527
+ putfile = File.open(@dset,"wb")
528
+ putfile << ary.to_s
529
+ putfile.close
530
+
531
+ end
532
+
533
+ def get(name, z, t, lonlat=nil)
534
+
535
+ # t: [0,1,2,..] : record number
536
+ # time: [0,1/24,2/24,...] days since 00:00Z01jan2000 : Numeric with units
537
+ # date: [00:00Z01jan2000,01:00Z01jan2000,...] : DateTime class
538
+
539
+ if ( @options["template"] )
540
+
541
+ ary_time = get_dim(@dimensions[3])
542
+ start_date = @dimensions[3][:startdatetime]
543
+
544
+ if @options["365_day_calendar"] == true
545
+ calendar = "365_day"
546
+ else
547
+ calendar = nil
548
+ end
549
+ units = Units["#{dimensions[3][:increment_units]} since #{start_date.strftime('%Y-%m-%d %H:%M:%S')}"]
550
+ target_date = (UNumeric[ary_time[t],units.to_s]).to_datetime(0.1,calendar)
551
+
552
+ # substitute DSET by the target file name
553
+ # and determine first record in the target file (="init_xxxx")
554
+
555
+ init_year = start_date.year
556
+ init_month = start_date.month
557
+ init_day = start_date.day
558
+ init_hour = start_date.hour
559
+ init_min = start_date.min
560
+
561
+ @dset_r = @dset.dup
562
+ if ( @dset_r =~ /%y[24]/ )
563
+ init_year = target_date.year
564
+ init_month = 1 if !( @dset_r =~ /%m[12]/ )
565
+ init_day = 1 if !( @dset_r =~ /%d[12]/ )
566
+ init_hour = 0 if !( @dset_r =~ /%h[12]/ )
567
+ init_min = 0 if !( @dset_r =~ /%n2/ )
568
+ @dset_r.gsub!( /%y2/, sprintf("%02d",init_year%100) )
569
+ @dset_r.gsub!( /%y4/, sprintf("%04d",init_year) )
570
+ end
571
+ if ( @dset_r =~ /%m[12]/ )
572
+ init_month = target_date.month
573
+ init_day = 1 if !( @dset_r =~ /%d[12]/ )
574
+ init_hour = 0 if !( @dset_r =~ /%h[12]/ )
575
+ init_min = 0 if !( @dset_r =~ /%n2/ )
576
+ @dset_r.gsub!( /%m1/, sprintf("%d",init_month) )
577
+ @dset_r.gsub!( /%m2/, sprintf("%02d",init_month) )
578
+ end
579
+ if ( @dset_r =~ /%d[12]/ )
580
+ init_day = target_date.day
581
+ init_hour = 0 if !( @dset_r =~ /%h[12]/ )
582
+ init_min = 0 if !( @dset_r =~ /%n2/ )
583
+ @dset_r.gsub!( /%d1/, sprintf("%d",init_day) )
584
+ @dset_r.gsub!( /%d2/, sprintf("%02d",init_day) )
585
+ end
586
+ if ( @dset_r =~ /%h[12]/ )
587
+ init_hour = target_date.hour
588
+ init_min = 0 if !( @dset_r =~ /%n2/ )
589
+ @dset_r.gsub!( /%h1/, sprintf("%d",init_hour) )
590
+ @dset_r.gsub!( /%h2/, sprintf("%02d",init_hour) )
591
+ end
592
+ if ( @dset_r =~ /%n2/ )
593
+ init_min = target_date.min
594
+ @dset_r.gsub!( /%n2/, sprintf("%02d",init_min) )
595
+ end
596
+
597
+ # find t in the first record in the target file (="init_t")
598
+ # and determine the record number in the target file
599
+
600
+ init_date = DateTime.new(init_year,init_month,init_day,init_hour,init_min)
601
+ init_time = UNumeric.from_date(init_date,units,calendar).val
602
+
603
+ init_t = t
604
+ while init_t > 0
605
+ time = ary_time[init_t-1]
606
+ break if time < init_time
607
+ init_t = init_t - 1
608
+ end
609
+
610
+ t_in_target_file = t - init_t
611
+
612
+ start_byte = start_byte(name, z, t_in_target_file)
613
+ @datafile = File.open(@dset_r,"rb")
614
+ else
615
+ start_byte = start_byte(name, z, t)
616
+ @datafile = File.open(@dset,"rb")
617
+ end
618
+
619
+ @x_len = @dimensions[0][:len]
620
+ @y_len = @dimensions[1][:len]
621
+
622
+ if(lonlat)
623
+ if !(lonlat.is_a?(Array) || lonlat.is_a?(NArray))
624
+ raise "lonlat must be given Array or NArray"
625
+ end
626
+ lon_str = lonlat[0]
627
+ lon_end = lonlat[1]
628
+ lat_str = lonlat[2]
629
+ lat_end = lonlat[3]
630
+
631
+ if( @map[name][:xytranspose] )
632
+ @datafile.pos = start_byte + @y_len*lon_str*@map[name][:byte]
633
+ readdata = @datafile.read(@y_len*(lon_end-lon_str+1)*@map[name][:byte])
634
+
635
+ if( readdata == nil )
636
+ raise "File Read Error: #{@datafile.path}, " +
637
+ "#{@x_len*(lat_end-lat_str+1)*@map[name][:byte]} bytes " +
638
+ "at #{@datafile.pos} bytes\n" +
639
+ "specified by #{@ctlfile.path}, #{name} ( z=#{z}, t=#{t} ) (Perhaps there is a mismatch between the control and data files)"
640
+ end
641
+
642
+ ary = NArray.to_na(readdata, @map[name][:type], @y_len, lon_end-lon_str+1)
643
+
644
+ ary = convert_endian_read(ary)
645
+ ary = ary[lat_str..lat_end,true].transpose
646
+ else
647
+ @datafile.pos = start_byte + @x_len*lat_str*@map[name][:byte]
648
+ readdata = @datafile.read(@x_len*(lat_end-lat_str+1)*@map[name][:byte])
649
+
650
+ if( readdata == nil )
651
+ raise "File Read Error: #{@datafile.path}, " +
652
+ "#{@x_len*(lat_end-lat_str+1)*@map[name][:byte]} bytes " +
653
+ "at #{@datafile.pos} bytes\n" +
654
+ "specified by #{@ctlfile.path}, #{name} ( z=#{z}, t=#{t} ) (Perhaps there is a mismatch between the control and data files)"
655
+ end
656
+
657
+ ary = NArray.to_na(readdata, @map[name][:type], @x_len, lat_end-lat_str+1)
658
+
659
+ ary = convert_endian_read(ary)
660
+ ary = ary[lon_str..lon_end,true]
661
+ end
662
+ else
663
+ @datafile.pos = start_byte
664
+ readdata = @datafile.read(@x_len*@y_len*@map[name][:byte])
665
+
666
+ if( readdata == nil )
667
+ raise "File Read Error: #{@datafile.path}, " +
668
+ "#{@x_len*(lat_end-lat_str+1)*@map[name][:byte]} bytes " +
669
+ "at #{@datafile.pos} bytes\n" +
670
+ "specified by #{@ctlfile.path}, #{name} ( z=#{z}, t=#{t} ) (Perhaps there is a mismatch between the control and data files)"
671
+ end
672
+
673
+ ary = NArray.to_na(readdata, @map[name][:type], @dimensions[0][:len],@dimensions[1][:len])
674
+
675
+ ary = convert_endian_read(ary)
676
+ ary = ary.transpose if ( @map[name][:xytranspose] )
677
+ end
678
+
679
+ @datafile.close
680
+ ary
681
+ end
682
+
683
+ attr_accessor(:title, :undef, :dset, :dimensions, :variables)
684
+ attr_reader(:ctlfile)
685
+
686
+ def get_dim(dim)
687
+ name = dim[:name]
688
+ if (dim[:levels])
689
+ var_dim = NArray.to_na(dim[:levels])
690
+ elsif (dim[:start] && dim[:increment] && dim[:len])
691
+ var_dim = NArray.float(dim[:len]).indgen!*dim[:increment]+dim[:start]
692
+ else
693
+ raise "cannot define dimension "+name
694
+ end
695
+ var_dim = var_dim[-1..0] if (name == 'y' && @options["yrev"])
696
+ var_dim = var_dim[-1..0] if (name == 'z' && @options["zrev"])
697
+ return var_dim
698
+ end
699
+
700
+ def varnames
701
+ @variables.collect{|i| i[:name]}
702
+ end
703
+
704
+ def get_alldim
705
+ ax = Hash.new
706
+ @dimensions.each{|dim|
707
+ name = dim[:name]
708
+ ax[name] = get_dim(dim)
709
+ }
710
+ return ax
711
+ end
712
+
713
+ def ctlfilename # obsolete
714
+ @ctlfile.path
715
+ end
716
+
717
+ ########## private methods #############
718
+ private
719
+
720
+ def parse_ctl
721
+ @ctlfile.rewind
722
+ @fileheader_len = 0 # defalut value
723
+ @title = ""
724
+ @variables = [] # initalization
725
+ @dimensions = [] # initalization
726
+ while ( line = @ctlfile.gets )
727
+ case(line)
728
+ when /^\s*\*/,/^\s*$/
729
+ # do nothing
730
+ when /^\s*DSET\s*(\S*)/i
731
+ if ($1)
732
+ # @dset = $1
733
+ # @dset = $1.gsub(/(\^)/,"./") # replace "^" with "./"
734
+ @dset = $1.gsub(/(^\^|^([^\/]))/,File.dirname(@ctlfile.path)+'/\2')
735
+ # relative -> absolute path (e.g. '^a' or 'a' -> '/hoge/a')
736
+ # @datafile = File.open(@dset,@mode)
737
+ else
738
+ raise "Invalid line: "+line
739
+ end
740
+ when /^\s*TITLE\s*(\S+.*)$/i
741
+ if ($1)
742
+ @title = $1
743
+ else
744
+ raise "Invalid line: "+line
745
+ end
746
+ when /^\s*UNDEF\s*(\S*)/i
747
+ if ($1)
748
+ @undef = $1.to_f
749
+ else
750
+ raise "Invalid line: "+line
751
+ end
752
+ when /^\s*FILEHEADER\s*(\S*)/i
753
+ if ($1)
754
+ @fileheader_len = $1.to_i
755
+ else
756
+ raise "Invalid line: "+line
757
+ end
758
+ when /^\s*BYTESWAPPED\s*$/i
759
+ @options["byteswapped"] = true
760
+ when /^\s*OPTIONS\s*(\S+.*)$/i
761
+ if ($1)
762
+ # $1.split.each{ |opt|
763
+ $1.downcase.split.each{ |opt|
764
+ if (@options.has_key?(opt))
765
+ @options[opt] = true
766
+ else
767
+ raise "Invalid/unsupported option: "+opt
768
+ end
769
+ }
770
+ else
771
+ raise "Invalid line: "+line
772
+ end
773
+ when /^\s*PDEF/i
774
+ /^\s*PDEF\s+(\d+)\s+(\d+)\s+(\S+)+(.*)$/i =~ line
775
+ if ( (isize=$1) && (jsize=$2) && (projection=$3) && (pdefspec=$4))
776
+ @options["pdef"] = true
777
+ else
778
+ raise "Invalid line: "+line
779
+ end
780
+ when /^\s*[XYZT]DEF/i
781
+ # /^\s*([XYZT])DEF\s+(\d+)\s+(\S+)\s+(.*)$/i =~ line
782
+ /^\s*([XYZT])DEF\s+(\d+)\s+(\S+)+(.*)$/i =~ line
783
+ if ( (len=$2) && (flag=$3) && (spec=$4))
784
+ dim = {:len=>len.to_i, :flag=>flag, :spec=>spec}
785
+ case $1
786
+ when /X/i
787
+ idim=0
788
+ dim[:name] = 'x'
789
+ dim[:description] = 'longitude'
790
+ dim[:units] = 'degrees_east'
791
+ when /Y/i
792
+ idim=1
793
+ dim[:name] = 'y'
794
+ dim[:description] = 'latitude'
795
+ dim[:units] = 'degrees_north'
796
+ when /Z/i
797
+ idim=2
798
+ dim[:name] = 'z'
799
+ dim[:description] = 'pressure level'
800
+ dim[:units] = 'hPa'
801
+ when /T/i
802
+ dim[:name] = 't'
803
+ dim[:description] = 'time'
804
+ idim=3
805
+ end
806
+ if (idim!=3)
807
+ if (dim[:flag] =~ /LINEAR/i)
808
+ begin
809
+ dim[:start],dim[:increment] = spec.split.collect!{|i| i.to_f}
810
+ rescue NameError,StandardError
811
+ raise $!.to_s+"\nCannot read start and increment from: "+spec
812
+ end
813
+ elsif (dim[:flag] =~ /LEVELS/i)
814
+ dim[:levels] = []
815
+ pos = @ctlfile.pos # back up for a one-line rewind
816
+ # dim[:spec] = "\n"
817
+ dim[:spec] += levs = spec+"\n"
818
+ if( /^\s*[\d\-\.]/ =~ levs )
819
+ dim[:levels] += levs.split.collect!{|i| i.to_f}
820
+ end
821
+ # while (dim[:spec] += levs = @ctlfile.gets)
822
+ while (levs = @ctlfile.gets)
823
+ if( /^\s*[\d\-\.]/ =~ levs )
824
+ dim[:spec] += levs
825
+ dim[:levels] += levs.split.collect!{|i| i.to_f}
826
+ #p '### levels',dim[:levels].length," ",levs.split
827
+ pos = @ctlfile.pos # back up for a one-line rewind
828
+ else
829
+ @ctlfile.pos = pos # one-line rewind (note: IO#lineno= doesn't work for this purpose)
830
+ break
831
+ end
832
+ end
833
+ else
834
+ raise "invalid or not-yet-supported dimension flag: "+dim[:flag]
835
+ end
836
+ else
837
+ # idim = 3 --- time
838
+ if (dim[:flag] =~ /LINEAR/i)
839
+ start,increment= spec.split
840
+ dim[:start] = 0.0
841
+ dim[:startdatetime] = parse_starttime(start)
842
+ dim[:increment],dim[:increment_units] = parse_timeincrement(increment)
843
+ dim[:units] = dim[:increment_units]+" since "+dim[:startdatetime].strftime("%Y-%m-%d %H:%MZ")
844
+
845
+ else
846
+ raise "invalid dimension flag(only LINEAR is available for time)"
847
+ end
848
+ end
849
+ @dimensions[idim]=dim
850
+ else
851
+ raise "Invalid line: "+line
852
+ end
853
+ when /^\s*VARS/i
854
+ total_lev_bytes=0
855
+ while ( vline = @ctlfile.gets )
856
+ case(vline)
857
+ when /^\s*\*/,/^\s*$/
858
+ # do nothing
859
+ when /^\s*ENDVARS/i
860
+ break
861
+ else
862
+ vline =~ /^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+.*?)\s*$/
863
+ # vline =~ /^\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s*(\S+.*?)\s*$/
864
+ if( !($1 && $2 && $3 && $4) )
865
+ raise "Something is wrong with this line: "+vline
866
+ end
867
+ name = $1; option = $3; description = $4; units = $5
868
+ nlev = max($2.to_i,1)
869
+ # total_levs += nlev
870
+ # case ($3)
871
+ case (option)
872
+ when /^0/,/^99/,/^-1,30/
873
+ byte=4; type="sfloat"
874
+ when /^-1,40,4/
875
+ byte=4; type="int"
876
+ when /^-1,40,2,-1/
877
+ byte=2; type="sint"
878
+ when /^-1,40,1/
879
+ byte=1; type="byte"
880
+ else
881
+ p option
882
+ raise "invalid or unsupported variable placement option: "
883
+ end
884
+ total_lev_bytes += nlev*byte
885
+ # @variables.push({:name=>$1,:nlev=>nlev,:option=>$3,
886
+ # :description=>$4})
887
+ if( ! $5 )
888
+ @variables.push({:name=>name,:nlev=>nlev,:option=>$3,:type=>type,:byte=>byte,
889
+ :description=>description})
890
+ else
891
+ @variables.push({:name=>$1,:nlev=>nlev,:option=>$3,:type=>type,:byte=>byte,
892
+ :description=>description, :units=>$5})
893
+ end
894
+ end
895
+ end
896
+
897
+ @map=Hash.new
898
+ cum_lev_bytes = 0
899
+ @variables.each{|i|
900
+ varname = i[:name]
901
+ @map[varname]={:offset=>@fileheader_len,:nlev=>i[:nlev],
902
+ :start=>cum_lev_bytes,:zstep=>i[:byte],:tstep=>total_lev_bytes,
903
+ :type=>i[:type],:byte=>i[:byte]}
904
+ if i[:option] =~ /^-1,30/
905
+ @map[varname][:xytranspose]=true
906
+ end
907
+ cum_lev_bytes += i[:nlev]*i[:byte]
908
+ }
909
+ end
910
+ end
911
+
912
+ # overwrite XDEF and YDEF by PDEF if PDEF exists
913
+ if @options["pdef"] == true
914
+
915
+ reference = true
916
+ case projection
917
+ when /lcc/i
918
+ latref,lonref,iref,jref,struelat,ntruelat,slon,dx,dy = pdefspec.split
919
+
920
+ imax, jmax = isize.to_i, jsize.to_i
921
+ dx, dy = dx.to_f, dy.to_f
922
+ bi, bj = (iref.to_i)-1, (jref.to_i)-1
923
+ by, bx = latref.to_f, lonref.to_f
924
+ sy,sx = struelat.to_f, slon.to_f
925
+ sy2, = ntruelat.to_f
926
+ unless bx.abs < 180
927
+ raise "parameter for basepoint is invalid"
928
+ end
929
+ unless dx != 0 && dy != 0
930
+ raise "parameter for distance is invalid"
931
+ end
932
+ unless sx.abs < 180
933
+ raise "parameter for standard is invalid"
934
+ end
935
+ unless 0 < sy.abs && sy.abs < sy2.abs && sy2.abs < 90 && sy*sy2>0
936
+ raise "parameter for standard is invalid"
937
+ end
938
+ bx = bx*PI/180
939
+ by = by*PI/180
940
+ sx = sx*PI/180
941
+ sy = sy*PI/180
942
+ sy2 = sy2*PI/180
943
+ xi = NArray.sfloat(imax).indgen(1) - bi
944
+ yj = NArray.sfloat(jmax).indgen(1) - bj
945
+ x = xi*dx
946
+ #y = -yj*dy
947
+ y = yj*dy
948
+ tansy = tan(PI/4+sy/2)
949
+ if sy == sy2
950
+ n = sin(sy)
951
+ else
952
+ tansy2 = tan(PI/4+sy2/2)
953
+ n = -log(cos(sy)/cos(sy2))/log(tansy/tansy2)
954
+ end
955
+ #f = R*cos(sy)*tansy**n/n
956
+ f = (2.0e7/PI)*cos(sy)*tansy**n/n
957
+ #r0 = f/tansy**n
958
+ tansy0 = tan(PI/4+by/2)
959
+ r0 = f/tansy0**n
960
+ if reference
961
+ lon = NMath::asin(sin(n*(bx-sx)) + x/r0)/n + sx
962
+ r = r0 - y/cos(n*(bx-sx))
963
+ r = r.abs
964
+ else
965
+ rsin = r0*sin(n*(bx-sx)) + x
966
+ rcos = r0*cos(n*(bx-sx)) - y
967
+ rcos.reshape!(1,jmax)
968
+ lon = NMath::atan(rsin/rcos)/n + sx
969
+ r = NMath::sqrt(rsin**2+rcos**2)
970
+ end
971
+ r = -r if n < 0
972
+ lat = NMath::atan((f/r)**(1.0/n))*2 - PI/2
973
+ lon = lon*180/PI
974
+ lat = lat*180/PI
975
+ else
976
+ warn "sorry, projection of '#{projection}' is not suported"
977
+ lon = NArray.sfloat(isize.to_i).indgen(1)
978
+ lat = NArray.sfloat(jsize.to_i).indgen(1)
979
+ end
980
+ p lon, lat
981
+
982
+ dim = {:len=>isize.to_i, :flag=>"levels"}
983
+ dim[:name] = 'x'
984
+ dim[:description] = 'longitude'
985
+ dim[:units] = 'degrees_east'
986
+ dim[:levels] = lon.to_a
987
+ @dimensions[0] = dim
988
+
989
+ dim = {:len=>jsize.to_i, :flag=>"levels"}
990
+ dim[:name] = 'y'
991
+ dim[:description] = 'latitude'
992
+ dim[:units] = 'degrees_north'
993
+ dim[:levels] = lat.to_a
994
+ @dimensions[1] = dim
995
+
996
+ end
997
+
998
+ #<check whether all the mandatory specifications are done>
999
+ for i in 0..3
1000
+ raise "#{i}-th dimension is not found " if( ! @dimensions[i] )
1001
+ end
1002
+ raise "UNDEF field is not found" if(!@undef)
1003
+ raise "DSET field is not found" if(!@dset)
1004
+ raise "VARS field is not found" if(!@variables)
1005
+
1006
+ # #<post processing>
1007
+ # @xybytes = 4 * @dimensions[0][:len] * @dimensions[1][:len]
1008
+ # @xy = @dimensions[0][:len] * @dimensions[1][:len]
1009
+
1010
+ end
1011
+
1012
+ def start_byte(name, level, time)
1013
+ # offset to read an xy section of the variable with NAME
1014
+ # at LEVEL(counted from 0) at TIME(conted from 0)
1015
+ if (map = @map[name] )
1016
+ if (level<0 || level>=map[:nlev])
1017
+ raise "Level #{level} is out of the range of the variable #{name}"
1018
+ end
1019
+ if (time<0 || time>=@dimensions[3][:len])
1020
+ raise "Time #{time} is not in the data period"
1021
+ end
1022
+ iblock = map[:start]+level*map[:zstep]+time*map[:tstep]
1023
+ str_byte = map[:offset] + @dimensions[0][:len] * @dimensions[1][:len] * iblock
1024
+ if( @options["sequential"] )
1025
+ str_byte += iblock*2 + 4
1026
+ end
1027
+ else
1028
+ raise "Variable does not exist: "+name
1029
+ end
1030
+ str_byte
1031
+ end
1032
+
1033
+ def parse_starttime(string)
1034
+ ## interpret the hh:mmZddmmmyyyy format for grads
1035
+
1036
+ if (/([\d:]*)Z(.*)/i =~ string)
1037
+ stime = $1
1038
+ sdate = $2
1039
+ else
1040
+ # must be date, not time, since month and year are mandatory
1041
+ sdate = string
1042
+ stime = ''
1043
+ end
1044
+
1045
+ if ( /(\d\d):(\d\d)/ =~ stime )
1046
+ begin
1047
+ shour = $1
1048
+ smin = $2
1049
+ hour = shour.to_i
1050
+ min = smin.to_i
1051
+ rescue StandardError,NameError
1052
+ raise "Cannot convert hour or time into interger: "+stime
1053
+ end
1054
+ elsif ( /\d\d/ =~ stime )
1055
+ begin
1056
+ shour = stime
1057
+ hour = shour.to_i
1058
+ min = 0
1059
+ rescue StandardError,NameError
1060
+ raise "Cannot convert hour or time into interger: "+stime
1061
+ end
1062
+ else
1063
+ hour = 0
1064
+ min = 0
1065
+ end
1066
+
1067
+ if ( /(\d*)(\w\w\w)(\d\d\d\d)/ =~ sdate )
1068
+ sday = $1
1069
+ smon = $2
1070
+ syear = $3
1071
+ begin
1072
+ if(sday == "")
1073
+ day = 1
1074
+ else
1075
+ day = sday.to_i
1076
+ end
1077
+ year = syear.to_i
1078
+ mon=['jan','feb','mar','apr','may','jun','jul','aug','sep',
1079
+ 'oct','nov','dec'].index(smon.downcase) + 1
1080
+ rescue StandardError, NameError
1081
+ raise "Could not parse the date string: "+sdate+"\n"+$!
1082
+ end
1083
+ else
1084
+ raise "The date part must be [dd]mmmyyyy, but what was given is: "+sdate
1085
+ end
1086
+
1087
+ return DateTime.new(year,mon,day,hour,min)
1088
+ end
1089
+
1090
+ def parse_timeincrement(string)
1091
+ if ( /(\d+)(\w\w)/ =~ string )
1092
+ sincrement = $1.to_i
1093
+ sunits = $2
1094
+ case sunits
1095
+ when /mn/i
1096
+ # fact = 1.0/1440.0 # factor to convert into days
1097
+ # units = 'days'
1098
+ fact = 1.0
1099
+ units = 'minutes'
1100
+ increment = sincrement * fact
1101
+ when /hr/i
1102
+ # fact = 1.0/24.0
1103
+ # units = 'days'
1104
+ fact = 1.0
1105
+ units = 'hours'
1106
+ increment = sincrement * fact
1107
+ when /dy/i
1108
+ fact = 1.0
1109
+ units = 'days'
1110
+ increment = sincrement * fact
1111
+ when /mo/i
1112
+ fact = 1.0
1113
+ units = 'months'
1114
+ increment = sincrement * fact
1115
+ when /yr/i
1116
+ fact = 1.0
1117
+ units = 'years'
1118
+ increment = sincrement * fact
1119
+ else
1120
+ raise "invalid units: "+sunits
1121
+ end
1122
+ else
1123
+ raise "invalid time-increment string: #{sunits}"
1124
+ end
1125
+ return [increment, units]
1126
+ end
1127
+
1128
+ def max(a,b)
1129
+ a>b ? a : b
1130
+ end
1131
+
1132
+ def generate_starttime(datetime)
1133
+ mon = Date::ABBR_MONTHNAMES[datetime.mon]
1134
+ return datetime.strftime("%H:%MZ%d#{mon}%Y")
1135
+ end
1136
+
1137
+ def generate_timeincrement(increment,units)
1138
+ increment = increment[0] if(increment.class==NArray)
1139
+ sincrement = increment
1140
+ case units
1141
+ when /min/i
1142
+ sunits = "mn"
1143
+ when /hour/i
1144
+ sunits = "hr"
1145
+ when /day/i
1146
+ sunits = "dy"
1147
+ when /mon/i
1148
+ sunits = "mo"
1149
+ when /year/i
1150
+ sunits = "yr"
1151
+ else
1152
+ raise "invalid time increment units: #{units}"
1153
+ end
1154
+
1155
+ if(sunits == "dy")
1156
+ if( increment < 0.0 )
1157
+ raise "invalid time increment: #{increment}"
1158
+ elsif( increment >= 365 && (increment.to_f/365) / (increment.to_i/365) < 1.003 )
1159
+ sincrement = (increment/365).to_i
1160
+ sunits = "yr"
1161
+ elsif( increment >= 28 && (increment.to_f/28) / (increment.to_i/28) < 1.11 )
1162
+ sincrement = (increment/28).to_i
1163
+ sunits = "mo"
1164
+ elsif( increment < 1.0 )
1165
+ if( increment >= 0.0416 && (increment*1440)%60 < 5 )
1166
+ sincrement = (increment*24).to_i
1167
+ sunits = "hr"
1168
+ else
1169
+ sincrement = increment*1440
1170
+ sunits = "mn"
1171
+ end
1172
+ end
1173
+ end
1174
+
1175
+ return sprintf("%2d",sincrement)+sunits
1176
+ end
1177
+
1178
+ def convert_endian_read(ary)
1179
+
1180
+ if( (@options["big_endian"] || @options["cray_32bit_ieee"]) &&
1181
+ @options["little_endian"] )
1182
+ raise "endian specification error"
1183
+ end
1184
+
1185
+ if( @options["big_endian"] || @options["cray_32bit_ieee"] )
1186
+ ary = ary.ntoh
1187
+ elsif( @options["little_endian"] )
1188
+ ary = ary.vtoh
1189
+ elsif( @options["byteswapped"] )
1190
+ ary = ary.swap_byte
1191
+ end
1192
+
1193
+ ary
1194
+ end
1195
+
1196
+ def convert_endian_write(ary)
1197
+
1198
+ if( (@options["big_endian"] || @options["cray_32bit_ieee"]) &&
1199
+ @options["little_endian"] )
1200
+ raise "endian specification error"
1201
+ end
1202
+
1203
+ if( @options["big_endian"] || @options["cray_32bit_ieee"] )
1204
+ ary = ary.hton
1205
+ elsif( @options["little_endian"] )
1206
+ ary = ary.htov
1207
+ elsif( @options["byteswapped"] )
1208
+ ary = ary.swap_byte
1209
+ end
1210
+
1211
+ ary
1212
+ end
1213
+
1214
+ end
1215
+
1216
+ class GrADSVar
1217
+
1218
+ def initialize(file,varname)
1219
+ @varname = varname
1220
+
1221
+ if file.is_a?(String)
1222
+ file = GrADS_Gridded.open(file)
1223
+ elsif ! file.is_a?(GrADS_Gridded)
1224
+ raise ArgumentError, "1st arg must be a GrADS_Gridded or a file name"
1225
+ end
1226
+ @ctl = file # control file name
1227
+ # @ctl = ctl
1228
+
1229
+ @idim = -1
1230
+ for i in 0...@ctl.dimensions.length
1231
+ # p @ctl.dimensions[i][:name]
1232
+ if @varname == @ctl.dimensions[i][:name]
1233
+ @idim = i
1234
+ end
1235
+ end
1236
+
1237
+ @attr = NumRu::Attribute.new
1238
+ if( @idim != -1 )
1239
+ @dimensions = [ @ctl.dimensions[@idim] ]
1240
+ @rank = 1
1241
+ @attr[:name] = @dimensions[0][:name]
1242
+ @attr[:long_name] = @dimensions[0][:description]
1243
+ @attr[:units] = @dimensions[0][:units]
1244
+ if @attr[:long_name] == "time" && @ctl.get_att("365_day_calendar") == true
1245
+ @attr[:calendar] = "365_day"
1246
+ end
1247
+
1248
+ @shape = [@dimensions[0][:len]]
1249
+ else
1250
+ @dimensions = @ctl.dimensions
1251
+ @rank = @dimensions.length
1252
+ found = false
1253
+ for i in 0...@ctl.variables.length
1254
+ if @varname == @ctl.variables[i][:name]
1255
+ @attr[:long_name] = @ctl.variables[i][:description]
1256
+ @attr[:nlev] = @ctl.variables[i][:nlev].to_s
1257
+
1258
+ @shape = [@dimensions[0][:len],@dimensions[1][:len],
1259
+ @dimensions[2][:len],@dimensions[3][:len]]
1260
+ @shape[2] = @ctl.variables[i][:nlev].to_i if( @ctl.variables[i][:nlev] )
1261
+
1262
+ @attr[:missing_value] = NArray.sfloat(1).fill!(@ctl.undef)
1263
+ found = true
1264
+ end
1265
+ end
1266
+ raise "variable #{@varname} is not found" if !found
1267
+ end
1268
+ end
1269
+
1270
+ attr_accessor (:rank)
1271
+ alias :ndims :rank
1272
+
1273
+ # def dim(name)
1274
+ # def dims(names)
1275
+
1276
+ def dim_names
1277
+ ary = Array.new()
1278
+ @dimensions.each{|dim| ary.push(dim[:name])}
1279
+ ary
1280
+ end
1281
+
1282
+ def name
1283
+ @varname
1284
+ end
1285
+
1286
+ def name=
1287
+ raise "name= not supported"
1288
+ end
1289
+
1290
+ def ndims
1291
+ @rank
1292
+ end
1293
+
1294
+ def vartype
1295
+ if( @idim == -1 )
1296
+ for i in 0...@ctl.variables.length
1297
+ if @varname == @ctl.variables[i][:name]
1298
+ type = @ctl.variables[i][:type]
1299
+ end
1300
+ end
1301
+ else
1302
+ type = "float"
1303
+ end
1304
+ type
1305
+ end
1306
+ alias ntype vartype
1307
+
1308
+ def typecode
1309
+ if( @idim == -1 )
1310
+ for i in 0...@ctl.variables.length
1311
+ if @varname == @ctl.variables[i][:name]
1312
+ byte = @ctl.variables[i][:byte]
1313
+ end
1314
+ end
1315
+ else
1316
+ byte = 4
1317
+ end
1318
+ byte
1319
+ end
1320
+
1321
+ def att(name)
1322
+ raise "use get_att instead of att"
1323
+ end
1324
+
1325
+ def get_att(name)
1326
+ @attr[name]
1327
+ end
1328
+
1329
+ def natts
1330
+ @attr.length
1331
+ end
1332
+
1333
+ def att_names
1334
+ @attr.keys
1335
+ end
1336
+
1337
+ def each_att
1338
+ raise "each_att not supported"
1339
+ end
1340
+
1341
+ def put_att(name,value)
1342
+ @attr[name] = value
1343
+ end
1344
+
1345
+ def attr # obsolete
1346
+ @attr
1347
+ end
1348
+
1349
+ def file
1350
+ @ctl.ctlfile
1351
+ end
1352
+
1353
+ # def shape_ul0
1354
+ # sh = []
1355
+ # @dimensions.each{|dim|
1356
+ ## if d.unlimited? then
1357
+ ## sh.push(0)
1358
+ ## else
1359
+ # sh.push(dim[:len])
1360
+ ## end
1361
+ # }
1362
+ # sh
1363
+ # end
1364
+
1365
+ def shape_current
1366
+ # sh = []
1367
+ # @dimensions.each{|dim|
1368
+ # sh.push(dim[:len])
1369
+ # }
1370
+ # sh
1371
+ @shape
1372
+ end
1373
+
1374
+ alias shape_ul0 shape_current
1375
+
1376
+ def scaled_put(var,hash=nil)
1377
+ raise "scaled_put not supported"
1378
+ end
1379
+
1380
+ def scaled_get(hash=nil)
1381
+ raise "scaled_get not supported"
1382
+ end
1383
+
1384
+ def put(var,hash=nil)
1385
+ raise "put not supported"
1386
+ end
1387
+
1388
+ def get(hash=nil)
1389
+ if @idim != -1
1390
+ na = @ctl.get_dim(@dimensions[0])
1391
+ if hash == nil
1392
+
1393
+ elsif hash.key?("start")==true
1394
+ h_sta = hash["start"]
1395
+ endq = hash.key?("end")
1396
+ strq = hash.key?("stride")
1397
+ if endq == false && strq == false
1398
+ na = na[h_sta[0]..-1]
1399
+ elsif endq == true && strq == false
1400
+ h_end = hash["end"]
1401
+ na = na[h_sta[0]..h_end[0]]
1402
+ elsif endq == false && strq == true
1403
+ h_str = hash["stride"]
1404
+ raise "sorry, stride is not supported yet."
1405
+ else endq == true && strq == true
1406
+ h_end = hash["end"]
1407
+ h_str = hash["stride"]
1408
+ raise "sorry, stride is not supported yet."
1409
+ end
1410
+ end
1411
+ else
1412
+ h_sta = [0, 0, 0, 0]
1413
+ h_end = [-1, -1, -1, -1]
1414
+ if hash == nil
1415
+ # elsif hash.key?("index")==true
1416
+ else
1417
+ if hash.key?("start")==true
1418
+ h_sta = hash["start"]
1419
+ if hash.key?("end")==true
1420
+ h_end = hash["end"]
1421
+ end
1422
+ end
1423
+ if hash.key?("stride")==true
1424
+ raise "sorry, stride is not supported yet."
1425
+ end
1426
+ end
1427
+
1428
+ idx_x = NArray.int(@shape[0]).indgen!
1429
+ idx_y = NArray.int(@shape[1]).indgen!
1430
+ idx_z = NArray.int(@shape[2]).indgen!
1431
+ idx_t = NArray.int(@shape[3]).indgen!
1432
+ str_x = idx_x[h_sta[0]]; end_x = idx_x[h_end[0]]
1433
+ str_y = idx_y[h_sta[1]]; end_y = idx_y[h_end[1]]
1434
+ str_z = idx_z[h_sta[2]]; end_z = idx_z[h_end[2]]
1435
+ str_t = idx_t[h_sta[3]]; end_t = idx_t[h_end[3]]
1436
+
1437
+ na = NArrayMiss.new(vartype,end_x-str_x+1,end_y-str_y+1,end_z-str_z+1,end_t-str_t+1)
1438
+ for t in str_t..end_t
1439
+ for z in str_z..end_z
1440
+ na_xy = @ctl.get(@varname,z,t,[str_x,end_x,str_y,end_y])
1441
+ mask = ( na_xy.ne @ctl.undef )
1442
+ na[true,true,z-str_z,t-str_t] = NArrayMiss.to_nam(na_xy,mask)
1443
+ end
1444
+ end
1445
+ end
1446
+ na
1447
+ end
1448
+
1449
+ alias simple_put put
1450
+ alias simple_get get
1451
+
1452
+ def __rubber_expansion( args ) # copied from NetCDFVar class
1453
+ if (id = args.index(false)) # substitution into id
1454
+ # false is incuded
1455
+ alen = args.length
1456
+ if args.rindex(false) != id
1457
+ raise ArguemntError,"only one rubber dimension is permitted"
1458
+ elsif alen > rank+1
1459
+ raise ArgumentError, "too many args"
1460
+ end
1461
+ ar = ( id!=0 ? args[0..id-1] : [] )
1462
+ args = ar + [true]*(rank-alen+1) + args[id+1..-1]
1463
+ elsif args.length == 0 # to support empty [], []=
1464
+ args = [true]*rank
1465
+ end
1466
+ args
1467
+ end
1468
+ private :__rubber_expansion
1469
+
1470
+ def [](*a) # copied from NetCDFVar class
1471
+ a = __rubber_expansion(a)
1472
+ first = Array.new
1473
+ last = Array.new
1474
+ stride = Array.new
1475
+ set_stride = false
1476
+ a.each{|i|
1477
+ if(i.is_a?(Fixnum))
1478
+ first.push(i)
1479
+ last.push(i)
1480
+ stride.push(1)
1481
+ elsif(i.is_a?(Range))
1482
+ first.push(i.first)
1483
+ last.push(i.exclude_end? ? i.last-1 : i.last)
1484
+ stride.push(1)
1485
+ elsif(i.is_a?(Hash))
1486
+ r = (i.to_a[0])[0]
1487
+ s = (i.to_a[0])[1]
1488
+ if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) )
1489
+ raise TypeError, "Hash argument must be {a_Range, step}"
1490
+ end
1491
+ first.push(r.first)
1492
+ last.push(r.exclude_end? ? r.last-1 : r.last)
1493
+ stride.push(s)
1494
+ set_stride = true
1495
+ elsif(i.is_a?(TrueClass))
1496
+ first.push(0)
1497
+ last.push(-1)
1498
+ stride.push(1)
1499
+ elsif( i.is_a?(Array) || i.is_a?(NArray))
1500
+ a_new = a.dup
1501
+ at = a.index(i)
1502
+ i = NArray.to_na(i) if i.is_a?(Array)
1503
+ for n in 0..i.length-1
1504
+ a_new[at] = i[n]..i[n]
1505
+ na_tmp = self[*a_new]
1506
+ if n==0 then
1507
+ k = at
1508
+ if at > 0
1509
+ a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end}
1510
+ end
1511
+ shape_tmp = na_tmp.shape
1512
+ shape_tmp[k] = i.length
1513
+ na = na_tmp.class.new(na_tmp.typecode,*shape_tmp)
1514
+ index_tmp = Array.new(shape_tmp.length,true)
1515
+ end
1516
+ index_tmp[k] = n..n
1517
+ na[*index_tmp] = na_tmp
1518
+ end
1519
+ return na
1520
+ else
1521
+ raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray"
1522
+ end
1523
+ }
1524
+
1525
+ if(set_stride)
1526
+ na = self.get({"start"=>first, "end"=>last, "stride"=>stride})
1527
+ else
1528
+ na = self.get({"start"=>first, "end"=>last})
1529
+ end
1530
+ shape = na.shape
1531
+ (a.length-1).downto(0){ |i|
1532
+ shape.delete_at(i) if a[i].is_a?(Fixnum)
1533
+ }
1534
+ na.reshape!( *shape )
1535
+ na
1536
+ end
1537
+
1538
+ def []=(*a) # copied from NetCDFVar class
1539
+ val = a.pop
1540
+ a = __rubber_expansion(a)
1541
+ first = Array.new
1542
+ last = Array.new
1543
+ stride = Array.new
1544
+ set_stride = false
1545
+ a.each{|i|
1546
+ if(i.is_a?(Fixnum))
1547
+ first.push(i)
1548
+ last.push(i)
1549
+ stride.push(1)
1550
+ elsif(i.is_a?(Range))
1551
+ first.push(i.first)
1552
+ last.push(i.exclude_end? ? i.last-1 : i.last)
1553
+ stride.push(1)
1554
+ elsif(i.is_a?(Hash))
1555
+ r = (i.to_a[0])[0]
1556
+ s = (i.to_a[0])[1]
1557
+ if ( !( r.is_a?(Range) ) || ! ( s.is_a?(Integer) ) )
1558
+ raise ArgumentError, "Hash argument must be {first..last, step}"
1559
+ end
1560
+ first.push(r.first)
1561
+ last.push(r.exclude_end? ? r.last-1 : r.last)
1562
+ stride.push(s)
1563
+ set_stride = true
1564
+ elsif(i.is_a?(TrueClass))
1565
+ first.push(0)
1566
+ last.push(-1)
1567
+ stride.push(1)
1568
+ elsif(i.is_a?(Array) || i.is_a?(NArray))
1569
+ a_new = a.dup
1570
+ at = a.index(i)
1571
+ i = NArray.to_na(i) if i.is_a?(Array)
1572
+ val = NArray.to_na(val) if val.is_a?(Array)
1573
+ rank_of_subset = a.dup.delete_if{|v| v.is_a?(Fixnum)}.length
1574
+ if val.rank != rank_of_subset
1575
+ raise "rank of the rhs (#{val.rank}) is not equal to the rank "+
1576
+ "of the subset specified by #{a.inspect} (#{rank_of_subset})"
1577
+ end
1578
+ k = at
1579
+ a[0..at-1].each{|x| if x.is_a?(Fixnum) then k -= 1 end}
1580
+ if i.length != val.shape[k]
1581
+ raise "length of the #{k+1}-th dim of rhs is incorrect "+
1582
+ "(#{i.length} for #{val.shape[k]})"
1583
+ end
1584
+ index_tmp = Array.new(val.rank,true) if !val.is_a?(Numeric) #==>Array-like
1585
+ for n in 0..i.length-1
1586
+ a_new[at] = i[n]..i[n]
1587
+ if !val.is_a?(Numeric) then
1588
+ index_tmp[k] = n..n
1589
+ self[*a_new] = val[*index_tmp]
1590
+ else
1591
+ self[*a_new] = val
1592
+ end
1593
+ end
1594
+ return self
1595
+ else
1596
+ raise TypeError, "argument must be Fixnum, Range, Hash, TrueClass, Array, or NArray"
1597
+ end
1598
+ }
1599
+
1600
+ if(set_stride)
1601
+ self.put(val, {"start"=>first, "end"=>last, "stride"=>stride})
1602
+ else
1603
+ self.put(val, {"start"=>first, "end"=>last})
1604
+ end
1605
+ end
1606
+
1607
+ end
1608
+
1609
+ end
1610
+
1611
+ if __FILE__ == $0 then
1612
+
1613
+ include NumRu
1614
+
1615
+ begin
1616
+ gr = GrADS_Gridded.open("../../testdata/T.jan.ctl")
1617
+ rescue
1618
+ gr = GrADS_Gridded.open("../../../testdata/T.jan.ctl")
1619
+ end
1620
+ print gr.to_ctl
1621
+ p gr
1622
+ p gr.path
1623
+ p gr.var_names
1624
+ p gr.get_dim(gr.dimensions[2])
1625
+ p gr.get('T',0,0)
1626
+
1627
+ begin
1628
+ grvar = GrADSVar.new("../../testdata/T.jan.ctl","T")
1629
+ rescue
1630
+ grvar = GrADSVar.new("../../../testdata/T.jan.ctl","T")
1631
+ end
1632
+
1633
+ p grvar.dim_names
1634
+ p grvar.shape_ul0
1635
+ t = grvar[3..9,5..15,0,0]
1636
+ p t
1637
+
1638
+ end