gphys 1.2.2.1 → 1.4.3

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 (405) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +8 -17
  3. data/.rspec +2 -0
  4. data/.travis.yml +3 -0
  5. data/ChangeLog +5762 -753
  6. data/LICENSE.txt +30 -18
  7. data/Rakefile +1 -0
  8. data/bin/console +14 -0
  9. data/bin/gpcat +43 -2
  10. data/bin/gpcut +16 -0
  11. data/bin/gpvect +167 -15
  12. data/bin/gpview +254 -51
  13. data/bin/setup +7 -0
  14. data/dim_op.c +1220 -0
  15. data/doc/attribute.html +19 -0
  16. data/doc/attributenetcdf.html +15 -0
  17. data/doc/axis.html +387 -0
  18. data/doc/coordmapping.html +111 -0
  19. data/doc/coordtransform.html +36 -0
  20. data/doc/dclext.html +821 -0
  21. data/doc/derivative/gphys-derivative.html +100 -0
  22. data/doc/derivative/index.html +21 -0
  23. data/doc/derivative/index.rd +14 -0
  24. data/doc/derivative/math-doc/document.pdf +0 -0
  25. data/doc/derivative/math-doc/document.tex +158 -0
  26. data/doc/derivative/math-doc/document/document.css +30 -0
  27. data/doc/derivative/math-doc/document/document.html +57 -0
  28. data/doc/derivative/math-doc/document/images.aux +1 -0
  29. data/doc/derivative/math-doc/document/images.log +385 -0
  30. data/doc/derivative/math-doc/document/images.pl +186 -0
  31. data/doc/derivative/math-doc/document/images.tex +364 -0
  32. data/doc/derivative/math-doc/document/img1.png +0 -0
  33. data/doc/derivative/math-doc/document/img10.png +0 -0
  34. data/doc/derivative/math-doc/document/img11.png +0 -0
  35. data/doc/derivative/math-doc/document/img12.png +0 -0
  36. data/doc/derivative/math-doc/document/img13.png +0 -0
  37. data/doc/derivative/math-doc/document/img14.png +0 -0
  38. data/doc/derivative/math-doc/document/img15.png +0 -0
  39. data/doc/derivative/math-doc/document/img16.png +0 -0
  40. data/doc/derivative/math-doc/document/img17.png +0 -0
  41. data/doc/derivative/math-doc/document/img18.png +0 -0
  42. data/doc/derivative/math-doc/document/img19.png +0 -0
  43. data/doc/derivative/math-doc/document/img2.png +0 -0
  44. data/doc/derivative/math-doc/document/img20.png +0 -0
  45. data/doc/derivative/math-doc/document/img21.png +0 -0
  46. data/doc/derivative/math-doc/document/img22.png +0 -0
  47. data/doc/derivative/math-doc/document/img23.png +0 -0
  48. data/doc/derivative/math-doc/document/img24.png +0 -0
  49. data/doc/derivative/math-doc/document/img25.png +0 -0
  50. data/doc/derivative/math-doc/document/img26.png +0 -0
  51. data/doc/derivative/math-doc/document/img27.png +0 -0
  52. data/doc/derivative/math-doc/document/img28.png +0 -0
  53. data/doc/derivative/math-doc/document/img29.png +0 -0
  54. data/doc/derivative/math-doc/document/img3.png +0 -0
  55. data/doc/derivative/math-doc/document/img30.png +0 -0
  56. data/doc/derivative/math-doc/document/img4.png +0 -0
  57. data/doc/derivative/math-doc/document/img5.png +0 -0
  58. data/doc/derivative/math-doc/document/img6.png +0 -0
  59. data/doc/derivative/math-doc/document/img7.png +0 -0
  60. data/doc/derivative/math-doc/document/img8.png +0 -0
  61. data/doc/derivative/math-doc/document/img9.png +0 -0
  62. data/doc/derivative/math-doc/document/index.html +57 -0
  63. data/doc/derivative/math-doc/document/labels.pl +13 -0
  64. data/doc/derivative/math-doc/document/next.png +0 -0
  65. data/doc/derivative/math-doc/document/next_g.png +0 -0
  66. data/doc/derivative/math-doc/document/node1.html +238 -0
  67. data/doc/derivative/math-doc/document/node2.html +75 -0
  68. data/doc/derivative/math-doc/document/prev.png +0 -0
  69. data/doc/derivative/math-doc/document/prev_g.png +0 -0
  70. data/doc/derivative/math-doc/document/up.png +0 -0
  71. data/doc/derivative/math-doc/document/up_g.png +0 -0
  72. data/doc/derivative/numru-derivative.html +158 -0
  73. data/doc/ep_flux/ep_flux.html +469 -0
  74. data/doc/ep_flux/ggraph_on_merdional_section.html +71 -0
  75. data/doc/ep_flux/index.html +31 -0
  76. data/doc/ep_flux/index.rd +24 -0
  77. data/doc/ep_flux/math-doc/document.pdf +0 -0
  78. data/doc/ep_flux/math-doc/document.tex +2018 -0
  79. data/doc/ep_flux/math-doc/document/WARNINGS +1 -0
  80. data/doc/ep_flux/math-doc/document/contents.png +0 -0
  81. data/doc/ep_flux/math-doc/document/crossref.png +0 -0
  82. data/doc/ep_flux/math-doc/document/document.css +30 -0
  83. data/doc/ep_flux/math-doc/document/document.html +101 -0
  84. data/doc/ep_flux/math-doc/document/images.aux +1 -0
  85. data/doc/ep_flux/math-doc/document/images.log +1375 -0
  86. data/doc/ep_flux/math-doc/document/images.pl +1328 -0
  87. data/doc/ep_flux/math-doc/document/images.tex +1471 -0
  88. data/doc/ep_flux/math-doc/document/img1.png +0 -0
  89. data/doc/ep_flux/math-doc/document/img10.png +0 -0
  90. data/doc/ep_flux/math-doc/document/img100.png +0 -0
  91. data/doc/ep_flux/math-doc/document/img101.png +0 -0
  92. data/doc/ep_flux/math-doc/document/img102.png +0 -0
  93. data/doc/ep_flux/math-doc/document/img103.png +0 -0
  94. data/doc/ep_flux/math-doc/document/img104.png +0 -0
  95. data/doc/ep_flux/math-doc/document/img105.png +0 -0
  96. data/doc/ep_flux/math-doc/document/img106.png +0 -0
  97. data/doc/ep_flux/math-doc/document/img107.png +0 -0
  98. data/doc/ep_flux/math-doc/document/img108.png +0 -0
  99. data/doc/ep_flux/math-doc/document/img109.png +0 -0
  100. data/doc/ep_flux/math-doc/document/img11.png +0 -0
  101. data/doc/ep_flux/math-doc/document/img110.png +0 -0
  102. data/doc/ep_flux/math-doc/document/img111.png +0 -0
  103. data/doc/ep_flux/math-doc/document/img112.png +0 -0
  104. data/doc/ep_flux/math-doc/document/img113.png +0 -0
  105. data/doc/ep_flux/math-doc/document/img114.png +0 -0
  106. data/doc/ep_flux/math-doc/document/img115.png +0 -0
  107. data/doc/ep_flux/math-doc/document/img116.png +0 -0
  108. data/doc/ep_flux/math-doc/document/img117.png +0 -0
  109. data/doc/ep_flux/math-doc/document/img118.png +0 -0
  110. data/doc/ep_flux/math-doc/document/img119.png +0 -0
  111. data/doc/ep_flux/math-doc/document/img12.png +0 -0
  112. data/doc/ep_flux/math-doc/document/img120.png +0 -0
  113. data/doc/ep_flux/math-doc/document/img121.png +0 -0
  114. data/doc/ep_flux/math-doc/document/img122.png +0 -0
  115. data/doc/ep_flux/math-doc/document/img123.png +0 -0
  116. data/doc/ep_flux/math-doc/document/img124.png +0 -0
  117. data/doc/ep_flux/math-doc/document/img125.png +0 -0
  118. data/doc/ep_flux/math-doc/document/img126.png +0 -0
  119. data/doc/ep_flux/math-doc/document/img127.png +0 -0
  120. data/doc/ep_flux/math-doc/document/img128.png +0 -0
  121. data/doc/ep_flux/math-doc/document/img129.png +0 -0
  122. data/doc/ep_flux/math-doc/document/img13.png +0 -0
  123. data/doc/ep_flux/math-doc/document/img130.png +0 -0
  124. data/doc/ep_flux/math-doc/document/img131.png +0 -0
  125. data/doc/ep_flux/math-doc/document/img132.png +0 -0
  126. data/doc/ep_flux/math-doc/document/img133.png +0 -0
  127. data/doc/ep_flux/math-doc/document/img134.png +0 -0
  128. data/doc/ep_flux/math-doc/document/img135.png +0 -0
  129. data/doc/ep_flux/math-doc/document/img136.png +0 -0
  130. data/doc/ep_flux/math-doc/document/img137.png +0 -0
  131. data/doc/ep_flux/math-doc/document/img138.png +0 -0
  132. data/doc/ep_flux/math-doc/document/img139.png +0 -0
  133. data/doc/ep_flux/math-doc/document/img14.png +0 -0
  134. data/doc/ep_flux/math-doc/document/img140.png +0 -0
  135. data/doc/ep_flux/math-doc/document/img141.png +0 -0
  136. data/doc/ep_flux/math-doc/document/img142.png +0 -0
  137. data/doc/ep_flux/math-doc/document/img143.png +0 -0
  138. data/doc/ep_flux/math-doc/document/img144.png +0 -0
  139. data/doc/ep_flux/math-doc/document/img145.png +0 -0
  140. data/doc/ep_flux/math-doc/document/img146.png +0 -0
  141. data/doc/ep_flux/math-doc/document/img147.png +0 -0
  142. data/doc/ep_flux/math-doc/document/img148.png +0 -0
  143. data/doc/ep_flux/math-doc/document/img149.png +0 -0
  144. data/doc/ep_flux/math-doc/document/img15.png +0 -0
  145. data/doc/ep_flux/math-doc/document/img150.png +0 -0
  146. data/doc/ep_flux/math-doc/document/img151.png +0 -0
  147. data/doc/ep_flux/math-doc/document/img152.png +0 -0
  148. data/doc/ep_flux/math-doc/document/img153.png +0 -0
  149. data/doc/ep_flux/math-doc/document/img154.png +0 -0
  150. data/doc/ep_flux/math-doc/document/img155.png +0 -0
  151. data/doc/ep_flux/math-doc/document/img156.png +0 -0
  152. data/doc/ep_flux/math-doc/document/img157.png +0 -0
  153. data/doc/ep_flux/math-doc/document/img158.png +0 -0
  154. data/doc/ep_flux/math-doc/document/img159.png +0 -0
  155. data/doc/ep_flux/math-doc/document/img16.png +0 -0
  156. data/doc/ep_flux/math-doc/document/img160.png +0 -0
  157. data/doc/ep_flux/math-doc/document/img161.png +0 -0
  158. data/doc/ep_flux/math-doc/document/img162.png +0 -0
  159. data/doc/ep_flux/math-doc/document/img163.png +0 -0
  160. data/doc/ep_flux/math-doc/document/img164.png +0 -0
  161. data/doc/ep_flux/math-doc/document/img165.png +0 -0
  162. data/doc/ep_flux/math-doc/document/img166.png +0 -0
  163. data/doc/ep_flux/math-doc/document/img167.png +0 -0
  164. data/doc/ep_flux/math-doc/document/img168.png +0 -0
  165. data/doc/ep_flux/math-doc/document/img169.png +0 -0
  166. data/doc/ep_flux/math-doc/document/img17.png +0 -0
  167. data/doc/ep_flux/math-doc/document/img170.png +0 -0
  168. data/doc/ep_flux/math-doc/document/img171.png +0 -0
  169. data/doc/ep_flux/math-doc/document/img172.png +0 -0
  170. data/doc/ep_flux/math-doc/document/img173.png +0 -0
  171. data/doc/ep_flux/math-doc/document/img174.png +0 -0
  172. data/doc/ep_flux/math-doc/document/img175.png +0 -0
  173. data/doc/ep_flux/math-doc/document/img176.png +0 -0
  174. data/doc/ep_flux/math-doc/document/img177.png +0 -0
  175. data/doc/ep_flux/math-doc/document/img178.png +0 -0
  176. data/doc/ep_flux/math-doc/document/img179.png +0 -0
  177. data/doc/ep_flux/math-doc/document/img18.png +0 -0
  178. data/doc/ep_flux/math-doc/document/img180.png +0 -0
  179. data/doc/ep_flux/math-doc/document/img181.png +0 -0
  180. data/doc/ep_flux/math-doc/document/img182.png +0 -0
  181. data/doc/ep_flux/math-doc/document/img183.png +0 -0
  182. data/doc/ep_flux/math-doc/document/img184.png +0 -0
  183. data/doc/ep_flux/math-doc/document/img185.png +0 -0
  184. data/doc/ep_flux/math-doc/document/img186.png +0 -0
  185. data/doc/ep_flux/math-doc/document/img187.png +0 -0
  186. data/doc/ep_flux/math-doc/document/img188.png +0 -0
  187. data/doc/ep_flux/math-doc/document/img189.png +0 -0
  188. data/doc/ep_flux/math-doc/document/img19.png +0 -0
  189. data/doc/ep_flux/math-doc/document/img190.png +0 -0
  190. data/doc/ep_flux/math-doc/document/img191.png +0 -0
  191. data/doc/ep_flux/math-doc/document/img192.png +0 -0
  192. data/doc/ep_flux/math-doc/document/img193.png +0 -0
  193. data/doc/ep_flux/math-doc/document/img194.png +0 -0
  194. data/doc/ep_flux/math-doc/document/img195.png +0 -0
  195. data/doc/ep_flux/math-doc/document/img196.png +0 -0
  196. data/doc/ep_flux/math-doc/document/img197.png +0 -0
  197. data/doc/ep_flux/math-doc/document/img198.png +0 -0
  198. data/doc/ep_flux/math-doc/document/img199.png +0 -0
  199. data/doc/ep_flux/math-doc/document/img2.png +0 -0
  200. data/doc/ep_flux/math-doc/document/img20.png +0 -0
  201. data/doc/ep_flux/math-doc/document/img200.png +0 -0
  202. data/doc/ep_flux/math-doc/document/img21.png +0 -0
  203. data/doc/ep_flux/math-doc/document/img22.png +0 -0
  204. data/doc/ep_flux/math-doc/document/img23.png +0 -0
  205. data/doc/ep_flux/math-doc/document/img24.png +0 -0
  206. data/doc/ep_flux/math-doc/document/img25.png +0 -0
  207. data/doc/ep_flux/math-doc/document/img26.png +0 -0
  208. data/doc/ep_flux/math-doc/document/img27.png +0 -0
  209. data/doc/ep_flux/math-doc/document/img28.png +0 -0
  210. data/doc/ep_flux/math-doc/document/img29.png +0 -0
  211. data/doc/ep_flux/math-doc/document/img3.png +0 -0
  212. data/doc/ep_flux/math-doc/document/img30.png +0 -0
  213. data/doc/ep_flux/math-doc/document/img31.png +0 -0
  214. data/doc/ep_flux/math-doc/document/img32.png +0 -0
  215. data/doc/ep_flux/math-doc/document/img33.png +0 -0
  216. data/doc/ep_flux/math-doc/document/img34.png +0 -0
  217. data/doc/ep_flux/math-doc/document/img35.png +0 -0
  218. data/doc/ep_flux/math-doc/document/img36.png +0 -0
  219. data/doc/ep_flux/math-doc/document/img37.png +0 -0
  220. data/doc/ep_flux/math-doc/document/img38.png +0 -0
  221. data/doc/ep_flux/math-doc/document/img39.png +0 -0
  222. data/doc/ep_flux/math-doc/document/img4.png +0 -0
  223. data/doc/ep_flux/math-doc/document/img40.png +0 -0
  224. data/doc/ep_flux/math-doc/document/img41.png +0 -0
  225. data/doc/ep_flux/math-doc/document/img42.png +0 -0
  226. data/doc/ep_flux/math-doc/document/img43.png +0 -0
  227. data/doc/ep_flux/math-doc/document/img44.png +0 -0
  228. data/doc/ep_flux/math-doc/document/img45.png +0 -0
  229. data/doc/ep_flux/math-doc/document/img46.png +0 -0
  230. data/doc/ep_flux/math-doc/document/img47.png +0 -0
  231. data/doc/ep_flux/math-doc/document/img48.png +0 -0
  232. data/doc/ep_flux/math-doc/document/img49.png +0 -0
  233. data/doc/ep_flux/math-doc/document/img5.png +0 -0
  234. data/doc/ep_flux/math-doc/document/img50.png +0 -0
  235. data/doc/ep_flux/math-doc/document/img51.png +0 -0
  236. data/doc/ep_flux/math-doc/document/img52.png +0 -0
  237. data/doc/ep_flux/math-doc/document/img53.png +0 -0
  238. data/doc/ep_flux/math-doc/document/img54.png +0 -0
  239. data/doc/ep_flux/math-doc/document/img55.png +0 -0
  240. data/doc/ep_flux/math-doc/document/img56.png +0 -0
  241. data/doc/ep_flux/math-doc/document/img57.png +0 -0
  242. data/doc/ep_flux/math-doc/document/img58.png +0 -0
  243. data/doc/ep_flux/math-doc/document/img59.png +0 -0
  244. data/doc/ep_flux/math-doc/document/img6.png +0 -0
  245. data/doc/ep_flux/math-doc/document/img60.png +0 -0
  246. data/doc/ep_flux/math-doc/document/img61.png +0 -0
  247. data/doc/ep_flux/math-doc/document/img62.png +0 -0
  248. data/doc/ep_flux/math-doc/document/img63.png +0 -0
  249. data/doc/ep_flux/math-doc/document/img64.png +0 -0
  250. data/doc/ep_flux/math-doc/document/img65.png +0 -0
  251. data/doc/ep_flux/math-doc/document/img66.png +0 -0
  252. data/doc/ep_flux/math-doc/document/img67.png +0 -0
  253. data/doc/ep_flux/math-doc/document/img68.png +0 -0
  254. data/doc/ep_flux/math-doc/document/img69.png +0 -0
  255. data/doc/ep_flux/math-doc/document/img7.png +0 -0
  256. data/doc/ep_flux/math-doc/document/img70.png +0 -0
  257. data/doc/ep_flux/math-doc/document/img71.png +0 -0
  258. data/doc/ep_flux/math-doc/document/img72.png +0 -0
  259. data/doc/ep_flux/math-doc/document/img73.png +0 -0
  260. data/doc/ep_flux/math-doc/document/img74.png +0 -0
  261. data/doc/ep_flux/math-doc/document/img75.png +0 -0
  262. data/doc/ep_flux/math-doc/document/img76.png +0 -0
  263. data/doc/ep_flux/math-doc/document/img77.png +0 -0
  264. data/doc/ep_flux/math-doc/document/img78.png +0 -0
  265. data/doc/ep_flux/math-doc/document/img79.png +0 -0
  266. data/doc/ep_flux/math-doc/document/img8.png +0 -0
  267. data/doc/ep_flux/math-doc/document/img80.png +0 -0
  268. data/doc/ep_flux/math-doc/document/img81.png +0 -0
  269. data/doc/ep_flux/math-doc/document/img82.png +0 -0
  270. data/doc/ep_flux/math-doc/document/img83.png +0 -0
  271. data/doc/ep_flux/math-doc/document/img84.png +0 -0
  272. data/doc/ep_flux/math-doc/document/img85.png +0 -0
  273. data/doc/ep_flux/math-doc/document/img86.png +0 -0
  274. data/doc/ep_flux/math-doc/document/img87.png +0 -0
  275. data/doc/ep_flux/math-doc/document/img88.png +0 -0
  276. data/doc/ep_flux/math-doc/document/img89.png +0 -0
  277. data/doc/ep_flux/math-doc/document/img9.png +0 -0
  278. data/doc/ep_flux/math-doc/document/img90.png +0 -0
  279. data/doc/ep_flux/math-doc/document/img91.png +0 -0
  280. data/doc/ep_flux/math-doc/document/img92.png +0 -0
  281. data/doc/ep_flux/math-doc/document/img93.png +0 -0
  282. data/doc/ep_flux/math-doc/document/img94.png +0 -0
  283. data/doc/ep_flux/math-doc/document/img95.png +0 -0
  284. data/doc/ep_flux/math-doc/document/img96.png +0 -0
  285. data/doc/ep_flux/math-doc/document/img97.png +0 -0
  286. data/doc/ep_flux/math-doc/document/img98.png +0 -0
  287. data/doc/ep_flux/math-doc/document/img99.png +0 -0
  288. data/doc/ep_flux/math-doc/document/index.html +101 -0
  289. data/doc/ep_flux/math-doc/document/internals.pl +258 -0
  290. data/doc/ep_flux/math-doc/document/labels.pl +265 -0
  291. data/doc/ep_flux/math-doc/document/next.png +0 -0
  292. data/doc/ep_flux/math-doc/document/next_g.png +0 -0
  293. data/doc/ep_flux/math-doc/document/node1.html +104 -0
  294. data/doc/ep_flux/math-doc/document/node10.html +164 -0
  295. data/doc/ep_flux/math-doc/document/node11.html +86 -0
  296. data/doc/ep_flux/math-doc/document/node12.html +166 -0
  297. data/doc/ep_flux/math-doc/document/node13.html +897 -0
  298. data/doc/ep_flux/math-doc/document/node14.html +1065 -0
  299. data/doc/ep_flux/math-doc/document/node15.html +72 -0
  300. data/doc/ep_flux/math-doc/document/node16.html +81 -0
  301. data/doc/ep_flux/math-doc/document/node2.html +82 -0
  302. data/doc/ep_flux/math-doc/document/node3.html +91 -0
  303. data/doc/ep_flux/math-doc/document/node4.html +149 -0
  304. data/doc/ep_flux/math-doc/document/node5.html +330 -0
  305. data/doc/ep_flux/math-doc/document/node6.html +99 -0
  306. data/doc/ep_flux/math-doc/document/node7.html +98 -0
  307. data/doc/ep_flux/math-doc/document/node8.html +83 -0
  308. data/doc/ep_flux/math-doc/document/node9.html +140 -0
  309. data/doc/ep_flux/math-doc/document/prev.png +0 -0
  310. data/doc/ep_flux/math-doc/document/prev_g.png +0 -0
  311. data/doc/ep_flux/math-doc/document/up.png +0 -0
  312. data/doc/ep_flux/math-doc/document/up_g.png +0 -0
  313. data/doc/gdir.html +412 -0
  314. data/doc/gdir_client.html +16 -0
  315. data/doc/gdir_connect_ftp-like.html +61 -0
  316. data/doc/gdir_server.html +45 -0
  317. data/doc/ggraph.html +1119 -0
  318. data/doc/gpcat.html +45 -0
  319. data/doc/gpcut.html +47 -0
  320. data/doc/gphys.html +624 -0
  321. data/doc/gphys_fft.html +324 -0
  322. data/doc/gphys_grads_io.html +69 -0
  323. data/doc/gphys_grib_io.html +82 -0
  324. data/doc/gphys_io.html +183 -0
  325. data/doc/gphys_io_common.html +18 -0
  326. data/doc/gphys_netcdf_io.html +283 -0
  327. data/doc/gplist.html +24 -0
  328. data/doc/gpmath.html +52 -0
  329. data/doc/gpmaxmin.html +32 -0
  330. data/doc/gpprint.html +35 -0
  331. data/doc/gpview.html +349 -0
  332. data/doc/grads2nc_with_gphys.html +21 -0
  333. data/doc/grads_gridded.html +307 -0
  334. data/doc/grib.html +149 -0
  335. data/doc/grid.html +224 -0
  336. data/doc/index.html +145 -0
  337. data/doc/index.rd +138 -0
  338. data/doc/netcdf_convention.html +136 -0
  339. data/doc/unumeric.html +176 -0
  340. data/doc/update +69 -0
  341. data/doc/update_rdoc +8 -0
  342. data/doc/varray.html +299 -0
  343. data/doc/varraycomposite.html +67 -0
  344. data/ext_init.c +1 -0
  345. data/extconf.rb +16 -6
  346. data/gphys.gemspec +33 -26
  347. data/interpo.c +1 -1
  348. data/lib/numru/dclext.rb +718 -546
  349. data/lib/numru/derivative.rb +2 -0
  350. data/lib/numru/ganalysis.rb +38 -0
  351. data/lib/numru/ganalysis/beta_plane.rb +103 -0
  352. data/lib/numru/ganalysis/eof.rb +3 -2
  353. data/lib/numru/ganalysis/fitting.rb +559 -0
  354. data/lib/numru/ganalysis/histogram.rb +36 -19
  355. data/lib/numru/ganalysis/log_p.rb +130 -0
  356. data/lib/numru/ganalysis/met.rb +396 -2
  357. data/lib/numru/ganalysis/met_z.rb +300 -0
  358. data/lib/numru/ganalysis/planet.rb +17 -7
  359. data/lib/numru/ganalysis/qg.rb +685 -0
  360. data/lib/numru/ganalysis/sigma_coord.rb +90 -0
  361. data/lib/numru/gdir.rb +2 -1
  362. data/lib/numru/ggraph.rb +204 -60
  363. data/lib/numru/ggraph_on_merdional_section.rb +1 -1
  364. data/lib/numru/gphys.rb +6 -0
  365. data/lib/numru/gphys/assoccoords.rb +18 -3
  366. data/lib/numru/gphys/axis.rb +209 -8
  367. data/lib/numru/gphys/derivative.rb +11 -0
  368. data/lib/numru/gphys/gphys.rb +539 -48
  369. data/lib/numru/gphys/gphys_dim_op.rb +331 -0
  370. data/lib/numru/gphys/gphys_fft.rb +48 -2
  371. data/lib/numru/gphys/gphys_io.rb +241 -13
  372. data/lib/numru/gphys/gphys_netcdf_io.rb +77 -39
  373. data/lib/numru/gphys/gphys_nusdas_io.rb +3 -0
  374. data/lib/numru/gphys/grib.rb +133 -54
  375. data/lib/numru/gphys/grib_params.rb +26 -3
  376. data/lib/numru/gphys/grid.rb +75 -34
  377. data/lib/numru/gphys/interpolate.rb +24 -10
  378. data/lib/numru/gphys/mdstorage.rb +160 -0
  379. data/lib/numru/gphys/netcdf_convention.rb +4 -2
  380. data/lib/numru/gphys/subsetmapping.rb +0 -1
  381. data/lib/numru/gphys/unumeric.rb +50 -5
  382. data/lib/numru/gphys/varray.rb +15 -30
  383. data/lib/numru/gphys/varraycomposite.rb +107 -24
  384. data/lib/numru/gphys/varraynetcdf.rb +9 -3
  385. data/lib/numru/gphys/version.rb +5 -0
  386. data/sample/druby_cli1.rb +2 -0
  387. data/sample/druby_cli2.rb +0 -6
  388. data/sample/druby_serv2.rb +0 -13
  389. data/spec/gphys_spec.rb +11 -0
  390. data/spec/spec_helper.rb +2 -0
  391. data/test/test_assoccoords.rb +102 -0
  392. data/test/test_axis.rb +61 -0
  393. data/test/test_fitting.rb +116 -0
  394. data/test/test_gphys.rb +20 -0
  395. data/test/test_met_z.rb +96 -0
  396. data/test/test_sigma_coord.rb +50 -0
  397. data/{test → test_old}/eof_slp.rb +0 -0
  398. data/{test → test_old}/mltbit.dat +0 -0
  399. data/{test → test_old}/test_ep_flux.rb +0 -0
  400. data/{test → test_old}/test_multibitIO.rb +0 -0
  401. metadata +530 -191
  402. data/README.md +0 -29
  403. data/lib/gphys.rb +0 -2
  404. data/lib/numru/dclext_datetime_ax.rb +0 -220
  405. data/lib/version.rb +0 -3
