gphys 1.1.1a

Sign up to get free protection for your applications and to get access to all the features.
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