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,886 @@
1
+ =begin
2
+ =extension of class NumRu::GPhys -- Fast Fourier transformation and its applications
3
+
4
+ This manual documents the methods of NumRu::GPhys defined in gphys_fft.rb
5
+
6
+ =class methods
7
+ ---GPhys::fft_ignore_missing( ignore=true, replace_val=nil )
8
+ Set a flag (class variable) to ignore missing values.
9
+ This is for data that do not have missing
10
+ but is treated as potentially having missing (often
11
+ by having the valid_* attributes of NetCDF.)
12
+ If replace_val is specified, data missing with replaced
13
+ with that value.
14
+
15
+
16
+ =methods
17
+ ---fft(backward=false, *dims)
18
+ Fast Fourier Transformation (FFT) by using
19
+ (((<FFTW|URL:http://www.fftw.org>))) ver 3 or ver 2.
20
+ A FFTW ver.2 interface is included in NArray, while
21
+ to use FFTW ver.3, you have to install separately.
22
+ Dimension specification by the argument dims is available
23
+ only with ver.3. By default, FFT is applied to all dimensions.
24
+
25
+ The transformation is complex. If the input data is not complex,
26
+ it will be coerced to complex before transformation.
27
+
28
+ When the FT is forward, the result is normalized
29
+ (i.e., divided by the data number), unlike the default behavior of
30
+ FFTW.
31
+
32
+ Each coordinate is assumed to be equally spaced without checking.
33
+ The new coordinate variables will be set equal to wavenumbers,
34
+ derived as 2*PI/(length of the axis)*[0,1,2,..], where the length
35
+ of the axis is derived as (coord.val.max - coord.val.min)*(n+1)/n.
36
+
37
+ REMARK
38
+ * If the units of the original coordinate is degree (or its
39
+ equivalent ones such as degrees_east), the wavenumber was
40
+ made in integers by converting the coordinate based on
41
+ radian.
42
+
43
+ ARGUMENTS
44
+ * backward (true of false) : when true, backward FT is done;
45
+ otherwise forward FT is done.
46
+ * dims (integers) : dimensions to apply FFT
47
+
48
+ RETURN VALUE
49
+ * a GPhys
50
+
51
+ EXAMPLE
52
+ gphy.fft # forward, for all dimensions
53
+ gphy.fft(true) # backward, for all dimensions
54
+ gphy.fft(nil, 0,1) # forward, for the first and second dimensions.
55
+ gphy.fft(true, -1) # backward, for the last dimension.
56
+
57
+
58
+ ---detrend(dim1[,dim2[,...]])
59
+ Remove means and linear trends along dimension(s) specified.
60
+ Algorithm: 1st order polynomial fitting.
61
+
62
+ ARGUMENTS
63
+ * dim? (Integer of String): the dimension along which you want to remove
64
+ trends.
65
+
66
+ RETURN VALUE
67
+ * a GPhys
68
+
69
+ EXAMPLE
70
+ * See ((<detrend>)).
71
+
72
+ ---cos_taper(dim1[,dim2[,...]])
73
+ Cosine tapering along dimension(s) specified.
74
+
75
+ Algorithm: to multiply with the half cosine curves at the both
76
+ 1/10 ends of the data.
77
+
78
+ cos taper shape:
79
+ _____________
80
+ _/ \_
81
+ -> <- -> <-
82
+ T/10 T/10
83
+ half-cosine half-cosine
84
+ shaped shaped
85
+
86
+ The spectra of tapered data should be multiplied by 1/0.875,
87
+ which is stored as GPhys::COS_TAPER_SP_FACTOR (==1/0.875).
88
+
89
+ ARGUMENTS
90
+ * dim? (Integer of String): the dimension along which you want to remove
91
+ trends.
92
+
93
+ RETURN VALUE
94
+ * a GPhys
95
+
96
+ EXAMPLE
97
+ dim = 0 # for the 1st dimension
98
+ fc = gphys.detrend(dim).cos_taper(dim).fft(nil,dim)
99
+ sp = fc.abs**2 * GPhys::COS_TAPER_SP_FACTOR
100
+
101
+ ---spect_zero_centering(dim)
102
+ Shifts the wavenumber axis to cover from -K/2 to K/2 instead of
103
+ from 0 to K-1, where the wavenumber is symbolically treated as integer,
104
+ which is actually not the case, though. Since the first (-K/2) and
105
+ the last (K/2) elements are duplicated, both are divided by 2.
106
+ Therefore, this method is to be used for spectra (squared quantity)
107
+ rather than the raw Fourier coefficients. (That is why the method name
108
+ is prefixed by "spect_").
109
+
110
+ The method is applied for a single dimension (specified by the argument
111
+ dim). If you need to apply for multiple dimensions, use it for multiple
112
+ times.
113
+
114
+ ARGUMENTS
115
+ * dim (integer): the dimension you want to shift spectra elements.
116
+ Count starts from zero.
117
+
118
+ RETURN VALUE
119
+ * a GPhys
120
+
121
+ EXAMPLE
122
+ * To get a spectra of a variable var along the 1st and 2nd dimensions:
123
+
124
+ fc = var.fft(nil, 0,1) # --> Fourier coef
125
+ sp = ( fc.abs**2 ).spect_zero_centering(0).spect_zero_centering(1)
126
+
127
+ Note that spect_zero_centering is applied after taking |fc|^2.
128
+
129
+ * Same but if you want to have the 2nd dimension one-sided:
130
+
131
+ fc = var.fft(nil, 0,1)
132
+ sp = ( fc.abs**2 ).spect_zero_centering(0).spect_one_sided(1)
133
+
134
+ * Similar to the first example but for cross spectra:
135
+
136
+ fc1 = var1.fft(nil, 0,1)
137
+ fc2 = var2.fft(nil, 0,1)
138
+ xsp = (fc1 * fc2.conj).spect_zero_centering(0).spect_zero_centering(1)
139
+
140
+ ---spect_one_sided(dim)
141
+ Similar to ((<spect_zero_centering>)) but to make one-sided spectra.
142
+ Namely, to convert from 0..K-1 to 0..K/2. To be applied for spectra;
143
+ wavenumber 2..K/2-1 are multiplied by 2.
144
+
145
+ ARGUMENTS
146
+ * dim (integer): the dimension you want to shift spectra elements.
147
+ Count starts from zero.
148
+
149
+ RETURN VALUE
150
+ * a GPhys
151
+
152
+ EXAMPLE
153
+ * See the 2nd example of ((<spect_zero_centering>)).
154
+
155
+ ---rawspect2powerspect(*dims)
156
+ Converts raw spectra obtained by gphys.fft.abs**2 into
157
+ power spectra by dividing by wavenumber increments
158
+ along the dimensions specified by dims.
159
+
160
+ ARGUMENTS
161
+ * dims (integers): the dimensions corresponding to wavenumbers.
162
+
163
+ RETURN VALUE
164
+ * a GPhys
165
+
166
+ EXAMPLE
167
+ * Suppose a 2 (or more) dimensional data gphys.
168
+
169
+ fc = gphys.fft(nil, 0, 1)
170
+ sp = fc.abs**2
171
+ ps = sp.rawspect2powerspect(0,1)
172
+
173
+ Here, sp is the raw spectrum of gphys, and ps is the power spectrum.
174
+ The Parseval relation for them are as follows:
175
+
176
+ (gphys**2).mean == sp.sum
177
+ == pw.sum*dk*dl (== \int pw dk dl, mathematically),
178
+
179
+ where, dk = (pw.coord(0)[1] - pw.coord(0)[0]), and
180
+ dl = (pw.coord(1)[1] - pw.coord(1)[0]).
181
+
182
+ ---phase_velocity_filter(xdim, tdim, cmin=nil, cmax=nil, xconv=nil, tconv=nil, remove_xtmean=false)
183
+
184
+ Filtering by phase velocity (between cmin and cmax)
185
+
186
+ REMARKS
187
+ * If the number of the grid points along x or t is an even number,
188
+ the maximum wavenumber or frequency is treated as positive
189
+ and negative, respectively, which results in an asymmetry of
190
+ the treatment of positive and negative phase speeds.
191
+ (That should be ok. -- In case its effect is significant,
192
+ to do the filtering itself is not meaningful.)
193
+
194
+ ARGUMENTS
195
+ * xdim (Integer or String): spacial dimension
196
+ * tdim (Integer or String): time dimension
197
+ * cmin (Float or nil): minimum phase velocity. nil means no specification.
198
+ (at least cmin or cmax must be given by Float)
199
+ * cmax (Float or nil): maximum phase velocity. nil means no specification.
200
+ (at least cmin or cmax must be given by Float)
201
+ * xconv (nil or UNumeric) : (optional) if given, xconv is multiplied
202
+ with the x axis before computing the phase velocity
203
+ (kconv=1/xconv is used to scale wavenumbers)
204
+ * tconv (nil or UNumeric) : (optional) if given, tconv is multiplied
205
+ with the t axis before computing the phase velocity
206
+ (fconv=1/tconv is used to scale frequency)
207
+ * remove_xtmean (false or true) : if false (default),
208
+ components with k=0 and f=0 are counted as c=0 (stationary),
209
+ (unlike ((<phase_velocity_binning>))), so they are included if
210
+ cmin*cmax <= 0; if true, k=0 & f=0 components are always removed.
211
+
212
+ RETURN VALUE
213
+ * a GPhys
214
+
215
+ EXAMPLE
216
+ * For a 4D data with [x,y,z,t] dimensions, filtering by the phase
217
+ velocity in the y dimension greater than 10.0 (in the unit
218
+ of y/t) can be made by
219
+
220
+ cmin = 10.0; cmax = nil
221
+ gpfilt = gp.phase_velocity_filter(1, 3, cmin, cmax)
222
+
223
+ * For a global data (on the Earth's surface) with
224
+ [lon, lat, z, time] axes, where the units of lon is
225
+ "degrees" (or "degrees_east" or "radian")
226
+ and the units of time is "hours", to filter disturbances
227
+ whose zonal phase speed MEASURED AT THE EQUATOR is less or
228
+ equal to 30 m/s can be made by
229
+
230
+ cmin = -30.0; cmax = 30.0
231
+ xconv = UNumeric[6.37e6, "m"] # Earth's radius (i.e., m/radian)
232
+ # This is a special case since "radian" is exceptionally omitted.
233
+ # See the private method __predefined_coord_units_conversion.
234
+ tconv = UNumeric[3.6e3, "s/hours"]
235
+ gpfilt = gp.phase_velocity_filter(1, 3, cmin, cmax, xconv, tconv)
236
+
237
+
238
+ ---phase_velocity_binning_iso_norml(kdim, fdim, cmin, cmax, cint, kconv=nil, fconv=nil)
239
+
240
+ Same as ((<phase_velocity_binning>)) but exclusively for
241
+ equal phase velocity spacing. Also, a normalization is
242
+ additionally made, to scale spectra in terms of integration
243
+ along phase velocity axis --- The result of
244
+ ((<phase_velocity_binning>)) called inside
245
+ this method is divided by cint along with corresponding
246
+ units conversion. Therefore, if this method is applied
247
+ to spectra, a normalization is made such that an integration
248
+ (not summation) along the phase velocity gives the variance
249
+ (or covariance etc.) -- This normalization is suitable to
250
+ quadratic quantities (such as spectra) but is not suitable to
251
+ raw Fourier coefficients.
252
+
253
+ ARGUMENTS
254
+ * kdim (Integer or String): see ((<phase_velocity_binning>))
255
+ * fdim (Integer or String): see ((<phase_velocity_binning>))
256
+ * cmin (Float) : minimum phase velocity
257
+ * cmin (Float) : maximum phase velocity
258
+ * cint (Float) : inter val with which the range [cmin and cmax]
259
+ is divided.
260
+ * kconv (nil or UNumeric) : see ((<phase_velocity_binning>))
261
+ * fconv (nil or UNumeric) : see ((<phase_velocity_binning>))
262
+
263
+ RETURN VALUE
264
+ * a GPhys
265
+
266
+ ---phase_velocity_binning(kdim, fdim, cbins, kconv=nil, fconv=nil)
267
+
268
+ Bin a 2D spectrum in space and time based on phase velocity.
269
+ The operand (self) must be Fourier coefficients or spectra,
270
+ whose grid has not been altered since the call of the method
271
+ fft (i.e., those that have not applied with zero centering
272
+ etc, since it is done in this method).
273
+
274
+ Binning by this method is based on summation, leaving
275
+ the units unchanged.
276
+
277
+ REMARKS
278
+ * Components whose phase velocities are exactly equal to one
279
+ of the boundaries are divided into the two bins half by half
280
+ * components with k=0 and f=0 are excluded -- the spatio-temporal
281
+ mean do not reflect in the result
282
+
283
+ ARGUMENTS
284
+ * kdim (Integer or String): wavenumber dimension (from spacial dimension)
285
+ * fdim (Integer or String): frequency dimension (from time dimension)
286
+ * cbins : an Array of bin bounds or a Hash of max, min, int
287
+ e.g., [-10,-1,-0.1,0.1,11,10], {"min"=>-30,"max"=>30,"int"=>5}
288
+ * kconv (nil or UNumeric) : (optional) if given, kconv is multiplied
289
+ with the wavenumber axis before computing the phase velocity
290
+ * fconv (nil or UNumeric) : (optional) if given, fconv is multiplied
291
+ with the frequency axis before computing the phase velocity
292
+
293
+ RETURN VALUE
294
+ * a GPhys
295
+
296
+ EXAMPLES
297
+ * Example A
298
+ fu = u.fft(nil, 0, 2)
299
+ cfu = fu.phase_velocity_binning(0, 2, {"min"=>-1,"max"=>1,"int"=>0.1})
300
+
301
+ * Example B
302
+ fu = u.fft(nil, 0, 2)
303
+ pw = fu.abs**2rawspect2powerspect(0,2) # power spectrum
304
+ cbins = [-100.0, -10.0, -1.0, 1.0, 10.0, 100.0] # logarithmic spacing
305
+ cpw = pw.phase_velocity_binning(0, 2, cbins)
306
+
307
+ * Example C
308
+ fu = u.fft(nil, 0, 3)
309
+ fv = v.fft(nil, 0, 3)
310
+ kconv = UNumeric[1/6.37e6, "m-1"]
311
+ fconv = UNumeric[1/3.6e3, "hours/s"]
312
+ fuv = (fu * fv.conj) # cross spectra
313
+ cfuv = fuv.phase_velocity_binning(0, 3, {"min"=>-50,"max"=>50,"int"=>5},
314
+ kconv, fconv)
315
+
316
+ =end
317
+
318
+ begin
319
+ require "numru/fftw3"
320
+ rescue LoadError
321
+ end
322
+ require "numru/gphys/gphys"
323
+
324
+ module NumRu
325
+ class GPhys
326
+ @@fft_forward = -1
327
+ @@fft_backward = 1
328
+ @@fft_ignore_missing = false
329
+ @@fft_missing_replace_val = nil
330
+
331
+ def self.fft_ignore_missing( ignore=true, replace_val=nil )
332
+ @@fft_ignore_missing = ignore
333
+ @@fft_missing_replace_val = replace_val
334
+ end
335
+
336
+
337
+ COS_TAPER_SP_FACTOR = 1.0 / 0.875 # Spectral factor for the cosine taper.
338
+ # Specta should be multiplied by this.
339
+ def cos_taper(*dims)
340
+ if dims.length < 1
341
+ raise ArgumentError,'You have to specify one or more dimensions'
342
+ end
343
+ dims.sort!.uniq!
344
+ val = self.data.val
345
+ dims.each{|dim|
346
+ dim = dim_index(dim) if dim.is_a?(String)
347
+ dim += rank if dim < 0
348
+ raise ArgumentError,"dim #{dim} does not exist" if dim<0 || dim>rank
349
+ nx = shape[dim]
350
+ wgt = NArray.float(nx).fill!(1)
351
+ x = 10.0 / nx * (NArray.float(nx).indgen!+0.5)
352
+ wskl = x.lt(1).where
353
+ wskr = x.gt(9).where
354
+ wgt[wskl] = 0.5*( 1.0 - NMath::cos(Math::PI*x[wskl]) )
355
+ wgt[wskr] = 0.5*( 1.0 - NMath::cos(Math::PI*x[wskr]) )
356
+ wgt.reshape!( *([1]*dim + [nx] + [1]*(rank-dim-1)) )
357
+ val = val*wgt
358
+ }
359
+ to_ret = self.copy
360
+ to_ret.data.val = val
361
+ to_ret
362
+ end
363
+
364
+ def detrend(*dims)
365
+ if dims.length < 1
366
+ raise ArgumentError,'You have to specify one or more dimensions'
367
+ end
368
+ dims.sort!.uniq!
369
+ val = self.data.val
370
+ dims.each{|dim|
371
+ dim = dim_index(dim) if dim.is_a?(String)
372
+ dim += rank if dim < 0
373
+ raise ArgumentError,"dim #{dim} does not exist" if dim<0 || dim>rank
374
+ if val.is_a?(NArray)
375
+ x = self.coord(dim).val
376
+ x.reshape!( *([1]*dim + [x.length] + [1]*(rank-dim-1)) )
377
+ vmean = val.mean(dim)
378
+ vxmean = (val*x).mean(dim)
379
+ xmean = x.mean(dim)
380
+ x2mean = (x*x).mean(dim)
381
+ denom = x2mean-xmean**2
382
+ if denom != 0
383
+ a = (vxmean - vmean*xmean)/denom
384
+ b = (vmean*x2mean - vxmean*xmean)/denom
385
+ else
386
+ a = 0
387
+ b = vmean
388
+ end
389
+ elsif val.is_a?(NArrayMiss)
390
+ x = self.coord(dim).val
391
+ x.reshape!( *([1]*dim + [x.length] + [1]*(rank-dim-1)) )
392
+ x = NArrayMiss.to_nam( NArray.new(x.typecode, *val.shape) + x,
393
+ val.get_mask )
394
+ vmean = val.mean(dim)
395
+ vxmean = (val*x).mean(dim)
396
+ xmean = x.mean(dim)
397
+ x2mean = (x*x).mean(dim)
398
+ denom = x2mean-xmean**2
399
+ meq0 = denom.eq(0).to_na(0) # ==0 and not masked
400
+ mne0 = denom.ne(0).to_na(0) # !=0 and not masked
401
+ denom.set_mask(mne0) # only nonzero part will be used to divide:
402
+ a = (vxmean - vmean*xmean)/denom
403
+ b = (vmean*x2mean - vxmean*xmean)/denom
404
+ a[meq0] = 0
405
+ b[meq0] = vmean[meq0]
406
+ end
407
+ a.newdim!(dim) if !a.is_a?(Numeric)
408
+ b.newdim!(dim) if !b.is_a?(Numeric)
409
+ val = val - a*x-b
410
+ }
411
+ to_ret = self.copy
412
+ to_ret.data.val = val
413
+ to_ret
414
+ end
415
+
416
+ def fft(backward=false, *dims)
417
+ fftw3 = false
418
+ if defined?(FFTW3)
419
+ fftw3 = true
420
+ elsif !defined?(FFTW)
421
+ raise "Both FFTW3 and FFTW are not installed."
422
+ end
423
+ if backward==true
424
+ dir = @@fft_backward
425
+ elsif !backward
426
+ dir = @@fft_forward
427
+ else
428
+ raise ArgumentError,"1st arg must be true or false (or, equivalenty, nil)"
429
+ end
430
+
431
+ # <FFT>
432
+
433
+ gfc = self.copy # make a deep clone
434
+ if fftw3
435
+ val = gfc.data.val
436
+ if @@fft_ignore_missing and val.is_a?(NArrayMiss)
437
+ if @@fft_missing_replace_val
438
+ val = val.to_na(@@fft_missing_replace_val)
439
+ else
440
+ val = val.to_na
441
+ end
442
+ end
443
+ fcoef = FFTW3.fft( val, dir, *dims )
444
+ else
445
+ # --> always FFT for all dimensions
446
+ if dims.length == 0
447
+ raise ArgumentError,
448
+ "dimension specification is available only if FFTW3 is installed"
449
+ end
450
+ val = gfc.data.val
451
+ if @@fft_ignore_missing and val.is_a?(NArrayMiss)
452
+ if @@fft_missing_replace_val
453
+ val = val.to_na(@@fft_missing_replace_val)
454
+ else
455
+ val = val.to_na
456
+ end
457
+ end
458
+ fcoef = FFTW.fftw( val, dir )
459
+ end
460
+ if dir == @@fft_forward
461
+ if dims.length == 0
462
+ fcoef = fcoef / fcoef.length # normalized if forward FT
463
+ else
464
+ sh = fcoef.shape
465
+ len = 1
466
+ dims.each{|d|
467
+ raise ArgumentError, "dimension out of range" if sh[d] == nil
468
+ len *= sh[d]
469
+ }
470
+ fcoef = fcoef / len
471
+ end
472
+ end
473
+ gfc.data.replace_val( fcoef )
474
+
475
+ # <coordinate variables>
476
+ for i in 0...gfc.rank
477
+ if dims.length == 0 || dims.include?(i) || dims.include?(i+rank)
478
+ __predefined_coord_units_conversion(gfc.coord(i))
479
+ cv = gfc.coord(i).val
480
+ n = cv.length
481
+ clen = (cv.max - cv.min) * n / (n-1)
482
+ wn = (2*Math::PI/clen) * NArray.new(cv.typecode,cv.length).indgen!
483
+ if (!backward)
484
+ gfc.coord(i).set_att('origin_in_real_space',cv[0..0])
485
+ else
486
+ if ( org = gfc.coord(i).get_att('origin_in_real_space') )
487
+ wn += org[0]
488
+ ###gfc.coord(i).del_att('origin_in_real_space')
489
+ end
490
+ end
491
+ gfc.coord(i).replace_val(wn)
492
+ gfc.coord(i).units = gfc.coord(i).units**(-1)
493
+ __coord_name_conversion(gfc.coord(i), backward)
494
+ end
495
+ end
496
+
497
+ # <fini>
498
+ gfc
499
+ end
500
+
501
+ def __predefined_coord_units_conversion(coord)
502
+ case coord.units
503
+ when Units["degree"]
504
+ val = coord.val
505
+ coord.replace_val( val * (Math::PI/180) )
506
+ coord.units = "radian"
507
+ end
508
+ end
509
+ private :__predefined_coord_units_conversion
510
+
511
+ def __coord_name_conversion(coord, backward)
512
+
513
+ if !backward #--> forward
514
+
515
+ ( ln = coord.get_att('long_name') ) &&
516
+ coord.set_att('long_name','wavenumber - '+ln)
517
+
518
+ case coord.name
519
+ when 'x'
520
+ coord.name = 'k'
521
+ when 'y'
522
+ coord.name = 'l'
523
+ when 'z'
524
+ coord.name = 'm'
525
+ # when 'lon','longitude'
526
+ # coord.name = 's'
527
+ when 't','time'
528
+ if coord.units === Units['s-1'] # compatible_with?
529
+ coord.name = 'omega'
530
+ coord.set_att('long_name', 'angular frequency')
531
+ end
532
+ end
533
+
534
+ else #--> backward
535
+
536
+ if ( ln = coord.get_att('long_name') )
537
+ case ln
538
+ when /^wavenumber -/
539
+ coord.set_att( 'long_name', ln.sub(/^wavenumber - */,'') )
540
+ when /angular frequency/
541
+ coord.set_att( 'long_name', 'time' )
542
+ end
543
+ end
544
+
545
+ case coord.name
546
+ when 'k'
547
+ coord.name = 'x'
548
+ when 'l'
549
+ coord.name = 'y'
550
+ when 'm'
551
+ coord.name = 'z'
552
+ when 'omega'
553
+ coord.name = 'time'
554
+ end
555
+ end
556
+ end
557
+ private :__coord_name_conversion
558
+
559
+ def spect_zero_centering(dim)
560
+ dim = dim + self.rank if dim<0
561
+ len = self.shape[dim]
562
+ b = self[ *( [true]*dim + [[(len+1)/2..len-1,0..len/2],false] ) ].copy
563
+ s1 = [true]*dim + [0, false]
564
+ s2 = [true]*dim + [-1, false]
565
+ if (len % 2) == 0 #--> even number
566
+ b[*s1] = b[*s1]/2 # the ends are duplicated --> halved
567
+ b[*s2] = b[*s1]
568
+ end
569
+ b.coord(dim)[0..len/2-1] = -b.coord(dim)[len/2+1..-1].val[-1..0]
570
+ b
571
+ end
572
+
573
+ def spect_one_sided(dim)
574
+ dim = dim + self.rank if dim<0
575
+ len = self.shape[dim]
576
+ b = self[ *([true]*dim + [0..len/2,false]) ] * 2
577
+ b[*([true]*dim + [0,false])] = b[*([true]*dim + [0,false])] / 2
578
+ if (self.shape[dim] % 2) == 0 # --> even number
579
+ b[*([true]*dim + [-1,false])] = b[*([true]*dim + [-1,false])] / 2
580
+ end
581
+ b
582
+ end
583
+
584
+ def rawspect2powerspect(*dims)
585
+ # developpers memo: Needs Units conversion.
586
+ factor = nil
587
+ dims.each{|dim|
588
+ ax = self.coord(dim)
589
+ dwn = UNumeric.new( ((ax[-1].val - ax[0].val)/(ax.length - 1)).abs,
590
+ ax.units )
591
+ if !factor
592
+ factor = dwn**(-1)
593
+ else
594
+ factor = factor / dwn
595
+ end
596
+ }
597
+ self * factor
598
+ end
599
+
600
+ def phase_velocity_filter(xdim, tdim, cmin=nil, cmax=nil, xconv=nil, tconv=nil, remove_xtmean=false)
601
+ raise(ArgumentError,"need at least cmin or cmax") if !(cmin || cmax)
602
+
603
+
604
+ xdim = dim_index(xdim) if xdim.is_a?(String)
605
+ xdim += rank if xdim < 0
606
+ tdim = dim_index(tdim) if tdim.is_a?(String)
607
+ tdim += rank if tdim < 0
608
+ fc = self.fft(nil,xdim,tdim)
609
+
610
+ kdim = xdim
611
+ fdim = tdim
612
+ kconv = ( xconv ? 1.0/xconv : nil )
613
+ fconv = ( tconv ? 1.0/tconv : nil )
614
+ cp, = fc.phase_velocity(kdim,fdim,kconv,fconv,!remove_xtmean,true)
615
+
616
+ fcv = fc.val
617
+ nk = fc.shape[kdim]
618
+ nf = fc.shape[fdim]
619
+ sel = [true]*fc.rank
620
+ for jf in 0...nf
621
+ for jk in 0...nk
622
+ c = cp[jk,jf]
623
+ if ( cmin && c<cmin or cmax && c>cmax)
624
+ sel[kdim]=jk
625
+ sel[fdim]=jf
626
+ fcv[*sel] = 0.0
627
+ end
628
+ end
629
+ end
630
+ fc.replace_val(fcv)
631
+ gp = fc.fft(true,xdim,tdim)
632
+ gp = gp.real if (self.typecode <= NArray::FLOAT)
633
+ GPhys.new(self.grid_copy, gp.data)
634
+ #^ use the original grid, since units may have changed
635
+ end
636
+
637
+ def phase_velocity_binning_iso_norml(kdim, fdim, cmin, cmax, cint,
638
+ kconv=nil, fconv=nil)
639
+ cbins = {"min"=>cmin,"max"=>cmax,"int"=>cint}
640
+ pwc = phase_velocity_binning(kdim, fdim, cbins, kconv, fconv)
641
+ fact = UNumeric[int, pwc.coord(0).units]
642
+ pwc/fact
643
+ end
644
+
645
+ def phase_velocity_binning(kdim, fdim, cbins, kconv=nil, fconv=nil)
646
+
647
+ # < process arguments >
648
+
649
+ case cbins
650
+ when Hash
651
+ min = cbins["min"] ||raise(ArgumentError,"a Hash cbins must have 'min'")
652
+ max = cbins["max"] ||raise(ArgumentError,"a Hash cbins must have 'max'")
653
+ int = cbins["int"] ||raise(ArgumentError,"a Hash cbins must have 'int'")
654
+ cbins = Array.new
655
+ eps = int.abs*1e-6 # epsilon to deal with float steps
656
+ (min.to_f..(max.to_f+eps)).step(int){|c| cbins.push(c)}
657
+ cbins = NArray.to_na(cbins)
658
+ when Array
659
+ cbins = NArray.to_na(cbins)
660
+ when NArray
661
+ else
662
+ raise ArgumentError, "cbins must be a Hash or Array or NArray"
663
+ end
664
+
665
+ kdim = dim_index(kdim) if kdim.is_a?(String)
666
+ kdim += rank if kdim < 0
667
+ fdim = dim_index(fdim) if fdim.is_a?(String)
668
+ fdim += rank if fdim < 0
669
+
670
+ # < sort along wavenumber/freuqency axis >
671
+
672
+ pw = self.spect_zero_centering(kdim).spect_one_sided(fdim)
673
+
674
+ # < process axes >
675
+
676
+ cp, cunits = pw.phase_velocity(kdim,fdim,kconv,fconv,false)
677
+
678
+ vcbins = VArray.new(cbins, {"units"=>cunits.to_s,
679
+ "long_name"=>"phase velocity bounds"}, "cbounds")
680
+ vccent = VArray.new( (cbins[0..-2] + cbins[1..-1])/2,
681
+ {"units"=>cunits.to_s, "long_name"=>"phase velocity"}, "c")
682
+ axc = Axis.new(true).set_cell(vccent, vcbins).set_pos_to_center
683
+ axes = [axc] # the first dimension will be "c"
684
+ gr = pw.grid
685
+ (0...pw.rank).each do |d|
686
+ if d!=kdim && d!=fdim
687
+ axes.push(gr.axis(d))
688
+ end
689
+ end
690
+ newgrid = Grid.new(*axes)
691
+
692
+ nk = pw.shape[kdim]
693
+ nf = pw.shape[fdim]
694
+ cp.reshape!(nk*nf)
695
+
696
+ # < reorder input data >
697
+
698
+ dimorder = (0...pw.rank).collect{|i| i}
699
+ dimorder.delete(fdim)
700
+ dimorder.unshift(fdim)
701
+ dimorder.delete(kdim)
702
+ dimorder.unshift(kdim) # --> [kdim, fdim, the other dims...]
703
+ sh = pw.shape
704
+ reshape = [nk*nf]
705
+ (0...rank).each{|i| reshape.push(sh[i]) if i!=fdim && i!=kdim}
706
+ pwv = pw.val.transpose(*dimorder).reshape(*reshape)
707
+ # --> [ combined k&fdim, the other dims...]
708
+
709
+ # < binning >
710
+
711
+ shc = newgrid.shape
712
+ pwc = NArray.new(pwv.typecode, *shc) # will have no missing data
713
+ nc = axc.length
714
+ for jc in 0...nc
715
+ w = (cp.gt(cbins[jc]) & cp.lt(cbins[jc+1])).where
716
+ pwc[jc,false] += pwv[w,false].sum(0) if w.length>0
717
+ w = (cp.eq(cbins[jc])).where
718
+ pwc[jc,false] += pwv[w,false].sum(0)/2 if w.length>0 # half from bdry
719
+ w = (cp.eq(cbins[jc+1])).where
720
+ pwc[jc,false] += pwv[w,false].sum(0)/2 if w.length>0 # half from bdry
721
+ end
722
+
723
+ vpwc = VArray.new(pwc,pw.data,pw.name)
724
+ gpwc = GPhys.new(newgrid,vpwc)
725
+
726
+ gpwc
727
+ end
728
+
729
+ def phase_velocity(kdim,fdim,kconv,fconv,kf0_is_c0=true,no_kfreorder=false)
730
+ kax = self.axis(kdim)
731
+ fax = self.axis(fdim)
732
+ kax.pos = kax.pos*kconv if kconv
733
+ fax.pos = fax.pos*fconv if fconv
734
+ cunits = fax.pos.units / kax.pos.units
735
+
736
+ f = fax.pos.val
737
+ k = kax.pos.val
738
+ nk = k.length
739
+ nf = f.length
740
+ if no_kfreorder
741
+ k[nk/2+1..-1] = -k[nk/2+1..-1][-1..0]+k[nk/2]
742
+ f[nf/2+1..-1] = -f[nf/2+1..-1][-1..0]+f[nf/2]
743
+ end
744
+ f = -f
745
+ cp = f.newdim(0) / k.newdim(1) #cp[kdim,fdim]
746
+ jf0 = f.eq(0).where[0] # where f==0
747
+ jk0 = k.eq(0).where[0] # where k==0
748
+ if kf0_is_c0
749
+ cp[jk0,jf0] = 0.0 # treat k=f=0 as stationary (c=0)
750
+ else
751
+ cp[jk0,jf0] = 1.0/0.0 # not to count k=f=0 component at all (c=infty)
752
+ end
753
+
754
+ [cp, cunits]
755
+ end
756
+
757
+ end
758
+ end
759
+
760
+ ######################################################
761
+ ## < test >
762
+ if $0 == __FILE__
763
+ require "numru/ggraph"
764
+
765
+ include NumRu
766
+ include NMath
767
+
768
+ # < make a GPhys from scratch >
769
+ vx = VArray.new( NArray.float(11).indgen! * (3*Math::PI/11) ).rename("x")
770
+ vx.units = 'km'
771
+ vy = VArray.new( NArray.float(8).indgen! * (3*Math::PI/8) ).rename("y")
772
+ vy.units = 'km'
773
+ xax = Axis.new().set_pos(vx)
774
+ #yax = Axis.new(true).set_cell_guess_bounds(vy).set_pos_to_center
775
+ yax = Axis.new().set_pos(vy)
776
+ grid = Grid.new(xax, yax)
777
+ a = NArray.float(vx.length, vy.length)
778
+ a[] = sin(vx.val.newdim(1)) * cos(vy.val.newdim(0))
779
+ v = VArray.new( a )
780
+ v.units = 'm/s'
781
+ gpz = GPhys.new(grid,v)
782
+
783
+ print "Original:\n"
784
+ p gpz.val
785
+ fc = gpz.fft
786
+ print "2D FFT & abs:\n"
787
+ p fc.val.abs, fc.units.to_s, fc.coord(0).units.to_s
788
+ print "Check the invertivility: ",
789
+ (fc.fft(true) - gpz).abs.max, ' / ', gpz.abs.max, "\n"
790
+ sp = fc.abs**2
791
+ print "Check parsevals relation: ",
792
+ sp.sum, ' / ', (gpz**2).mean, "\n"
793
+
794
+ spex = sp.spect_zero_centering(0)
795
+ spex2 = spex.spect_one_sided(1)
796
+ print " sidedness changed --> ",spex.sum,", ",spex2.sum,"\n"
797
+
798
+ if defined?(FFTW3)
799
+ fc = gpz.fft(nil, 0)
800
+ print "1D FFT & abs:\n"
801
+ p fc.val.abs
802
+ print "Check the invertivility: ",
803
+ (fc.fft(true, 0) - gpz).abs.max, ' / ', gpz.abs.max, "\n"
804
+ sp = fc.abs**2
805
+ print "Check parsevals relation: ",
806
+ sp.sum(0).mean, ' / ', (gpz**2).mean, "\n"
807
+ end
808
+
809
+ print "\n** Check detrend **\n"
810
+ print "when NArray...\n"
811
+ EPS = 5e-14
812
+ a.indgen!
813
+ v = VArray.new( a )
814
+ gp = GPhys.new(grid,v)
815
+ gpdt = gp.detrend(0)
816
+ if gpdt.val.max <EPS; print "test succeeded\n";else; raise "test failed";end
817
+ gpdt = gp.detrend(1)
818
+ if gpdt.val.max <EPS; print "test succeeded\n";else; raise "test failed";end
819
+ print " -- NArrayMiss\n"
820
+ mask = a.le(47)
821
+ am = NArrayMiss.to_nam(a, mask)
822
+ v = VArray.new( am )
823
+ gp = GPhys.new(grid,v)
824
+ gpdt = gp.detrend(0)
825
+ #if gpdt.val.max <EPS; print "test succeeded\n";else; raise "test failed";end
826
+ p "The following should be basically zero:",gpdt.val
827
+ gpdt = gp.detrend(1)
828
+ #if gpdt.val.max <EPS; print "test succeeded\n";else; raise "test failed";end
829
+ p "The following should be basically zero:",gpdt.val
830
+
831
+ print "\n** Check cos_taper **\n"
832
+ a = NArray.float(30,10).fill!(1)
833
+ v = VArray.new( a )
834
+ xax2 = Axis.new().set_pos(VArray.new(NArray.float(30).indgen!).rename("x"))
835
+ yax2 = Axis.new().set_pos(VArray.new(NArray.float(10).indgen!).rename("y"))
836
+ gp = GPhys.new( Grid.new(xax2, yax2), v )
837
+ gpct = gp.cos_taper(0)
838
+ gpct = gp.cos_taper(0,1)
839
+ p gpct.val
840
+ p GPhys::COS_TAPER_SP_FACTOR, 1/GPhys::COS_TAPER_SP_FACTOR
841
+
842
+ print "\n** Check phase velocity binning **\n"
843
+
844
+ vd = VArray.new( NArray.to_na([0.0,1.0]),{"units"=>"m","long_name"=>"dummy"},"d")
845
+ dax = Axis.new().set_pos(vd)
846
+ vy.units = 'hour'
847
+ vy.name = 't'
848
+
849
+ xx = vx.val.newdim(1)
850
+ yy = vy.val.newdim(0)
851
+ a = sin(xx) * cos(yy) + 0.5*sin(xx*1.2+yy*0.6)
852
+ #a = 0.5*sin(xx*1.2+yy*0.7)
853
+ #a = sin(xx) * cos(yy) + 0.2*sin(xx+yy)
854
+
855
+ b = NArray.float(a.shape[0], 2, a.shape[1])
856
+ b[true,0,true] = a + 1
857
+ b[true,1,true] = a
858
+ v = VArray.new( b, {"units"=>"K", "long_name"=>"vv"}, "v" )
859
+ grid = Grid.new(xax, dax, yax)
860
+ gp = GPhys.new(grid, v)
861
+
862
+ fc = gp.fft(nil, 0, 2)
863
+ sp = fc.abs**2
864
+ fconv = UNumeric[1/3.6e3,"hour/s"]
865
+ kconv = UNumeric[1e-3,"km/m"]
866
+ csp = fc.phase_velocity_binning(0, 2, {"min"=>-2,"max"=>2,"int"=>0.25},
867
+ kconv, fconv)
868
+ p csp
869
+ #cspn = sp.phase_velocity_binning_iso_norml(0, 2, -2, 2, 0.25, kconv, fconv)
870
+
871
+ DCL.gropn(1)
872
+ DCL.sldiv('y',2,2)
873
+ GGraph::tone gp[true,0,true],true,"color_bar"=>true
874
+ GGraph::line csp[true,0].real,true, "max"=>0.6,"min"=>-0.6
875
+ GGraph::line csp[true,0].imag,false, "type"=>2
876
+ #GGraph::line cspn[true,0]
877
+
878
+ gpf = gp.phase_velocity_filter(0, 2, -2.0, 0.0, 1/kconv, 1/fconv)
879
+ GGraph::tone gpf[true,0,true],true,"color_bar"=>true
880
+ gpf = gp.phase_velocity_filter(0, 2, -0.3, -0.01, 1/kconv, 1/fconv)
881
+ GGraph::tone gpf[true,0,true],true,"color_bar"=>true
882
+
883
+
884
+ DCL.grcls
885
+ end
886
+