@@ -100,7 +100,7 @@ module NumRu
100
100
  fx = fx[idx, true]
101
101
  fy = fy[idx, true]
102
102
  end
103
- if ((yi=opts['xintv']) >= 2)
103
+ if ((yi=opts['yintv']) >= 2)
104
104
  idx = NArray.int(sh[1]/yi).indgen!*yi # [0,yi,2*yi,..]
105
105
  fx = fx[true, idx]
106
106
  fy = fy[true, idx]
@@ -1,9 +1,15 @@
1
1
  # The root file to load the entire gphys package except GGraph.
2
2
 
3
+ begin
4
+ require "rubygems"
5
+ rescue LoadError
6
+ end
7
+ require 'numru/gphys/version'
3
8
  require 'numru/gphys/gphys'
4
9
  require "numru/gphys/gphys_io"
5
10
  require 'numru/gphys/gphys_fft'
6
11
  require 'numru/gphys_ext' # extension library
7
12
  require 'numru/gphys/interpolate'
13
+ require 'numru/gphys/gphys_dim_op'
8
14
  require 'numru/gdir'
9
15
  # require 'numru/gphys/ep_flux' # Made optional. Require it explicitly if needed
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  require "narray"
2
3
  #require "numru/gphys_ext"
3
4
 
@@ -110,6 +111,15 @@ module NumRu
110
111
  @assoc_crds[name].data # return a VArray
