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,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
+