111
112
  end
112
113
 
114
+ def replace(gphys)
115
+ raise(ArgumentError,"not a GPhys") unless gphys.is_a?(GPhys)
116
+ nm = gphys.name
117
+ raise("assoc coord '#{nm}' is not found") unless (old=@assoc_crds[nm])
118
+ raise("shapes of the current and new '#{nm}' are different") unless old.shape==gphys.shape
119
+ @assoc_crds[nm] = gphys
120
+ self
121
+ end
122
+
113
123
  def coord_gphys(name)
114
124
  @assoc_crds[name] # return a GPhys
115
125
  end
@@ -122,7 +132,7 @@ module NumRu
122
132
  @assoc_crds.keys
123
133
  end
124
134
 
125
- # assoc_crds �Ɋւ�����W�l�x�[�X�̐؂�o�� : ������ Hash �̂�
135
+ # assoc_crds に関する座標値ベースの切り出し : 引数は Hash のみ
126
136
  def cut(hash)
127
137
  cutaxnms = hash.keys
128
138
  newcrds = Array.new
@@ -145,7 +155,7 @@ module NumRu
145
155
  anms = @assoc_crds[nm].axnames
146
156
  crdaxexist.push( NArray.to_na(
147
157
  orgaxnms.collect{|a| anms.include?(a) ? 1 : 0} ) )
148
- v = @assoc_crds[nm].val # ���W�l (NArray or NArrayMiss)
158
+ v = @assoc_crds[nm].val # 座標値 (NArray or NArrayMiss)
149
159
  if v.is_a?(NArrayMiss)
150
160
  crds.push(v.to_na)
151
161
  masks.push(v.get_mask)
@@ -221,7 +231,12 @@ module NumRu
221
231
  end
222
232
  end
223
233
 
224
- ret = self.class.new( new_assoc_crds, @axnames )
234
+ axnames = Array.new
235
+ args.each_with_index do |a, i|
236
+ axnames.push @axnames[i] unless Numeric === a
237
+ end
238
+
239
+ ret = self.class.new( new_assoc_crds, axnames )
225
240
  ret.set_lost_coords( lost_assoc_crds ) if !lost_assoc_crds.empty?
226
241
  ret
227
242
  end
@@ -1,3 +1,4 @@
1
+ # -*- coding: utf-8 -*-
1
2
  require "numru/gphys/varray"
2
3
  require "numru/gphys/varraynetcdf"
3
4
  require "numru/gphys/varraycomposite"
@@ -53,6 +54,15 @@ simulation. The 3rd is not physical and may not be considered as
53
54
  it returns a fancy but sometimes unwanted message if the
54
55
  axis is the time with since field in the form of yyyy-mm-dd....
55
56
 
57
+ ---Axis.join(ary)
58
+ Join multiple axis objects. (simple concatenation without sort)
59
+
60
+ ARGUMENTS
61
+ * ary : Array (or 1D NArray) of Axis objects
62
+
63
+ RETURN VALUE
64
+ * an Axis
65
+
56
66
  ==Instance Methods
57
67
  ---name=(nm)
58
68
  Set a name.
@@ -372,10 +382,10 @@ module NumRu
372
382
  @cell
373
383
  end
374
384
  def cell_center?
375
- @cell && @pos.equal?(@cell_center)
385
+ @cell && @pos.length == @cell_center.length
376
386
  end
377
387
  def cell_bounds?
378
- @cell && @pos.equal?(@cell_bounds)
388
+ @cell && @pos.length == @cell_bounds.length
379
389
  end
380
390
  def bare_index?
381
391
  @bare_index
@@ -420,6 +430,51 @@ module NumRu
420
430
  out
421
431
  end
422
432
 
433
+ # Join multiple axis objects
434
+ # * ary : Array (or 1D NArray) of Axis objects
435
+ def Axis.join(ary)
436
+ ax = ary[0]
437
+ #raise(ArgumentError,"not an Axis") if !ax.is_a?(Axis)
438
+ lens = ary.collect{|ax| ax.length}
439
+ na = ary.length
440
+
441
+ axpool = Hash.new
442
+ cell = ax.cell?
443
+ if cell
444
+ axpool[:celctrs] = ary.collect{|ax| ax.cell_center}
445
+ axpool[:celbnds] = ary.collect{|ax| ax.cell_bounds}
446
+ else
447
+ axpool[:pos] = ary.collect{|ax| ax.pos}
448
+ end
449
+ ax.aux_names.each do |nm|
450
+ axpool[nm] = ary.collect{|ax| ax.get_aux(nm)}
451
+ end
452
+ axpool.each do |nm,vas|
453
+ for i in 1...na
454
+ if ( vas[i-1].length == lens[i-1]+1 and vas[i].length == lens[i]+1 \
455
+ and vas[i-1][-1].val == vas[i][0].val )
456
+ vas[i] = vas[i][1..-1] # exclude overwrap (such as cell_bounds)
457
+ end
458
+ vas = NArray.to_na(vas) if vas.is_a?(Array)
459
+ axpool[nm] = VArrayComposite.new( vas )
460
+ end
461
+ end
462
+
463
+ bidx = ax.bare_index?
464
+ name = ax.name
465
+ jax = Axis.new(cell, bidx, name) # prepare outout (jax: joined axis)
466
+ if cell
467
+ jax.set_cell(axpool.delete(:celctrs), axpool.delete(:celbnds))
468
+ ax.cell_center? ? jax.set_pos_to_center : jax.set_pos_to_bounds
469
+ else
470
+ jax.set_pos(axpool.delete(:pos))
471
+ end
472
+ axpool.each do |nm,va|
473
+ jax.set_aux(nm, va)
474
+ end
475
+ jax
476
+ end
477
+
423
478
  def collect
424
479
  # This method is like ((<copy>)), but it is the 'collect'
425
480
  # iterator for each VArray in self (block required).
@@ -670,11 +725,115 @@ module NumRu
670
725
  end
671
726
 
672
727
  def cut(coord_cutter)
673
- _cut_(false, coord_cutter)
728
+ if cyclic_extendible?
729
+ _cut_cyclic(false, coord_cutter)
730
+ else
731
+ _cut_(false, coord_cutter)
732
+ end
674
733
  end
675
734
  def cut_rank_conserving(coord_cutter)
676
- _cut_(true, coord_cutter)
735
+ if cyclic_extendible?
736
+ _cut_cyclic(true, coord_cutter)
737
+ else
738
+ _cut_(true, coord_cutter)
739
+ end
740
+ end
741
+
742
+ def _cut_cyclic(conserve_rank, coord_cutter)
743
+
744
+ # assume that the coordinates are monotonic (without checking)
745
+
746
+ slicer = Array.new
747
+ ax = self.pos.val
748
+ modulo = self.modulo
749
+ units = self.pos.get_att('units')
750
+ calendar = self.pos.get_att('calendar')
751
+
752
+ case coord_cutter
753
+ when true
754
+ slicer=true
755
+ newax = self
756
+ when Range
757
+ # find the grid points included in the range
758
+ range = coord_cutter
759
+ range_ary = [range.first, range.last]
760
+ r0 = range_ary.min # called xmin in _cut_
761
+ r1 = range_ary.max # called xmax in _cut
762
+ r0 = UNumeric.from_date(r0,units,calendar).val if r0.class <= Date
763
+ r1 = UNumeric.from_date(r1,units,calendar).val if r1.class <= Date
764
+ x0 = ax.min
765
+ x1 = ax.max
766
+ na = ( (r0 - x1)/modulo ).ceil
767
+ nb = ( (r1 - x0)/modulo ).floor
768
+ if na > nb
769
+ raise "Range #{range} does not include any grid point in the axis '#{name}'"
770
+ elsif na==nb
771
+ # no need for cyclic repetition
772
+ n = na
773
+ wh = ( (ax >= r0-n*modulo) & (ax <= r1-n*modulo) ).where
774
+ if wh.length == 0
775
+ raise "Range #{range} does not include any grid point in the axis '#{name}'"
776
+ end
777
+ slicer = wh.min..wh.max
778
+ newax = self[slicer]
779
+ if n != 0
780
+ newax = newax.add( n*modulo ) # shift the axis to match the range
781
+ end
782
+ else # na < nb
783
+ # cyclic repetition needed
784
+ slicer = Array.new
785
+ shift = Array.new
786
+ ns = (na..nb).to_a
787
+ ns.reverse! if ax[0] > ax[-1] # to keep mononicity
788
+ for n in ns
789
+ wh = ( (ax >= r0-n*modulo) & (ax <= r1-n*modulo) ).where
790
+ slicer += wh.to_a
791
+ shift += [n*modulo] * wh.length
792
+ end
793
+ newax = self[slicer].add( shift )
794
+ end
795
+ when Numeric, Date, DateTime
796
+ # find the nearst point
797
+ pt = coord_cutter
798
+ pt = UNumeric.from_date(pt,units,calendar).val if pt.class <= Date
799
+ dx, base = _cyclic_dx(ax-pt, modulo)
800
+ minloc = _minloc_(dx)
801
+ if conserve_rank
802
+ slicer=minloc..minloc
803
+ else
804
+ slicer=minloc
805
+ end
806
+ shift = -base[slicer]
807
+ newax = self[slicer] # Don't worry. It shouldn't be an Axis any more
808
+ when Array, NArray
809
+ # find the nearst points
810
+ ary = coord_cutter
811
+ slicer = Array.new
812
+ shift = Array.new
813
+ ary.each{ |pt|
814
+ pt = UNumeric.from_date(pt,units,calendar).val if pt.class <= Date
815
+ dx, base = _cyclic_dx(ax-pt, modulo)
816
+ minloc = _minloc_(dx)
817
+ slicer.push( minloc )
818
+ # p "****",base,slicer,"#",base[slicer]
819
+ shift.push( -base[minloc] )
820
+ }
821
+ newax = self[slicer].copy
822
+ newax.set_pos( newax.pos + NArray.to_na(shift) )
823
+ else
824
+ raise TypeError, "(#{coord_cutter.inspect}) is not accepted as a coordinate selector"
825
+ end
826
+
827
+ [ newax, slicer ]
677
828
  end
829
+ private :_cut_cyclic
830
+
831
+ def _cyclic_dx(dx, modulo)
832
+ base = modulo*(dx/modulo).round
833
+ dx = ( dx - base ).abs
834
+ [dx, base]
835
+ end
836
+ private :_cyclic_dx
678
837
 
679
838
  def _cut_(conserve_rank, coord_cutter)
680
839
 
@@ -735,7 +894,7 @@ module NumRu
735
894
  # Developper's MEMO: Such a method should be supported in NArray
736
895
  minloc = 0 # initialization
737
896
  for i in 0...(a.length-1) # here, do not assume monotonic
738
- minloc = i+1 if a[i+1]<a[i]
897
+ minloc = i+1 if a[i+1]<a[minloc]
739
898
  end
740
899
  minloc
741
900
  end
@@ -826,6 +985,35 @@ module NumRu
826
985
  @pos.axis_cyclic_extendible?
827
986
  end
828
987
 
988
+ def add(z)
989
+ self.copy.add!(z)
990
+ end
991
+
992
+ # * z : usually a scalar, but can be an array-like object (which
993
+ # may be used in cyclic operations)
994
+ def add!(z)
995
+ @pos += z
996
+
997
+ if @cell
998
+ if cell_bounds?
999
+ if z.respond_to?(:length)
1000
+ @cell_center += z[0..-2]
1001
+ else
1002
+ @cell_center += z
1003
+ end
1004
+ elsif cell_center?
1005
+ if z.respond_to?(:length) # array-like
1006
+ @cell_bounds[0..-2] += z
1007
+ @cell_bounds[-1..-1] += z[-1..-1] # simply use the last one
1008
+ else
1009
+ @cell_bounds += z
1010
+ end
1011
+ end
1012
+ end
1013
+
1014
+ self
1015
+ end
1016
+
829
1017
  ######### private methods ####################################
830
1018
 
831
1019
  private
@@ -840,9 +1028,9 @@ module NumRu
840
1028
  # < define numerical integration / averaging >
841
1029
 
842
1030
  ## 2005/09/12 DEVLOPMENT MEMO by horinout
843
- ## cyclic �ł��傤�ǂP�O���b�h�L�΂����� modulo �ɒB����ꍇ
844
- ## �_�T���v����Z�������^�C�v�ł��T�C�N���b�N�p�d�݂��‚���
845
- ## �悤�ɂ������D
1031
+ ## cyclic でちょうど1グリッド伸ばしたら modulo に達する場合
1032
+ ## 点サンプルやセル中央タイプでもサイクリック用重みをつける
1033
+ ## ようにしたい.
846
1034
 
847
1035
  if( @bare_index )
848
1036
  @integ_weight = NArray.int(@pos.length).fill!(1)
@@ -960,4 +1148,17 @@ if $0 == __FILE__
960
1148
 
961
1149
  axpt.pos.set_att("units","days since 2001-01-01")
962
1150
  p axpt.cut(DateTime.new(2001,1,4,12,0))
1151
+
1152
+ p "## test join"
1153
+ axpt.set_aux("AUX1", xc*0.1 )
1154
+ axpt2 = Axis.new().set_pos(xc+10)
1155
+ axpt2.set_aux("AUX1", xc*0.01 )
1156
+ jax = Axis.join([axpt,axpt2])
1157
+ p jax, jax.name, jax.pos.val.to_a, jax.get_aux("AUX1").val.to_a
1158
+
1159
+ p "## test join (cell)"
1160
+ axcel_c2 = Axis.new(true).set_cell(xc+10,xb+10)
1161
+ axcel_c2.set_pos_to_center
1162
+ jax = Axis.join([axcel_c,axcel_c2])
1163
+ p jax, jax.name, jax.pos.val.to_a, jax.cell_bounds.val.to_a
963
1164
  end
@@ -13,6 +13,8 @@ require 'numru/derivative'
13
13
  * First derivative (2nd Order difference use three point.)
14
14
  * ((<cderiv>))
15
15
  * First derivative (using center difference method)
16
+ * ((<deriv2d>))
17
+ * 2nd derivative
16
18
 
17
19
  =module NumRu::GPhys::Derivative
18
20
 
@@ -70,6 +72,15 @@ Module functions of Derivative Operater for GPhys.
70
72
  RETURN VALUE
71
73
  * a GPhys
72
74
 
75
+ ---deriv2nd(gp, dim_or_dimname, bc=LINEAR_EXT, altcoord=nil)
76
+
77
+ 2nd Derivate (({gp})) respect to (({dim})) th or (({dimname})) dimension
78
+ covering non-uniform grids. Based on:
79
+ ( (z_{i+1}-z_{i})/(x_{i+1}-x_{i}) - (z_{i}-z_{i-1})/(x_{i}-x_{i-1}) )
80
+ / ((x_{i+1}-x_{i-1})/2)
81
+
82
+ See ((<cderiv>)) for usage.
83
+
73
84
  =end
74
85
  ############################################################
75
86
 
@@ -70,6 +70,72 @@
70
70
 
71
71
  See the manual of ((|GPhys::IO.each_along_dims_write|)).
72
72
 
73
+ ---GPhys.join_md_nocheck(gpnary)
74
+ Join multiple GPhys objects that are ordered perfectly in a NArray.
75
+
76
+ LIMITATION (as of 2013-03-04)
77
+ * joining assoc_coords is yet to be supported; Currently
78
+ assoc_coords are ignored if any.
79
+
80
+ ARGUMENT
81
+ * gpnarray [NArray of GPhys] having the same rank with that of
82
+ its component GPhys objects. multiple GPhys objects are joined
83
+ along the dimension with multiple elements (the order is kept).
84
+
85
+ RETURN VALUE
86
+ * a GPhys
87
+
88
+ ---GPhys.join_md(gpnary)
89
+ Join multiple GPhys objects (ordered in a NArray).
90
+
91
+ Like GPhys.join_md_nocheck but it supports insersion
92
+ of omitted 1-element dimensions and transpose for
93
+ gpnary (the input NArray). It means that the rank of gpnary
94
+ can be smaller than that of its compoent GPhys objects, and
95
+ the order of dimensions can be arbitrary. Also,
96
+ the order of coordinate values along each dimension does not
97
+ have to be monotonic; the method supports sorting and spliting
98
+ along dimensions. For example, if gpnary == NArray.object(2):[gp0, gp1],
99
+ where the first object gp0 has the 1st coordinate [0,1,7,8] and
100
+ the second object gp1 has the 1st coordinate [3,4,5,6],
101
+ gpnary is restructured as [ gp0[0..1,false], gp1, gp0[2..3,false] ],
102
+ and join is made by using GPhys.join_md_nocheck.
103
+
104
+ This method is generally faster than GPhys.join unless the split
105
+ is one-dimensional.
106
+
107
+ ARGUMENT
108
+ * gpnarray [NArray of GPhys]
109
+
110
+ RETURN VALUE
111
+ * a GPhys
112
+
113
+ ---GPhys.join(gpary)
114
+ Join multiple GPhys objects (no need for any pre-ordering).
115
+
116
+ ARGUMENT
117
+ * gpnarray [Array (or 1D NArray) of GPhys]
118
+
119
+ RETURN VALUE
120
+ * a GPhys
121
+
122
+ ---GPhys.concat(gpary, axis_or_ary, name=nil, attr=nil)
123
+ Concatenate an Array (or 1D NArray) of GPhys objects
124
+ along the new dimension specified by the 2nd to 4th arguments.
125
+ The rank of the result (a GPhys) is one plus the rank of
126
+ the GPhys objects.
127
+
128
+ ARGUMENTS
129
+ * gpary [1D NArray or Array of GPhys]
130
+ * axis_or_ary [an Axis or a 1D NArray or Array of floats]
131
+ * name [String; optional] name of the coordinate;
132
+ needed if axis_or_ary is not an Axis.
133
+ * attr [Hash; optional] attributes of the coordinate;
134
+ used if axis_or_ary is not an Axis.
135
+
136
+ RETURN VALUE
137
+ * a GPhys
138
+
73
139
  ==Instance Methods
74
140
  ---data
75
141
  Returns the data object
@@ -87,8 +153,16 @@
87
153
  * a Grid
88
154
 
89
155
  NOTE
90
- * There is a PROTECTED method (('grid')), which returns
91
- the grid object without duplicating.
156
+ * (('grid')) does not make a copy.
157
+
158
+ ---grid
159
+ Returns the grid object without copying.
160
+
161
+ RETURN VALUE
162
+ * a Grid
163
+
164
+ NOTE
165
+ * Use (('grid_copy')) to avoid side effects
92
166
 
93
167
  ---copy
94
168
  Make a deep clone onto memory
@@ -436,7 +510,7 @@
436
510
  ---shape
437
511
  Aliased to ((<shape_current>))
438
512
 
439
- ---cyclic_ext(dim_or_dimname, modulo)
513
+ ---cyclic_ext(dim_or_dimname)
440
514
  Extend a dimension cyclically.
441
515
 
442
516
  The extension is done only when adding one grid point makes a full circle.
@@ -446,7 +520,6 @@
446
520
 
447
521
  ARGUMENTS
448
522
  * dim_or_dimname (String or Integer)
449
- * modulo (Numeric)
450
523
 
451
524
  RETURN VALUE
452
525
  * a GPhys (possibly self)
@@ -481,6 +554,7 @@ These methods returns a NArray (not a GPhys).
481
554
  require "numru/gphys/grid"
482
555
  require "numru/misc/md_iterators"
483
556
  require "numru/gphys/narray_ext"
557
+ require "numru/gphys/mdstorage" # for GPhys.join
484
558
 
485
559
  module NumRu
486
560
  class GPhys
@@ -488,8 +562,8 @@ module NumRu
488
562
  include NumRu::Misc::MD_Iterators
489
563
 
490
564
  def initialize(grid, data)
491
- raise ArgumentError,"1st arg not a Grid" if ! grid.is_a?(Grid)
492
- raise ArgumentError,"2nd arg not a VArray" if ! data.is_a?(VArray)
565
+ #raise ArgumentError,"1st arg not a Grid" if ! grid.is_a?(Grid)
566
+ #raise ArgumentError,"2nd arg not a VArray" if ! data.is_a?(VArray)
493
567
  if ( grid.shape_current != data.shape_current )
494
568
  raise ArgumentError, "Shapes of grid and data do not agree. " +
495
569
  "#{grid.shape_current.inspect} vs #{data.shape_current.inspect}"
@@ -499,7 +573,7 @@ module NumRu
499
573
  end
500
574
 
501
575
  attr_reader :grid, :data
502
- protected :grid
576
+ ###protected :grid # protection is lifted
503
577
 
504
578
  def grid_copy
505
579
  # deep clone of the grid
@@ -508,11 +582,11 @@ module NumRu
508
582
 
509
583
  def copy
510
584
  # deep clone onto memory
511
- GPhys.new( @grid.copy, @data.copy )
585
+ self.class.new( @grid.copy, @data.copy )
512
586
  end
513
587
 
514
588
  def inspect
515
- "<GPhys grid=#{@grid.inspect}\n data=#{@data.inspect}>"
589
+ "<#{self.class} grid=#{@grid.inspect}\n data=#{@data.inspect}>"
516
590
  end
517
591
 
518
592
  def name
@@ -571,7 +645,7 @@ module NumRu
571
645
  # * @grid is shared with self (no duplication)
572
646
  # Thus, use GPhys#copy to separate all sub-objects (deep clone).
573
647
  data = @data.convert_units(to)
574
- GPhys.new(@grid, data)
648
+ self.class.new(@grid, data)
575
649
  end
576
650
 
577
651
  def long_name
@@ -588,7 +662,7 @@ module NumRu
588
662
  else
589
663
  slicer = __rubber_expansion( slicer )
590
664
  end
591
- GPhys.new( @grid[*slicer], @data[*slicer] )
665
+ self.class.new( @grid[*slicer], @data[*slicer] )
592
666
  end
593
667
 
594
668
  def []=(*args)
@@ -621,17 +695,17 @@ module NumRu
621
695
  acspec = Hash.new
622
696
  acnms.each{|nm| acspec[nm] = spec.delete(nm)}
623
697
  grid, sl = @grid.cut_assoccoord(acspec)
624
- gphys = GPhys.new( grid, self.data[*sl] )
698
+ gphys = self.class.new( grid, self.data[*sl] )
625
699
  else
626
700
  gphys = self
627
701
  end
628
702
  newgrid, slicer = gphys.grid.cut( *args )
629
- GPhys.new( newgrid, gphys.data[ *slicer ] )
703
+ self.class.new( newgrid, gphys.data[ *slicer ] )
630
704
  end
631
705
 
632
706
  def cut_rank_conserving( *args )
633
707
  newgrid, slicer = @grid.cut_rank_conserving( *args )
634
- GPhys.new( newgrid, @data[ *slicer ] )
708
+ self.class.new( newgrid, @data[ *slicer ] )
635
709
  end
636
710
 
637
711
  Axis.defined_operations.each do |method|
@@ -639,7 +713,7 @@ module NumRu
639
713
  def #{method}(dim_or_dimname, *extra_args)
640
714
  vary, grid = @grid.#{method}(@data, dim_or_dimname, *extra_args)
641
715
  if grid
642
- GPhys.new( grid, vary )
716
+ self.class.new( grid, vary )
643
717
  else
644
718
  vary # scalar
645
719
  end
@@ -725,21 +799,11 @@ module NumRu
725
799
 
726
800
  def coerce(other)
727
801
  case other
728
- when Numeric
729
- ##na_other = self.data.val.fill(other) # Not efficient!
730
- va_other, = self.data.coerce(other)
731
- c_other = GPhys.new( @grid[ *([0..0]*self.rank) ],
732
- va_other.reshape!( *([1]*self.rank) ) )
733
- c_other.put_att('units',nil) # should be treated as such, not 1
734
- when Array, NArray
735
- va_other, = self.data.coerce(other)
736
- c_other = GPhys.new( @grid, va_other )
737
- c_other.put_att('units',nil) # should be treated as such, not 1
738
- when VArray
739
- c_other = GPhys.new( @grid, other )
740
- else
741
- raise "Cannot coerse #{other.class}"
742
- end
802
+ when Numeric, Array, NArrayMiss
803
+ c_other = UNumeric::Num2Coerce.new( other )
804
+ else
805
+ raise "Cannot coerse #{other.class}"
806
+ end
743
807
  [c_other, self]
744
808
  end
745
809
 
@@ -776,9 +840,9 @@ module NumRu
776
840
  def shape_coerce_full(other)
777
841
  o, s = shape_coerce(other)
778
842
  if o.length < s.length
779
- o = GPhys.new( s.grid, o + NArray.new(o.typecode,*s.shape) )
843
+ o = self.class.new( s.grid, o + NArray.new(o.typecode,*s.shape) )
780
844
  elsif o.length > s.length
781
- s = GPhys.new( o.grid, s + NArray.new(s.typecode,*o.shape) )
845
+ s = self.class.new( o.grid, s + NArray.new(s.typecode,*o.shape) )
782
846
  end
783
847
  [o, s]
784
848
  end
@@ -786,17 +850,17 @@ module NumRu
786
850
  def transpose(*dims)
787
851
  grid = @grid.transpose(*dims)
788
852
  data = @data.transpose(*dims)
789
- GPhys.new( grid, data )
853
+ self.class.new( grid, data )
790
854
  end
791
855
 
792
856
  for f in VArray::Math_funcs
793
857
  eval <<-EOS, nil, __FILE__, __LINE__+1
794
858
  #def GPhys.#{f}(gphys)
795
859
  # raise ArgumentError, "Not a GPhys" if !gphys.is_a?(GPhys)
796
- # GPhys.new( gphys.grid, VArray.#{f}(gphys.data) )
860
+ # self.class.new( gphys.grid, VArray.#{f}(gphys.data) )
797
861
  #end
798
862
  def #{f}(*arg)
799
- GPhys.new( self.grid, self.data.#{f}(*arg) )
863
+ self.class.new( self.grid, self.data.#{f}(*arg) )
800
864
  end
801
865
  EOS
802
866
  end
@@ -813,18 +877,18 @@ module NumRu
813
877
  vary = myself.data#{f} other
814
878
  newgrid = myself.grid_copy
815
879
  end
816
- GPhys.new( newgrid, vary )
880
+ self.class.new( newgrid, vary )
817
881
  else
818
882
  if other.respond_to?(:grid) #.is_a?(GPhys)
819
883
  vary = myself#{f} other.data
820
884
  else
821
885
  vary = myself#{f} other
822
886
  end
823
- GPhys.new( other.grid.copy, vary )
887
+ self.class.new( other.grid.copy, vary )
824
888
  end
825
889
  else
826
890
  vary = self.data#{f} other
827
- GPhys.new( @grid.copy, vary )
891
+ self.class.new( @grid.copy, vary )
828
892
  end
829
893
  end
830
894
  EOS
@@ -841,14 +905,14 @@ module NumRu
841
905
  eval <<-EOS, nil, __FILE__, __LINE__+1
842
906
  def #{f}
843
907
  vary = #{f.delete("@")} self.data
844
- GPhys.new( @grid.copy, vary )
908
+ self.class.new( @grid.copy, vary )
845
909
  end
846
910
  EOS
847
911
  end
848
912
  for f in VArray::NArray_type1_methods
849
913
  eval <<-EOS, nil, __FILE__, __LINE__+1
850
914
  def #{f}(*args)
851
- GPhys.new( self.grid.copy, self.data.#{f}(*args) )
915
+ self.class.new( self.grid.copy, self.data.#{f}(*args) )
852
916
  end
853
917
  EOS
854
918
  end
@@ -862,12 +926,16 @@ module NumRu
862
926
  for f in VArray::NArray_type3_methods
863
927
  eval <<-EOS, nil, __FILE__, __LINE__+1
864
928
  def #{f}(*args)
929
+ arg_hash = args.pop if args[-1].is_a?(Hash)
930
+ # arg_hash: to support "min_count" in NArrayMiss
865
931
  args = args.collect{|i| @grid.dim_index(i)}
866
- result = self.data.#{f}(*args)
932
+ args.push( arg_hash ) if arg_hash
933
+ result = self.data.#{f}(*args)
867
934
  if Numeric===result || UNumeric===result
868
935
  result
869
936
  else
870
- GPhys.new( self.grid.delete_axes(args, "#{f}"), result )
937
+ args.pop if args[-1].is_a?(Hash)
938
+ self.class.new( self.grid.delete_axes(args, "#{f}"), result )
871
939
  end
872
940
  end
873
941
  EOS
@@ -878,13 +946,11 @@ module NumRu
878
946
  end
879
947
  alias shape shape_current
880
948
 
881
- def cyclic_ext(dim_or_dimname, modulo)
949
+ # Old version of cyclic_ext
950
+ def cyclic_ext_with_modulo(dim_or_dimname, modulo)
882
951
  # Cyclic extention to push the first element after the last element
883
952
  # if appropriate.
884
953
 
885
- # <<developper's memo by horinout, 2005/01>>
886
- # in future modulo should be read based on conventions if nil
887
-
888
954
  vx = coord(dim_or_dimname)
889
955
  return self if vx.length <= 1
890
956
 
@@ -907,6 +973,27 @@ module NumRu
907
973
  end
908
974
  end
909
975
 
976
+ def cyclic_ext(dim_or_dimname)
977
+ # Cyclic extention to push the first element after the last element
978
+ # if appropriate. (by using the cut method)
979
+
980
+ ax = axis(dim_or_dimname)
981
+ if ax.cyclic_extendible?
982
+ modulo = ax.modulo
983
+ v = ax.pos.val
984
+ v0 = v[0]
985
+ eps = 1e-2/ax.length
986
+ if v0 < v[-1] # increasing
987
+ v1 = v0 + modulo*(1+eps)
988
+ else
989
+ v1 = v0 - modulo*(1+eps)
990
+ end
991
+ return self.cut(ax.name=>v0..v1)
992
+ else
993
+ return self
994
+ end
995
+ end
996
+
910
997
  def self.each_along_dims(gphyses, loopdims)
911
998
  if !gphyses.is_a?(Array)
912
999
  gphyses = [gphyses] # put in an Array (if a single GPhys)
@@ -1000,7 +1087,7 @@ module NumRu
1000
1087
  else
1001
1088
  vary = VArray.new(NArray.new(vtst.typecode, *grid.shape), rs.data)
1002
1089
  end
1003
- results_whole.push( GPhys.new( grid, vary ) )
1090
+ results_whole.push( self.new( grid, vary ) )
1004
1091
  end
1005
1092
  end
1006
1093
  for j in 0...results.length
@@ -1024,6 +1111,310 @@ module NumRu
1024
1111
  @grid = ary[1]
1025
1112
  end
1026
1113
 
1114
+ ####### join multiple GPhys objects #######
1115
+
1116
+ def GPhys.join_md_nocheck(gpnary)
1117
+ #< check >
1118
+ if !gpnary.is_a?(NArray)
1119
+ raise(ArgumentError,"Input must be an NArray of GPhys")
1120
+ end
1121
+ rank = gpnary.rank
1122
+
1123
+ #< axes >
1124
+ gp0 = gpnary[0]
1125
+
1126
+ axes = Array.new
1127
+ for d in 0...rank
1128
+ if gpnary.shape[d] > 1 # --> join axes
1129
+ sel = [0]*d + [true] + [0]*(rank-d-1) # [0,..0,true,0,...0]
1130
+ axs = gpnary[*sel].collect{|gp| gp.axis(d)} # axes along d-th dim
1131
+ ax = Axis.join(axs)
1132
+ else
1133
+ ax = gp0.axis(d)
1134
+ end
1135
+ axes.push(ax)
1136
+ end
1137
+
1138
+ #< grid >
1139
+ grid = Grid.new(*axes)
1140
+ if gp0.assoc_coords
1141
+ assoc_coords = gp0.assoccoordnames.collect do |aname|
1142
+ GPhys.join( gpnary.collect{|gp| gp.assoc_coord_gphys(aname)}, true )
1143
+ end
1144
+ grid.set_assoc_coords(assoc_coords)
1145
+ end
1146
+
1147
+ #< data >
1148
+ data = VArrayComposite.new( gpnary.collect{|gp| gp.data} )
1149
+
1150
+ #< new gphys >
1151
+ GPhys.new(grid, data)
1152
+ end
1153
+
1154
+ def GPhys.join_md(gpnary)
1155
+ #< Check >
1156
+
1157
+ if !gpnary.is_a?(NArray)
1158
+ raise(ArgumentError,"Input must be an NArray of GPhys")
1159
+ end
1160
+ arank = gpnary.rank # rank of the input NArray
1161
+ ashape = gpnary.shape
1162
+ rank = gpnary[0].rank
1163
+
1164
+ #< Reshape and transpose gpnary if needed >
1165
+
1166
+ # / find dimmensions to join /
1167
+ dimmap = Array.new
1168
+ for i in 0...arank
1169
+ if ashape[i] > 1 # join needed
1170
+ sel = Array.new(arank, 0) # [0,0,...,0]
1171
+ gp0 = gpnary[ *sel ]
1172
+ sel[i] = 1
1173
+ gp1 = gpnary[ *sel ] # [0,..,0,1,0,...,0]
1174
+ for d in 0...rank
1175
+ c0 = gp0.coord(d)[0]
1176
+ c1 = gp1.coord(d)[0]
1177
+ if c0.val != c1.convert_units(c0.units).val
1178
+ dimmap[i] = d # dimension to join (found)
1179
+ break
1180
+ end
1181
+ raise("Corresponding dim is not found for #{i}") if d==rank-1
1182
+ end
1183
+ else
1184
+ dimmap[i] = nil # no need to join this dimension
1185
+ end
1186
+ end
1187
+ if (x=dimmap-[nil]).length != x.uniq.length
1188
+ raise "Dimensions to join cannot be determined uniquely"
1189
+ end
1190
+
1191
+ # / "solo" dimensions (dimensions no need to join) /
1192
+ sdims = (0...rank).collect{|d| d} - dimmap
1193
+ for i in 0...arank
1194
+ if dimmap[i].nil?
1195
+ dimmap[i] = sdims.shift # assign dimensions orderly to
1196
+ # minimize the need to transpose
1197
+ end
1198
+ end
1199
+ sdims.each do |d|
1200
+ dimmap.insert(d,d) # assign dimensions orderly to
1201
+ gpnary = gpnary.newdim(d) # minimize the need to transpose
1202
+ end
1203
+ # now, gpnary.rank == rank
1204
+
1205
+ # / transpose gpnary if needed /
1206
+ if dimmap != (0...rank).collect{|d| d}
1207
+ imap = Array.new
1208
+ dimmap.each_with_index do |d,j|
1209
+ imap[j] = d
1210
+ end
1211
+ gpnary = gpnary.transpose(*imap)
1212
+ end
1213
+
1214
+ #< Sort along dimensions to join >
1215
+ gpnary = __sort_gpnary(gpnary)
1216
+
1217
+ #< Join! >
1218
+ self.join_md_nocheck(gpnary)
1219
+ end
1220
+
1221
+ # Join multiple GPhys objects (not need for any pre-ordering).
1222
+ #
1223
+ # ARGUMENT
1224
+ # * gpnarray [Array (or 1D NArray) of GPhys]
1225
+ #
1226
+ def GPhys.join(gpary, ignore_overlap=false)
1227
+
1228
+ #< initialization with the first GPhys object >
1229
+
1230
+ gp = gpary[0]
1231
+ rank = gp.rank
1232
+ gpstore = MDStorage.new(rank)
1233
+ gpstore[ *Array.new(rank, 0) ] = gp # first element
1234
+ x0s = (0...rank).collect{|d|
1235
+ pos = gp.axis(d).pos
1236
+ x0 = UNumeric[ pos.val[0], pos.units ]
1237
+ [ x0 ] # first values of each coordinate
1238
+ }
1239
+
1240
+ #< scan the coordiantes of the remaining GPhys objects >
1241
+ for k in 1...gpary.length
1242
+ gp = gpary[k]
1243
+ idx = Array.new
1244
+ for d in 0...rank
1245
+ pos = gp.axis(d).pos
1246
+ x0 = UNumeric[ pos.val[0], pos.units ]
1247
+ i = x0s[d].index(x0)
1248
+ if i.nil?
1249
+ x0s[d].push(x0)
1250
+ i = x0s[d].length-1
1251
+ end
1252
+ idx.push(i)
1253
+ end
1254
+ gpstore[*idx] = gp
1255
+ end
1256
+
1257
+ if !ignore_overlap && gpstore.count_non_nil != gpary.length
1258
+ raise(ArgumentError,"Cannot uniquely locate one or more objects; some overlap in the grids?")
1259
+ end
1260
+
1261
+ gpnary = gpstore.to_na
1262
+
1263
+ #< Sort along dimensions to join >
1264
+ gpnary = __sort_gpnary(gpnary)
1265
+
1266
+ #< Join! >
1267
+ self.join_md_nocheck(gpnary)
1268
+ end
1269
+
1270
+ def GPhys.concat(gpary, axis_or_ary, name=nil, attr=nil)
1271
+ #< interpret gpary (1st arg) >
1272
+ gpary = NArray.to_na(gpary) if gpary.is_a?(Array)
1273
+ if !gpary.is_a?(NArray) || gpary.rank != 1
1274
+ raise(ArgumentError,"1st arg must be a 1D NArray or Array of GPhys")
1275
+ end
1276
+ len = gpary.length
1277
+
1278
+ #< interpret axis_or_ary (2nd arg) and make an Axis if not >
1279
+ case axis_or_ary
1280
+ when Axis
1281
+ ax = axis_or_ary
1282
+ if ax.length != len
1283
+ raise(ArgumentError,"length mismatch #{len} vs #{ax.length}")
1284
+ end
1285
+ else
1286
+ ary = axis_or_ary # must be an NArray or Array
1287
+ ary = NArray.to_na(ary).to_f if ary.is_a?(Array)
1288
+ if !ary.is_a?(NArray) || ary.rank != 1
1289
+ raise(ArgumentError,
1290
+ "If not an Axis, 2nd arg must be 1D NArray or Array of float")
1291
+ end
1292
+ if ary.length != len
1293
+ raise(ArgumentError,"length mismatch #{len} vs #{ary.length}")
1294
+ end
1295
+ if name.nil?
1296
+ raise(ArgumentError,
1297
+ "3rd arg (name) is needed if the 2nd arg is not an Axis")
1298
+ end
1299
+ va = VArray.new(ary, attr, name)
1300
+ ax = Axis.new().set_pos(va)
1301
+ end
1302
+
1303
+ #< new grid >
1304
+ grid = gpary[0].grid.insert_axis(-1,ax) # insert_axis: non-destructive
1305
+
1306
+ #< join VArrays >
1307
+ ds = gpary.collect{|gp| gp.data}
1308
+ gpary[0].rank.times{ds.newdim!(0)} # for VArrayComposite.new
1309
+ data = VArrayComposite.new(ds)
1310
+
1311
+ #< result >
1312
+ GPhys.new(grid, data)
1313
+ end
1314
+
1315
+ ############## < private class methods > ##############
1316
+ def GPhys::__sort_gpnary(gpnary)
1317
+ #< Sort along dimensions to join >
1318
+
1319
+ shape = gpnary.shape
1320
+ rank = shape.length
1321
+ for d in 0...rank
1322
+ n = shape[d]
1323
+ if n > 1 # --> d is a dimesnion to join; possibly need to sort
1324
+ sel = Array.new(rank, 0) # [0,0,...,0]
1325
+ xs = Array.new # will be [ [pos, k-th obj, j-th elem], ... ]
1326
+ xunits = gpnary[0].axis(d).pos.units
1327
+ for k in 0...n
1328
+ sel[d] = k
1329
+ axis = gpnary[*sel].axis(d)
1330
+ if axis.pos.units != xunits
1331
+ pos = axis.pos.convert_units(xunits)
1332
+ if !axis.cell?
1333
+ axis.set_pos(pos)
1334
+ else
1335
+ if axis.cell_center?
1336
+ bds = axis.cell_bounds.convert_units(xunits)
1337
+ axis.set_cell(pos,bds)
1338
+ else
1339
+ ctrs = axis.cell_center.convert_units(xunits)
1340
+ axis.set_cell(ctr,pos)
1341
+ end
1342
+ end
1343
+ end
1344
+ x = axis.pos.val
1345
+ for i in 0...x.length
1346
+ xs.push( {:pos=>x[i], :kobj=>k, :idx=>i} )
1347
+ end
1348
+ end
1349
+
1350
+ if ( gpnary[0].axis(d).length == 1 or # -> cannot determine order
1351
+ xs[0][:pos] <= xs[1][:pos] ) # -> increasing
1352
+ xs.sort!{|a,b| a[:pos] <=> b[:pos]} # increasing order
1353
+ else
1354
+ xs.sort!{|a,b| b[:pos] <=> a[:pos]} # decreasing order
1355
+ end
1356
+
1357
+ x0 = xs.shift
1358
+ xconf = [ { :kobj=>x0[:kobj], :ids=>[x0[:idx]] } ]
1359
+ ic = 0
1360
+ xs.each do |x|
1361
+ if x[:kobj] == xconf[ic][:kobj] # same obj
1362
+ xconf[ic][:ids].push(x[:idx])
1363
+ else # -> new obj
1364
+ ic += 1
1365
+ xconf[ic] = {:kobj=>x[:kobj], :ids=>[x[:idx]] }
1366
+ end
1367
+ end
1368
+ if xconf.length == n
1369
+ # At most, only reodering is needed
1370
+ gpnary2 = gpnary.clone # to replace gpnary
1371
+ selj = Array.new(rank, true) # [true, true,...]
1372
+ selk = Array.new(rank, true) # [true, true,...]
1373
+ for j in 0...xconf.length
1374
+ if j != (k=xconf[j][:kobj]) # need to reorder the dimension d
1375
+ selj[d] = j
1376
+ selk[d] = k
1377
+ gpnary2[*selj] = gpnary[*selk]
1378
+ end
1379
+ end
1380
+ gpnary = gpnary2
1381
+ else
1382
+ # Need to divide some object(s)
1383
+ shape2 = shape.clone
1384
+ n2 = xconf.length
1385
+ shape2[d] = n2
1386
+ gpnary2 = NArray.object(*shape2) # to replace gpnary
1387
+ selj = Array.new(rank, true) # [true, true,...]
1388
+ selk = Array.new(rank, true) # [true, true,...]
1389
+ for j in 0...xconf.length
1390
+ selj[d] = j
1391
+ selk[d] = xconf[j][:kobj]
1392
+ ids = xconf[j][:ids] # indices to subset d-th D of gpnary elem
1393
+ regular = true
1394
+ for b in 0...ids.length-1
1395
+ if ids[b+1] - ids[b+1] != 1
1396
+ regular = false
1397
+ break
1398
+ end
1399
+ end
1400
+ if regular
1401
+ ids = ids[0]..ids[-1]
1402
+ else
1403
+ #ids = NArray.to_na(ids)
1404
+ end
1405
+ seld = Array.new(rank, true) # [true, true,...]
1406
+ seld[d] = ids
1407
+ gpnary2[*selj] = gpnary[*selk].collect{|g| g[*seld]}
1408
+ end
1409
+ gpnary = gpnary2
1410
+ end
1411
+ end
1412
+
1413
+ end
1414
+ gpnary
1415
+ end
1416
+ private_class_method :__sort_gpnary
1417
+
1027
1418
  ############## < private methods > ##############
1028
1419
 
1029
1420
  private
@@ -1182,8 +1573,10 @@ if $0 == __FILE__
1182
1573
  p gpz3_cext.coord(0).val, gpz3_cext.val
1183
1574
 
1184
1575
  print "cyclic extention if appropriate\n"
1185
- gpz3_cext = gpz3.cyclic_ext(0,10.0)
1576
+ gpz3.axis(0).pos.set_att("modulo",[10.0])
1577
+ gpz3_cext = gpz3.cyclic_ext(0)
1186
1578
  p gpz3_cext.coord(0).val, gpz3_cext.val
1579
+ gpz3.axis(0).pos.del_att("modulo")
1187
1580
 
1188
1581
  print "axis to gphys\n"
1189
1582
  ax = gpz3.axis(1)
@@ -1220,4 +1613,102 @@ if $0 == __FILE__
1220
1613
  g = Marshal.load(mar)
1221
1614
  p g
1222
1615
 
1616
+ # test join
1617
+ p "## testing join_md_nocheck..."
1618
+ nx = 4
1619
+ ny = 3
1620
+ nz = 2
1621
+ vx0 = VArray.new( NArray.float(nx).indgen! ).rename("x")
1622
+ vy0 = VArray.new( NArray.float(ny).indgen! + 0.5 ).rename("y")
1623
+ vyb0 = VArray.new( NArray.float(ny+1).indgen! ).rename("yb")
1624
+ vx1 = VArray.new( NArray.float(nx).indgen! + nx ).rename("x")
1625
+ vy1 = VArray.new( NArray.float(ny).indgen! + (ny+0.5) ).rename("y")
1626
+ vyb1 = VArray.new( NArray.float(ny+1).indgen! + ny ).rename("yb")
1627
+ xax0 = Axis.new().set_pos(vx0)
1628
+ yax0 = Axis.new(true).set_cell(vy0,vyb0).set_pos_to_center
1629
+ xax1 = Axis.new().set_pos(vx1)
1630
+ yax1 = Axis.new(true).set_cell(vy1,vyb1).set_pos_to_center
1631
+ vz = VArray.new( NArray.float(nz).indgen! ).rename("z")
1632
+ zax = Axis.new().set_pos(vz)
1633
+ v = VArray.new( NArray.float(nx,ny,nz).indgen!, nil, "V" )
1634
+ gp00 = GPhys.new( Grid.new(xax0, yax0, zax), v )
1635
+ gp10 = GPhys.new( Grid.new(xax1, yax0, zax), v+100 )
1636
+ gp01 = GPhys.new( Grid.new(xax0, yax1, zax), v+200 )
1637
+ gp11 = GPhys.new( Grid.new(xax1, yax1, zax), v+300 )
1638
+ x = NArray.float(nx,ny).random!
1639
+ =begin
1640
+ gp00.set_assoc_coords([GPhys.new(Grid.new(xax0,yax0),VArray.new(x,nil,"A"))])
1641
+ gp10.set_assoc_coords([GPhys.new(Grid.new(xax1,yax0),VArray.new(x,nil,"A"))])
1642
+ gp01.set_assoc_coords([GPhys.new(Grid.new(xax0,yax1),VArray.new(x,nil,"A"))])
1643
+ gp11.set_assoc_coords([GPhys.new(Grid.new(xax1,yax1),VArray.new(x,nil,"A"))])
1644
+ =end
1645
+ gpnary = NArray.to_na( [[ [gp00,gp10], [gp01,gp11] ]] )
1646
+ gpu = GPhys.join_md_nocheck(gpnary)
1647
+ p "#",gpu, gpu.coord(0).val, gpu.coord(1).val, gpu.axis(1).cell_bounds.val
1648
+ p "#",gpu.val
1649
+
1650
+ p "## testing join_md..."
1651
+ gpnary = NArray.to_na( [ [gp00,gp01], [gp10,gp11] ] )
1652
+ gpu = GPhys.join_md(gpnary)
1653
+ p gpu.copy, gpu.val
1654
+
1655
+ gpnary = NArray.to_na( [gp00,gp01] )
1656
+ gpu = GPhys.join_md(gpnary)
1657
+ p gpu.copy, gpu.val
1658
+
1659
+ gpnary = NArray.to_na( [gp10,gp00] )
1660
+ gpu = GPhys.join_md(gpnary)
1661
+ p gpu.copy, gpu.val
1662
+
1663
+ gp00.coord(0)[0..1] = NArray.to_na([1, 2])
1664
+ gp00.coord(0)[2..3] = NArray.to_na([7, 8])
1665
+ gp10.coord(0)[0..3] = NArray.to_na([3,4,5,6])
1666
+ gpnary = NArray.to_na( [gp00,gp10] )
1667
+ gpu = GPhys.join_md(gpnary)
1668
+ p gpu.copy, gpu.val
1669
+
1670
+ ans = NArray.to_na(
1671
+ [ [ [ 0.0, 1.0, 100.0, 101.0, 102.0, 103.0, 2.0, 3.0 ],
1672
+ [ 4.0, 5.0, 104.0, 105.0, 106.0, 107.0, 6.0, 7.0 ],
1673
+ [ 8.0, 9.0, 108.0, 109.0, 110.0, 111.0, 10.0, 11.0 ] ],
1674
+ [ [ 12.0, 13.0, 112.0, 113.0, 114.0, 115.0, 14.0, 15.0 ],
1675
+ [ 16.0, 17.0, 116.0, 117.0, 118.0, 119.0, 18.0, 19.0 ],
1676
+ [ 20.0, 21.0, 120.0, 121.0, 122.0, 123.0, 22.0, 23.0 ] ] ] )
1677
+ if gpu.val == ans
1678
+ p "test ok"
1679
+ else
1680
+ raise "test failed"
1681
+ end
1682
+
1683
+ p "## testing join..."
1684
+ gpu = GPhys.join( [gp11,gp10,gp01,gp00] )
1685
+ p gpu.copy, gpu.val
1686
+ if gpu.val[true,0..2,true] == ans and gpu.val[true,3..5,true] == ans+200
1687
+ p "test ok"
1688
+ else
1689
+ raise "test failed"
1690
+ end
1691
+
1692
+ p "## testing to confirm the failure of join..."
1693
+ begin
1694
+ gpu = GPhys.join( [gp11,gp11+0.1,gp01,gp00] )
1695
+ # overlap in grids: cannot not uniquely join
1696
+ rescue ArgumentError
1697
+ puts "test ok: confirmed the expected failure."
1698
+ end
1699
+
1700
+ p "## testing concat..."
1701
+ gpary = [gp00[0..2,0..1,0], gp00[0..2,0..1,0]+100]
1702
+ gpu = GPhys.concat( gpary, [0.0, 1.0], "time", {"units"=>"days"} )
1703
+ ans = NArray.to_na( [ [ [ 0.0, 1.0, 2.0 ],
1704
+ [ 4.0, 5.0, 6.0 ] ],
1705
+ [ [ 100.0, 101.0, 102.0 ],
1706
+ [ 104.0, 105.0, 106.0 ] ] ] )
1707
+ if gpu.coord(2).name == "time" && gpu.val == ans
1708
+ p "test ok"
1709
+ else
1710
+ raise "test failed"
1711
+ end
1712
+
1223
1713
  end
1714
+