gentooboontoo-gphys 0.6.1.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (401) hide show
  1. checksums.yaml +7 -0
  2. data/ChangeLog +1255 -0
  3. data/README +32 -0
  4. data/bin/gdir_client +9 -0
  5. data/bin/gdir_server +123 -0
  6. data/bin/gpaop +134 -0
  7. data/bin/gpcat +140 -0
  8. data/bin/gpcut +94 -0
  9. data/bin/gpedit +196 -0
  10. data/bin/gplist +67 -0
  11. data/bin/gpmath +114 -0
  12. data/bin/gpmaxmin +127 -0
  13. data/bin/gpprint +57 -0
  14. data/bin/gpvect +657 -0
  15. data/bin/gpview +603 -0
  16. data/bin/grads2nc_with_gphys +56 -0
  17. data/doc/attribute.html +19 -0
  18. data/doc/attributenetcdf.html +15 -0
  19. data/doc/axis.html +368 -0
  20. data/doc/coordmapping.html +111 -0
  21. data/doc/coordtransform.html +36 -0
  22. data/doc/derivative/gphys-derivative.html +80 -0
  23. data/doc/derivative/index.html +21 -0
  24. data/doc/derivative/index.rd +14 -0
  25. data/doc/derivative/math-doc/document/document.css +30 -0
  26. data/doc/derivative/math-doc/document/document.html +57 -0
  27. data/doc/derivative/math-doc/document/images.aux +1 -0
  28. data/doc/derivative/math-doc/document/images.log +385 -0
  29. data/doc/derivative/math-doc/document/images.pl +186 -0
  30. data/doc/derivative/math-doc/document/images.tex +364 -0
  31. data/doc/derivative/math-doc/document/img1.png +0 -0
  32. data/doc/derivative/math-doc/document/img10.png +0 -0
  33. data/doc/derivative/math-doc/document/img11.png +0 -0
  34. data/doc/derivative/math-doc/document/img12.png +0 -0
  35. data/doc/derivative/math-doc/document/img13.png +0 -0
  36. data/doc/derivative/math-doc/document/img14.png +0 -0
  37. data/doc/derivative/math-doc/document/img15.png +0 -0
  38. data/doc/derivative/math-doc/document/img16.png +0 -0
  39. data/doc/derivative/math-doc/document/img17.png +0 -0
  40. data/doc/derivative/math-doc/document/img18.png +0 -0
  41. data/doc/derivative/math-doc/document/img19.png +0 -0
  42. data/doc/derivative/math-doc/document/img2.png +0 -0
  43. data/doc/derivative/math-doc/document/img20.png +0 -0
  44. data/doc/derivative/math-doc/document/img21.png +0 -0
  45. data/doc/derivative/math-doc/document/img22.png +0 -0
  46. data/doc/derivative/math-doc/document/img23.png +0 -0
  47. data/doc/derivative/math-doc/document/img24.png +0 -0
  48. data/doc/derivative/math-doc/document/img25.png +0 -0
  49. data/doc/derivative/math-doc/document/img26.png +0 -0
  50. data/doc/derivative/math-doc/document/img27.png +0 -0
  51. data/doc/derivative/math-doc/document/img28.png +0 -0
  52. data/doc/derivative/math-doc/document/img29.png +0 -0
  53. data/doc/derivative/math-doc/document/img3.png +0 -0
  54. data/doc/derivative/math-doc/document/img30.png +0 -0
  55. data/doc/derivative/math-doc/document/img4.png +0 -0
  56. data/doc/derivative/math-doc/document/img5.png +0 -0
  57. data/doc/derivative/math-doc/document/img6.png +0 -0
  58. data/doc/derivative/math-doc/document/img7.png +0 -0
  59. data/doc/derivative/math-doc/document/img8.png +0 -0
  60. data/doc/derivative/math-doc/document/img9.png +0 -0
  61. data/doc/derivative/math-doc/document/index.html +57 -0
  62. data/doc/derivative/math-doc/document/labels.pl +13 -0
  63. data/doc/derivative/math-doc/document/next.png +0 -0
  64. data/doc/derivative/math-doc/document/next_g.png +0 -0
  65. data/doc/derivative/math-doc/document/node1.html +238 -0
  66. data/doc/derivative/math-doc/document/node2.html +75 -0
  67. data/doc/derivative/math-doc/document/prev.png +0 -0
  68. data/doc/derivative/math-doc/document/prev_g.png +0 -0
  69. data/doc/derivative/math-doc/document/up.png +0 -0
  70. data/doc/derivative/math-doc/document/up_g.png +0 -0
  71. data/doc/derivative/math-doc/document.pdf +0 -0
  72. data/doc/derivative/math-doc/document.tex +158 -0
  73. data/doc/derivative/numru-derivative.html +129 -0
  74. data/doc/ep_flux/ep_flux.html +469 -0
  75. data/doc/ep_flux/ggraph_on_merdional_section.html +71 -0
  76. data/doc/ep_flux/index.html +31 -0
  77. data/doc/ep_flux/index.rd +24 -0
  78. data/doc/ep_flux/math-doc/document/WARNINGS +1 -0
  79. data/doc/ep_flux/math-doc/document/contents.png +0 -0
  80. data/doc/ep_flux/math-doc/document/crossref.png +0 -0
  81. data/doc/ep_flux/math-doc/document/document.css +30 -0
  82. data/doc/ep_flux/math-doc/document/document.html +101 -0
  83. data/doc/ep_flux/math-doc/document/images.aux +1 -0
  84. data/doc/ep_flux/math-doc/document/images.log +1375 -0
  85. data/doc/ep_flux/math-doc/document/images.pl +1328 -0
  86. data/doc/ep_flux/math-doc/document/images.tex +1471 -0
  87. data/doc/ep_flux/math-doc/document/img1.png +0 -0
  88. data/doc/ep_flux/math-doc/document/img10.png +0 -0
  89. data/doc/ep_flux/math-doc/document/img100.png +0 -0
  90. data/doc/ep_flux/math-doc/document/img101.png +0 -0
  91. data/doc/ep_flux/math-doc/document/img102.png +0 -0
  92. data/doc/ep_flux/math-doc/document/img103.png +0 -0
  93. data/doc/ep_flux/math-doc/document/img104.png +0 -0
  94. data/doc/ep_flux/math-doc/document/img105.png +0 -0
  95. data/doc/ep_flux/math-doc/document/img106.png +0 -0
  96. data/doc/ep_flux/math-doc/document/img107.png +0 -0
  97. data/doc/ep_flux/math-doc/document/img108.png +0 -0
  98. data/doc/ep_flux/math-doc/document/img109.png +0 -0
  99. data/doc/ep_flux/math-doc/document/img11.png +0 -0
  100. data/doc/ep_flux/math-doc/document/img110.png +0 -0
  101. data/doc/ep_flux/math-doc/document/img111.png +0 -0
  102. data/doc/ep_flux/math-doc/document/img112.png +0 -0
  103. data/doc/ep_flux/math-doc/document/img113.png +0 -0
  104. data/doc/ep_flux/math-doc/document/img114.png +0 -0
  105. data/doc/ep_flux/math-doc/document/img115.png +0 -0
  106. data/doc/ep_flux/math-doc/document/img116.png +0 -0
  107. data/doc/ep_flux/math-doc/document/img117.png +0 -0
  108. data/doc/ep_flux/math-doc/document/img118.png +0 -0
  109. data/doc/ep_flux/math-doc/document/img119.png +0 -0
  110. data/doc/ep_flux/math-doc/document/img12.png +0 -0
  111. data/doc/ep_flux/math-doc/document/img120.png +0 -0
  112. data/doc/ep_flux/math-doc/document/img121.png +0 -0
  113. data/doc/ep_flux/math-doc/document/img122.png +0 -0
  114. data/doc/ep_flux/math-doc/document/img123.png +0 -0
  115. data/doc/ep_flux/math-doc/document/img124.png +0 -0
  116. data/doc/ep_flux/math-doc/document/img125.png +0 -0
  117. data/doc/ep_flux/math-doc/document/img126.png +0 -0
  118. data/doc/ep_flux/math-doc/document/img127.png +0 -0
  119. data/doc/ep_flux/math-doc/document/img128.png +0 -0
  120. data/doc/ep_flux/math-doc/document/img129.png +0 -0
  121. data/doc/ep_flux/math-doc/document/img13.png +0 -0
  122. data/doc/ep_flux/math-doc/document/img130.png +0 -0
  123. data/doc/ep_flux/math-doc/document/img131.png +0 -0
  124. data/doc/ep_flux/math-doc/document/img132.png +0 -0
  125. data/doc/ep_flux/math-doc/document/img133.png +0 -0
  126. data/doc/ep_flux/math-doc/document/img134.png +0 -0
  127. data/doc/ep_flux/math-doc/document/img135.png +0 -0
  128. data/doc/ep_flux/math-doc/document/img136.png +0 -0
  129. data/doc/ep_flux/math-doc/document/img137.png +0 -0
  130. data/doc/ep_flux/math-doc/document/img138.png +0 -0
  131. data/doc/ep_flux/math-doc/document/img139.png +0 -0
  132. data/doc/ep_flux/math-doc/document/img14.png +0 -0
  133. data/doc/ep_flux/math-doc/document/img140.png +0 -0
  134. data/doc/ep_flux/math-doc/document/img141.png +0 -0
  135. data/doc/ep_flux/math-doc/document/img142.png +0 -0
  136. data/doc/ep_flux/math-doc/document/img143.png +0 -0
  137. data/doc/ep_flux/math-doc/document/img144.png +0 -0
  138. data/doc/ep_flux/math-doc/document/img145.png +0 -0
  139. data/doc/ep_flux/math-doc/document/img146.png +0 -0
  140. data/doc/ep_flux/math-doc/document/img147.png +0 -0
  141. data/doc/ep_flux/math-doc/document/img148.png +0 -0
  142. data/doc/ep_flux/math-doc/document/img149.png +0 -0
  143. data/doc/ep_flux/math-doc/document/img15.png +0 -0
  144. data/doc/ep_flux/math-doc/document/img150.png +0 -0
  145. data/doc/ep_flux/math-doc/document/img151.png +0 -0
  146. data/doc/ep_flux/math-doc/document/img152.png +0 -0
  147. data/doc/ep_flux/math-doc/document/img153.png +0 -0
  148. data/doc/ep_flux/math-doc/document/img154.png +0 -0
  149. data/doc/ep_flux/math-doc/document/img155.png +0 -0
  150. data/doc/ep_flux/math-doc/document/img156.png +0 -0
  151. data/doc/ep_flux/math-doc/document/img157.png +0 -0
  152. data/doc/ep_flux/math-doc/document/img158.png +0 -0
  153. data/doc/ep_flux/math-doc/document/img159.png +0 -0
  154. data/doc/ep_flux/math-doc/document/img16.png +0 -0
  155. data/doc/ep_flux/math-doc/document/img160.png +0 -0
  156. data/doc/ep_flux/math-doc/document/img161.png +0 -0
  157. data/doc/ep_flux/math-doc/document/img162.png +0 -0
  158. data/doc/ep_flux/math-doc/document/img163.png +0 -0
  159. data/doc/ep_flux/math-doc/document/img164.png +0 -0
  160. data/doc/ep_flux/math-doc/document/img165.png +0 -0
  161. data/doc/ep_flux/math-doc/document/img166.png +0 -0
  162. data/doc/ep_flux/math-doc/document/img167.png +0 -0
  163. data/doc/ep_flux/math-doc/document/img168.png +0 -0
  164. data/doc/ep_flux/math-doc/document/img169.png +0 -0
  165. data/doc/ep_flux/math-doc/document/img17.png +0 -0
  166. data/doc/ep_flux/math-doc/document/img170.png +0 -0
  167. data/doc/ep_flux/math-doc/document/img171.png +0 -0
  168. data/doc/ep_flux/math-doc/document/img172.png +0 -0
  169. data/doc/ep_flux/math-doc/document/img173.png +0 -0
  170. data/doc/ep_flux/math-doc/document/img174.png +0 -0
  171. data/doc/ep_flux/math-doc/document/img175.png +0 -0
  172. data/doc/ep_flux/math-doc/document/img176.png +0 -0
  173. data/doc/ep_flux/math-doc/document/img177.png +0 -0
  174. data/doc/ep_flux/math-doc/document/img178.png +0 -0
  175. data/doc/ep_flux/math-doc/document/img179.png +0 -0
  176. data/doc/ep_flux/math-doc/document/img18.png +0 -0
  177. data/doc/ep_flux/math-doc/document/img180.png +0 -0
  178. data/doc/ep_flux/math-doc/document/img181.png +0 -0
  179. data/doc/ep_flux/math-doc/document/img182.png +0 -0
  180. data/doc/ep_flux/math-doc/document/img183.png +0 -0
  181. data/doc/ep_flux/math-doc/document/img184.png +0 -0
  182. data/doc/ep_flux/math-doc/document/img185.png +0 -0
  183. data/doc/ep_flux/math-doc/document/img186.png +0 -0
  184. data/doc/ep_flux/math-doc/document/img187.png +0 -0
  185. data/doc/ep_flux/math-doc/document/img188.png +0 -0
  186. data/doc/ep_flux/math-doc/document/img189.png +0 -0
  187. data/doc/ep_flux/math-doc/document/img19.png +0 -0
  188. data/doc/ep_flux/math-doc/document/img190.png +0 -0
  189. data/doc/ep_flux/math-doc/document/img191.png +0 -0
  190. data/doc/ep_flux/math-doc/document/img192.png +0 -0
  191. data/doc/ep_flux/math-doc/document/img193.png +0 -0
  192. data/doc/ep_flux/math-doc/document/img194.png +0 -0
  193. data/doc/ep_flux/math-doc/document/img195.png +0 -0
  194. data/doc/ep_flux/math-doc/document/img196.png +0 -0
  195. data/doc/ep_flux/math-doc/document/img197.png +0 -0
  196. data/doc/ep_flux/math-doc/document/img198.png +0 -0
  197. data/doc/ep_flux/math-doc/document/img199.png +0 -0
  198. data/doc/ep_flux/math-doc/document/img2.png +0 -0
  199. data/doc/ep_flux/math-doc/document/img20.png +0 -0
  200. data/doc/ep_flux/math-doc/document/img200.png +0 -0
  201. data/doc/ep_flux/math-doc/document/img21.png +0 -0
  202. data/doc/ep_flux/math-doc/document/img22.png +0 -0
  203. data/doc/ep_flux/math-doc/document/img23.png +0 -0
  204. data/doc/ep_flux/math-doc/document/img24.png +0 -0
  205. data/doc/ep_flux/math-doc/document/img25.png +0 -0
  206. data/doc/ep_flux/math-doc/document/img26.png +0 -0
  207. data/doc/ep_flux/math-doc/document/img27.png +0 -0
  208. data/doc/ep_flux/math-doc/document/img28.png +0 -0
  209. data/doc/ep_flux/math-doc/document/img29.png +0 -0
  210. data/doc/ep_flux/math-doc/document/img3.png +0 -0
  211. data/doc/ep_flux/math-doc/document/img30.png +0 -0
  212. data/doc/ep_flux/math-doc/document/img31.png +0 -0
  213. data/doc/ep_flux/math-doc/document/img32.png +0 -0
  214. data/doc/ep_flux/math-doc/document/img33.png +0 -0
  215. data/doc/ep_flux/math-doc/document/img34.png +0 -0
  216. data/doc/ep_flux/math-doc/document/img35.png +0 -0
  217. data/doc/ep_flux/math-doc/document/img36.png +0 -0
  218. data/doc/ep_flux/math-doc/document/img37.png +0 -0
  219. data/doc/ep_flux/math-doc/document/img38.png +0 -0
  220. data/doc/ep_flux/math-doc/document/img39.png +0 -0
  221. data/doc/ep_flux/math-doc/document/img4.png +0 -0
  222. data/doc/ep_flux/math-doc/document/img40.png +0 -0
  223. data/doc/ep_flux/math-doc/document/img41.png +0 -0
  224. data/doc/ep_flux/math-doc/document/img42.png +0 -0
  225. data/doc/ep_flux/math-doc/document/img43.png +0 -0
  226. data/doc/ep_flux/math-doc/document/img44.png +0 -0
  227. data/doc/ep_flux/math-doc/document/img45.png +0 -0
  228. data/doc/ep_flux/math-doc/document/img46.png +0 -0
  229. data/doc/ep_flux/math-doc/document/img47.png +0 -0
  230. data/doc/ep_flux/math-doc/document/img48.png +0 -0
  231. data/doc/ep_flux/math-doc/document/img49.png +0 -0
  232. data/doc/ep_flux/math-doc/document/img5.png +0 -0
  233. data/doc/ep_flux/math-doc/document/img50.png +0 -0
  234. data/doc/ep_flux/math-doc/document/img51.png +0 -0
  235. data/doc/ep_flux/math-doc/document/img52.png +0 -0
  236. data/doc/ep_flux/math-doc/document/img53.png +0 -0
  237. data/doc/ep_flux/math-doc/document/img54.png +0 -0
  238. data/doc/ep_flux/math-doc/document/img55.png +0 -0
  239. data/doc/ep_flux/math-doc/document/img56.png +0 -0
  240. data/doc/ep_flux/math-doc/document/img57.png +0 -0
  241. data/doc/ep_flux/math-doc/document/img58.png +0 -0
  242. data/doc/ep_flux/math-doc/document/img59.png +0 -0
  243. data/doc/ep_flux/math-doc/document/img6.png +0 -0
  244. data/doc/ep_flux/math-doc/document/img60.png +0 -0
  245. data/doc/ep_flux/math-doc/document/img61.png +0 -0
  246. data/doc/ep_flux/math-doc/document/img62.png +0 -0
  247. data/doc/ep_flux/math-doc/document/img63.png +0 -0
  248. data/doc/ep_flux/math-doc/document/img64.png +0 -0
  249. data/doc/ep_flux/math-doc/document/img65.png +0 -0
  250. data/doc/ep_flux/math-doc/document/img66.png +0 -0
  251. data/doc/ep_flux/math-doc/document/img67.png +0 -0
  252. data/doc/ep_flux/math-doc/document/img68.png +0 -0
  253. data/doc/ep_flux/math-doc/document/img69.png +0 -0
  254. data/doc/ep_flux/math-doc/document/img7.png +0 -0
  255. data/doc/ep_flux/math-doc/document/img70.png +0 -0
  256. data/doc/ep_flux/math-doc/document/img71.png +0 -0
  257. data/doc/ep_flux/math-doc/document/img72.png +0 -0
  258. data/doc/ep_flux/math-doc/document/img73.png +0 -0
  259. data/doc/ep_flux/math-doc/document/img74.png +0 -0
  260. data/doc/ep_flux/math-doc/document/img75.png +0 -0
  261. data/doc/ep_flux/math-doc/document/img76.png +0 -0
  262. data/doc/ep_flux/math-doc/document/img77.png +0 -0
  263. data/doc/ep_flux/math-doc/document/img78.png +0 -0
  264. data/doc/ep_flux/math-doc/document/img79.png +0 -0
  265. data/doc/ep_flux/math-doc/document/img8.png +0 -0
  266. data/doc/ep_flux/math-doc/document/img80.png +0 -0
  267. data/doc/ep_flux/math-doc/document/img81.png +0 -0
  268. data/doc/ep_flux/math-doc/document/img82.png +0 -0
  269. data/doc/ep_flux/math-doc/document/img83.png +0 -0
  270. data/doc/ep_flux/math-doc/document/img84.png +0 -0
  271. data/doc/ep_flux/math-doc/document/img85.png +0 -0
  272. data/doc/ep_flux/math-doc/document/img86.png +0 -0
  273. data/doc/ep_flux/math-doc/document/img87.png +0 -0
  274. data/doc/ep_flux/math-doc/document/img88.png +0 -0
  275. data/doc/ep_flux/math-doc/document/img89.png +0 -0
  276. data/doc/ep_flux/math-doc/document/img9.png +0 -0
  277. data/doc/ep_flux/math-doc/document/img90.png +0 -0
  278. data/doc/ep_flux/math-doc/document/img91.png +0 -0
  279. data/doc/ep_flux/math-doc/document/img92.png +0 -0
  280. data/doc/ep_flux/math-doc/document/img93.png +0 -0
  281. data/doc/ep_flux/math-doc/document/img94.png +0 -0
  282. data/doc/ep_flux/math-doc/document/img95.png +0 -0
  283. data/doc/ep_flux/math-doc/document/img96.png +0 -0
  284. data/doc/ep_flux/math-doc/document/img97.png +0 -0
  285. data/doc/ep_flux/math-doc/document/img98.png +0 -0
  286. data/doc/ep_flux/math-doc/document/img99.png +0 -0
  287. data/doc/ep_flux/math-doc/document/index.html +101 -0
  288. data/doc/ep_flux/math-doc/document/internals.pl +258 -0
  289. data/doc/ep_flux/math-doc/document/labels.pl +265 -0
  290. data/doc/ep_flux/math-doc/document/next.png +0 -0
  291. data/doc/ep_flux/math-doc/document/next_g.png +0 -0
  292. data/doc/ep_flux/math-doc/document/node1.html +104 -0
  293. data/doc/ep_flux/math-doc/document/node10.html +164 -0
  294. data/doc/ep_flux/math-doc/document/node11.html +86 -0
  295. data/doc/ep_flux/math-doc/document/node12.html +166 -0
  296. data/doc/ep_flux/math-doc/document/node13.html +897 -0
  297. data/doc/ep_flux/math-doc/document/node14.html +1065 -0
  298. data/doc/ep_flux/math-doc/document/node15.html +72 -0
  299. data/doc/ep_flux/math-doc/document/node16.html +81 -0
  300. data/doc/ep_flux/math-doc/document/node2.html +82 -0
  301. data/doc/ep_flux/math-doc/document/node3.html +91 -0
  302. data/doc/ep_flux/math-doc/document/node4.html +149 -0
  303. data/doc/ep_flux/math-doc/document/node5.html +330 -0
  304. data/doc/ep_flux/math-doc/document/node6.html +99 -0
  305. data/doc/ep_flux/math-doc/document/node7.html +98 -0
  306. data/doc/ep_flux/math-doc/document/node8.html +83 -0
  307. data/doc/ep_flux/math-doc/document/node9.html +140 -0
  308. data/doc/ep_flux/math-doc/document/prev.png +0 -0
  309. data/doc/ep_flux/math-doc/document/prev_g.png +0 -0
  310. data/doc/ep_flux/math-doc/document/up.png +0 -0
  311. data/doc/ep_flux/math-doc/document/up_g.png +0 -0
  312. data/doc/ep_flux/math-doc/document.pdf +0 -0
  313. data/doc/ep_flux/math-doc/document.tex +2018 -0
  314. data/doc/gdir.html +412 -0
  315. data/doc/gdir_client.html +16 -0
  316. data/doc/gdir_connect_ftp-like.html +61 -0
  317. data/doc/gdir_server.html +33 -0
  318. data/doc/ggraph.html +1332 -0
  319. data/doc/gpcat.html +27 -0
  320. data/doc/gpcut.html +27 -0
  321. data/doc/gphys.html +501 -0
  322. data/doc/gphys_fft.html +183 -0
  323. data/doc/gphys_grads_io.html +69 -0
  324. data/doc/gphys_grib_io.html +82 -0
  325. data/doc/gphys_io.html +96 -0
  326. data/doc/gphys_io_common.html +18 -0
  327. data/doc/gphys_netcdf_io.html +283 -0
  328. data/doc/gplist.html +23 -0
  329. data/doc/gpmath.html +34 -0
  330. data/doc/gpmaxmin.html +30 -0
  331. data/doc/gpprint.html +32 -0
  332. data/doc/gpview.html +187 -0
  333. data/doc/grads2nc_with_gphys.html +23 -0
  334. data/doc/grads_gridded.html +307 -0
  335. data/doc/grib.html +101 -0
  336. data/doc/grid.html +240 -0
  337. data/doc/index.html +125 -0
  338. data/doc/index.rd +121 -0
  339. data/doc/netcdf_convention.html +136 -0
  340. data/doc/unumeric.html +127 -0
  341. data/doc/update +64 -0
  342. data/doc/varray.html +293 -0
  343. data/doc/varraycomposite.html +67 -0
  344. data/lib/numru/dclext_datetime_ax.rb +220 -0
  345. data/lib/numru/derivative.rb +298 -0
  346. data/lib/numru/gdir.rb +1038 -0
  347. data/lib/numru/gdir_connect_ftp-like.rb +149 -0
  348. data/lib/numru/ggraph.rb +4604 -0
  349. data/lib/numru/ggraph_on_merdional_section.rb +178 -0
  350. data/lib/numru/gphys/attribute.rb +130 -0
  351. data/lib/numru/gphys/attributenetcdf.rb +80 -0
  352. data/lib/numru/gphys/axis.rb +958 -0
  353. data/lib/numru/gphys/coordmapping.rb +286 -0
  354. data/lib/numru/gphys/coordtransform.rb +209 -0
  355. data/lib/numru/gphys/derivative.rb +297 -0
  356. data/lib/numru/gphys/ep_flux.rb +868 -0
  357. data/lib/numru/gphys/gpcommon.rb +52 -0
  358. data/lib/numru/gphys/gphys.rb +1121 -0
  359. data/lib/numru/gphys/gphys_fft.rb +538 -0
  360. data/lib/numru/gphys/gphys_grads_io.rb +212 -0
  361. data/lib/numru/gphys/gphys_grib_io.rb +214 -0
  362. data/lib/numru/gphys/gphys_io.rb +363 -0
  363. data/lib/numru/gphys/gphys_io_common.rb +126 -0
  364. data/lib/numru/gphys/gphys_netcdf_io.rb +767 -0
  365. data/lib/numru/gphys/gphys_nusdas_io.rb +78 -0
  366. data/lib/numru/gphys/grads_gridded.rb +1539 -0
  367. data/lib/numru/gphys/grib.rb +2005 -0
  368. data/lib/numru/gphys/grib_params.rb +1270 -0
  369. data/lib/numru/gphys/grid.rb +602 -0
  370. data/lib/numru/gphys/netcdf_convention.rb +366 -0
  371. data/lib/numru/gphys/subsetmapping.rb +332 -0
  372. data/lib/numru/gphys/unumeric.rb +452 -0
  373. data/lib/numru/gphys/varray.rb +1079 -0
  374. data/lib/numru/gphys/varraycomposite.rb +415 -0
  375. data/lib/numru/gphys/varraygrads.rb +225 -0
  376. data/lib/numru/gphys/varraygrib.rb +177 -0
  377. data/lib/numru/gphys/varraynetcdf.rb +348 -0
  378. data/lib/numru/gphys/varraynusdas.rb +59 -0
  379. data/lib/numru/gphys.rb +7 -0
  380. data/lib/numru/htdir.rb +170 -0
  381. data/lib/numru/vizshot.rb +697 -0
  382. data/sample/cira86_to_nc.rb +122 -0
  383. data/sample/druby_cli1.rb +21 -0
  384. data/sample/druby_cli2.rb +34 -0
  385. data/sample/druby_serv1.rb +30 -0
  386. data/sample/druby_serv2.rb +64 -0
  387. data/sample/ep_flux/demo_NCEP_1.rb +48 -0
  388. data/sample/ep_flux/demo_NCEP_2.rb +57 -0
  389. data/sample/ep_flux/demo_NCEP_3.rb +81 -0
  390. data/sample/ggraph_latlon_labelling_dr002690.rb +159 -0
  391. data/sample/ggraph_mapfit-axes_dr002687.rb +131 -0
  392. data/sample/map_projection.rb +121 -0
  393. data/test/test_ep_flux.rb +533 -0
  394. data/testdata/T.jan.ctl +12 -0
  395. data/testdata/T.jan.dat +0 -0
  396. data/testdata/T.jan.grib +0 -0
  397. data/testdata/T.jan.nc +0 -0
  398. data/testdata/T.jan.packed.withmiss.nc +0 -0
  399. data/testdata/UV.jan.nc +0 -0
  400. data/testdata/cira86.dat +1332 -0
  401. metadata +527 -0
@@ -0,0 +1,4604 @@
1
+ require "numru/gphys"
2
+ require "numru/dcl"
3
+ require "numru/misc"
4
+ require "date"
5
+ require "numru/dclext_datetime_ax"
6
+
7
+ ############################################################
8
+
9
+ =begin
10
+ =module NumRu::GGraph and others in ggraph.rb
11
+
12
+ ==Index
13
+ * ((<module NumRu::GGraph>))
14
+ * ((<margin_info>))
15
+ Sets the strings to appear in the bottom margin.
16
+ * ((<title>))
17
+ Shows title by (({DCL.uxmttl('t',string,0.0)})).
18
+ Graphic methods such as ((<contour>)) calls this by default.
19
+ * ((<annotate>))
20
+ Show texts on the right margin of the viewport.
21
+ Graphic methods such as ((<contour>)) calls this by default.
22
+ * ((<fig>))
23
+ Define a figure by setting viewport, window, and coordinate transform
24
+ id (itr) from two 1D VArrays (({xax})) and (({yax})).
25
+ * ((<set_fig>))
26
+ Change the default option values for ((<fig>)).
27
+ * ((<next_fig>))
28
+ Set the option values effective only in the next call of ((<fig>))
29
+ (cleared then).
30
+ * ((<axes>))
31
+ Draw axes using (by default) info in (({xax})) and (({yax})) if non-nil.
32
+ * ((<set_axes>))
33
+ Change the default option values for ((<axes>)).
34
+ * ((<next_axes>))
35
+ Set the option values effective only in the next call of ((<axes>))
36
+ (cleared then).
37
+ * ((<map_trn?>))
38
+ Returns whether the current coordinate transformation is a map projection.
39
+ * ((<map>))
40
+ (For map projection) Draws map grid and/or lim and/or coast lines etc.
41
+ * ((<set_map>))
42
+ Change the default option values for ((<map>)).
43
+ * ((<next_map>))
44
+ Set the option values effective only in the next call of ((<map>))
45
+ * ((<line>))
46
+ Plot a poly-line by selecting the first dimension (with GPhys#first1D)
47
+ if (({gphys})) is more than 2D.
48
+ * ((<mark>))
49
+ Similar to ((<line>)) but plots marks instead of drawing a poly-line.
50
+ * ((<contour>))
51
+ Contour plot by selecting the first 2 dimensions (with GPhys#first2D)
52
+ if (({gphys})) is more than 3D.
53
+ * ((<set_contour>))
54
+ Set options for contour in general.
55
+ * ((<next_contour>))
56
+ Set options for contour in general, which is applied only to the next call.
57
+ * ((<set_contour_levels>))
58
+ Set contour levels for ((<contour>)) explicitly by values with the option (({levels})).
59
+ * ((<clear_contour_levels>))
60
+ Clear contour levels set by ((<set_contour_levels>)).
61
+ * ((<set_linear_contour_options>))
62
+ Change the default option values regarding linear contour level
63
+ setting in ((<contour>)).
64
+ * ((<next_linear_contour_options>))
65
+ Similar to ((<set_linear_contour_options>)) but the setting
66
+ is effective only for the next call of ((<contour>)).
67
+ * ((<tone>))
68
+ Color tone or shading by selecting the first 2 dimensions
69
+ (with GPhys#first2D) if (({gphys})) is more than 3D.
70
+ * ((<color_bar >)) Color bar
71
+ * ((<set_tone_levels>))
72
+ Set tone levels for ((<tone>)) explicitly by values.
73
+ * ((<set_tone>))
74
+ Set options for tone in general.
75
+ * ((<next_tone>))
76
+ Set options for tone in general, which is applied only to the next call.
77
+ * ((<clear_tone_levels>))
78
+ Clear tone levels set by ((<set_tone_levels>)).
79
+ * ((<set_linear_tone_options>))
80
+ Change the default option values regarding linear tone level
81
+ setting in ((<tone>)).
82
+ * ((<next_linear_tone_options>))
83
+ Similar to ((<set_linear_tone_options>)) but the setting
84
+ is effective only for the next call of ((<tone>)).
85
+ * ((<vector>)) 2-D vector plot using DCL_Ext::((<flow_vect>))
86
+
87
+ * ((<module NumRu::DCLExt>))
88
+ * ((<gl_set_params>))
89
+ Calls (({DCL.glpset})) multiple times (for each key and val of (({hash}))).
90
+ * ((<sg_set_params>))
91
+ Calls (({DCL.sgpset})) multiple times (for each key and val of (({hash}))).
92
+ * ((<sl_set_params>))
93
+ Calls (({DCL.slpset})) multiple times (for each key and val of (({hash}))).
94
+ * ((<sw_set_params>))
95
+ Calls (({DCL.swpset})) multiple times (for each key and val of (({hash}))).
96
+ * ((<uz_set_params>))
97
+ Calls (({DCL.uzpset})) multiple times (for each key and val of (({hash}))).
98
+ * ((<ul_set_params>))
99
+ Calls (({DCL.ulpset})) multiple times (for each key and val of (({hash}))).
100
+ * ((<uc_set_params>))
101
+ Calls (({DCL.ucpset})) multiple times (for each key and val of (({hash}))).
102
+ * ((<uu_set_params>))
103
+ Calls (({DCL.uupset})) multiple times (for each key and val of (({hash}))).
104
+ * ((<us_set_params>))
105
+ Calls (({DCL.uspset})) multiple times (for each key and val of (({hash}))).
106
+ * ((<ud_set_params>))
107
+ Calls (({DCL.udpset})) multiple times (for each key and val of (({hash}))).
108
+ * ((<ud_set_linear_levs>))
109
+ Set contour levels with a constant interval
110
+ * ((<ud_set_contour>))
111
+ Set contours of at specified levels.
112
+ * ((<ud_add_contour>))
113
+ Same as ((<ud_set_contour>)), but does not clear the contour levels that have
114
+ been set.
115
+ * ((<ue_set_params>))
116
+ Calls (({DCL.uepset})) multiple times (for each key and val of (({hash}))).
117
+ * ((<ue_set_linear_levs>))
118
+ Set tone levels with a constant interval
119
+ * ((<ue_set_tone>))
120
+ Set tone levels and patterns.
121
+ * ((<ue_add_tone>))
122
+ Same as ((<ue_set_tone>)), but does not clear the tone levels that have
123
+ been set.
124
+ * ((<ug_set_params>))
125
+ Calls (({DCL.ugpset})) multiple times (for each key and val of (({hash}))).
126
+ See ((<gl_set_params>)) for usage.
127
+ * ((<um_set_params>))
128
+ Calls (({DCL.umpset})) multiple times (for each key and val of (({hash}))).
129
+
130
+ * ((<set_unit_vect_options>))
131
+ * ((<next_unit_vect_options>))
132
+ * ((<unit_vect>)) Show the "unit vector", which indicate the vector scaling.
133
+ * ((<flow_vect>)) 2D Vector plot. Unlike (({DCL::ugvect})), scaling are made in term of the physical (or "U") coordinate.
134
+ * ((<flow_itr5>)) 2D Vector plot on the 2-dim polar coodinate.
135
+ * ((<color_bar>)) Color Bar
136
+
137
+ =module NumRu::GGraph
138
+
139
+ A graphic library for GPhys using RubyDCL.
140
+
141
+ This module uses GPhys but is not a part of it.
142
+ More specifically, even though this module is included in
143
+ the GPhys distribution, the class NumRu::GPhys knows nothing about it,
144
+ and GGraph accesses GPhys only though public methods.
145
+ So GGraph is not an insider, and you can make another graphic
146
+ library if you like.
147
+
148
+ ==Module Functions
149
+
150
+ ---margin_info(program=nil, data_source=nil, char_height=nil, date=nil, xl=0.0, xr=0.0, yb=nil, yt=0.0)
151
+
152
+ Sets the strings to appear in the bottom margin.
153
+
154
+ This method sets margin widths as DCL.slmgn(xl, xr, yb, yt),
155
+ and sets the 1st and 2nd margin strings as (({program}))
156
+ and (({data})).
157
+
158
+ ARGUMENTS
159
+ * program (String or nil) : String to be put on the left side in
160
+ the bottom margin. This is meant to represent the name of the
161
+ execution program. Therefore, if it is nil, the full path of
162
+ $0 is used.
163
+
164
+ * data_source (String or nil) : String to be put on the right side in
165
+ the bottom margin. This is meant to represent the data file name or the
166
+ directory in which the data are situated.
167
+ If nil, the full path of the current directory is used
168
+ (but nothing is shown if it is equal to the directory of the program).
169
+
170
+ * date (true, false, nil) : whether to put todays date --
171
+ true: always, nil: if program.length is short enough, false: never
172
+
173
+ * char_height (Float or nil) : height of the string to appear
174
+ in the V coordinate. If nil, internally defined.
175
+
176
+ * xl, xr, yb, yl (Float --- nil is available for yb) : margin
177
+ size in the V coordinate. The margin is set as
178
+ DCL.slmgn(xl, xr, yb, yt). If (({yb})) is nil, it is determined
179
+ internally as (({2.0 * char_height})).
180
+
181
+ ---title(string)
182
+ Shows title by (({DCL.uxmttl('t',string,0.0)})).
183
+ Graphic methods such as ((<contour>)) calls this by default.
184
+
185
+ RETURN VALUE
186
+ * nil
187
+
188
+ ---annotate(str_ary)
189
+ Show texts on the right margin of the viewport.
190
+ Graphic methods such as ((<contour>)) calls this by default.
191
+
192
+ ARGUMENTS
193
+ * str_ary (Array of String) :
194
+
195
+ RETURN VALUE
196
+ * nil
197
+
198
+ ---fig(xax=nil, yax=nil, options=nil)
199
+ Define a figure by setting viewport, window, and coordinate transform
200
+ id (itr) from two 1D VArrays (({xax})) and (({yax})) (which are
201
+ not needed if a map projection is specified with the optional
202
+ parameter 'itr').
203
+
204
+ (({DCL.grfrm})) or (({DCL.grfig})) is called depending options provided.
205
+
206
+ ARGUMENTS
207
+ * xax (VArray): (Used only if not map projection)
208
+ A VArray representing the x (horizontal) coordinate
209
+ of the figure.
210
+ The x range of the window (UXMIN & UYMAX in DCL) are determined
211
+ with the max and min of (({xax.val})). By default,
212
+ the min and max values are assigned to the left and right
213
+ boundaries, respectively, but it is reversed if (({xax})) has
214
+ a 'positive' attribute and its value is 'down' etc (see (({options}))).
215
+ * yax (VArray): (Used only if not map projection)
216
+ Similar to (({xax})) but for the y (vertical) coordinate
217
+ of the figure.
218
+ * options (Hash) : options to change the default behavior if specified.
219
+ It is a Hash with option names (String) as keys and their values.
220
+ Options are interpreted by a NumRu::Misc::KeywordOptAutoHelp,
221
+ so you can shorten the keys (by omitting tails) as long as it is
222
+ unambiguous.
223
+ option name default value # description:
224
+ "new_frame" true # whether to define a new frame by DCL.grfrm
225
+ # (otherwise, DCL.grfig is called)
226
+ "no_new_fig" false # If true, neither DCL.grfrm nor DCL.grfig
227
+ # is called (overrides new_frame) -- Then, you need
228
+ # to call one of them in advance. Convenient to set
229
+ # DCL parameters that are reset by grfrm or grfig.
230
+ "itr" 1 # coordinate transformation number
231
+ "viewport" [0.2, 0.8, 0.2, 0.8] # [vxmin, vxmax, vymin, vymax]
232
+ "eqdistvpt" false # modify viewport to equidistant for x and y
233
+ # (only for itr=1--4)
234
+ "window" nil # (for itr<10,>50) [uxmin, uxmax, uymin, uymax],
235
+ # each element allowed nil (only for itr<5,>50)
236
+ "xreverse" "positive:down,units:hPa" # (for itr<10,>50) Assign
237
+ # max value to UXMIN and min value to UXMAX if
238
+ # condition is satisfied (nil:never, true:always,
239
+ # String: when an attibute has the value specified
240
+ # ("key:value,key:value,..")
241
+ "yreverse" "positive:down,units:hPa" # (for itr<10,>50) Assign
242
+ # max value to UYMIN and min value to UYMAX if
243
+ # condition is satisfied (nil:never, true:always,
244
+ # String: when an attibute has the value specified
245
+ # ("key:value,key:value,..")
246
+ "round0" false # expand window range to good numbers (effective
247
+ # only to internal window settings)
248
+ "round1" false # expand window range to good numbers (effective
249
+ # even when "window" is explicitly specified)
250
+ "similar" nil # (for rectangular curvilinear coordinate only)
251
+ # 3-element float array for similar transformation
252
+ # in a rectangular curvilinear coordinate, which
253
+ # is fed in DCL:grssim:[simfac,vxoff,vyoff],where
254
+ # simfac and [vxoff,vyoff] represent scaling
255
+ # factor and origin shift, respectively.
256
+ "map_axis" nil # (for all map projections) 3-element float
257
+ # array to be fed in DCL::umscnt: [uxc, uxy, rot],
258
+ # where [uxc, uyc] represents the tangential point
259
+ # (or the pole at top side for cylindrical
260
+ # projections), and rot represents the rotation
261
+ # angle. If nil, internally determined. (units:
262
+ # degrees)
263
+ "map_radius" nil # (for itr>=20: conical/azimuhal map
264
+ # projections) raidus around the tangential point.
265
+ # (units: degrees)
266
+ "map_fit" nil # (Only for itr=10(cylindrical) and 11 (Mercator))
267
+ # true: fit the plot to the data window
268
+ # (overrides map_window and map_axis); false: do
269
+ # not fit (then map_window and map_axis are used);
270
+ # nil: true if itr==10, false if itr==11
271
+ "map_window" [-180, 180, -75, 75] # (for itr<20: cylindrical
272
+ # map projections) lon-lat window [lon_min,
273
+ # lon_max, lat_min, lat_max ] to draw the map
274
+ # (units: degres)
275
+ "help" false # show help message if true
276
+
277
+ RETURN VALUE
278
+ * nil
279
+
280
+ POSSIBLE EXCEPTIONS
281
+ * those from NumRu::DCL if any / TypeError if any
282
+ * options has a key that does not match any of the option names.
283
+ * options has a key that is ambiguous
284
+
285
+ ---set_fig(options)
286
+ Change the default option values for ((<fig>)).
287
+
288
+ ARGUMENTS
289
+ * options (Hash) : The usage is the same as (({options})) for ((<fig>)).
290
+
291
+ RETURN VALUE
292
+ * a Hash containing the values replaced (the ones before calling this
293
+ method)
294
+
295
+ POSSIBLE EXCEPTIONS
296
+ * see ((<fig>)).
297
+
298
+ ---next_fig(options)
299
+ Set the option values effective only in the next call of ((<fig>))
300
+ (cleared then).
301
+
302
+ These value are overwritten if specified explicitly in the next
303
+ call of ((<fig>)).
304
+
305
+ ARGUMENTS
306
+ * options (Hash) : The usage is the same as (({options})) for ((<fig>)).
307
+
308
+ RETURN VALUE
309
+ * nil
310
+
311
+ POSSIBLE EXCEPTIONS
312
+ * see ((<fig>)).
313
+
314
+ ---axes(xax=nil, yax=nil, options=nil)
315
+ Draw axes using (by default) info in (({xax})) and (({yax})) if non-nil.
316
+
317
+ ARGUMENTS
318
+ * xax (nil or VArray): if non-nil, attributes 'long_name' and 'units'
319
+ are read to define (({xtitle})) and (({xunits})) (see below).
320
+ These are overwritten by explicitly specifying (({xtitle})) and
321
+ (({xunits})).
322
+ * yax (nil or VArray): if non-nil, attributes 'long_name' and 'units'
323
+ are read to define (({ytitle})) and (({yunits})) (see below).
324
+ These are overwritten by explicitly specifying (({ytitle})) and
325
+ (({yunits})).
326
+ * options (Hash) : options to change the default behavior if specified.
327
+ It is a Hash with option names (String) as keys and their values.
328
+ Options are interpreted by a NumRu::Misc::KeywordOptAutoHelp,
329
+ so you can shorten the keys (by omitting tails) as long as it is
330
+ unambiguous.
331
+ option name default value # description:
332
+ "xside" "tb" # Where to draw xaxes (combination of t, b and u)
333
+ "yside" "lr" # Where to draw yaxes (combination of l, r and u)
334
+ "xtitle" nil # Title of x axis (if nil, internally determined)
335
+ "ytitle" nil # Title of y axis (if nil, internally determined)
336
+ "xunits" nil # Units of x axis (if nil, internally determined)
337
+ "yunits" nil # Units of y axis (if nil, internally determined)
338
+ "xtickint" nil # Interval of x axis tickmark
339
+ # (if nil, internally determined)
340
+ "ytickint" nil # Interval of y axis tickmark
341
+ # (if nil, internally determined)
342
+ "xlabelint" nil # Interval of x axis label
343
+ # (if nil, internally determined)
344
+ "ylabelint" nil # Interval of y axis label
345
+ # (if nil, internally determined)
346
+ "xmaplabel" false # If "lon"("lat"), use
347
+ # DCLExt::lon_ax(DCLExt::lat_ax) to draw xaxes;
348
+ # otherwise, DCL::usxaxs is used.
349
+ "ymaplabel" false # If "lon"("lat"), use
350
+ # DCLExt::lon_ax(DCLExt::lat_ax) to draw yaxes;
351
+ # otherwise, DCL::usyaxs is used.
352
+ "time_ax" nil # Type of calendar-type time axis: nil (=> auto
353
+ # slection), false (do not use the time axis even
354
+ # if the units of the axis is a time one with since
355
+ # field), "h" (=> like nil, but always use the
356
+ # hour-resolving datetime_ax method in
357
+ # dclext_datetime_ax.rb), or "ymd" (=> like "h" but
358
+ # for y-m-d type using DCL.uc[xy]acl)
359
+ "help" false # show help message if true
360
+
361
+ RETURN VALUE
362
+ * nil
363
+
364
+ POSSIBLE EXCEPTIONS
365
+ * those from NumRu::DCL if any / TypeError if any
366
+ * options has a key that does not match any of the option names.
367
+ * options has a key that is ambiguous
368
+
369
+ ---set_axes(options)
370
+ Change the default option values for ((<axes>)).
371
+
372
+ ARGUMENTS
373
+ * options (Hash) : The usage is the same as (({options})) for ((<axes>)).
374
+
375
+ RETURN VALUE
376
+ * a Hash containing the values replaced (the ones before calling this
377
+ method)
378
+
379
+ POSSIBLE EXCEPTIONS
380
+ * see ((<axes>)).
381
+
382
+ ---next_axes(options)
383
+ Set the option values effective only in the next call of ((<axes>))
384
+ (cleared then).
385
+
386
+ These value are overwritten if specified explicitly in the next
387
+ call of ((<axes>)).
388
+
389
+ ARGUMENTS
390
+ * options (Hash) : The usage is the same as (({options})) for ((<axes>)).
391
+
392
+ RETURN VALUE
393
+ * nil
394
+
395
+ POSSIBLE EXCEPTIONS
396
+ * see ((<axes>)).
397
+
398
+ ---sim_trn?
399
+ Returns whether the current coordinate transformation is a rectangular
400
+ curvelinear coordinate. A coordinate transformation must have been
401
+ established with ((<fig>)) or (({DCL::grstrf})).
402
+ Mainly for internal usage, but a user can use it too.
403
+
404
+ RETURN VALUE
405
+ * true or false
406
+
407
+ ---polar_coordinate_boundaries(xax=nil,yax=nil)
408
+ Draw boundaries in a polar coordinate.
409
+
410
+ ARGUMENTS
411
+ * xax (VArray): Grid points of the radial coordinate.
412
+ * yax (VArray): Grid points of the azimuthal coordinate.
413
+
414
+ RETURN VALUE
415
+ * nil
416
+
417
+ ---map_trn?
418
+ Returns whether the current coordinate transformation is a map projection.
419
+
420
+ A coordinate transformation must have been established
421
+ with ((<fig>)) or (({DCL::grstrf})).
422
+ Mainly for internal usage, but a user can use it too.
423
+
424
+ RETURN VALUE
425
+ * true or false
426
+
427
+ ---map(options=nil)
428
+ (For map projection) Draws map grid and/or lim and/or coast lines etc.
429
+
430
+ ARGUMENTS
431
+ * options (Hash) : options to change the default behavior if specified.
432
+ It is a Hash with option names (String) as keys and their values.
433
+ Options are interpreted by a NumRu::Misc::KeywordOptAutoHelp,
434
+ so you can shorten the keys (by omitting tails) as long as it is
435
+ unambiguous.
436
+ option name default value # description:
437
+ "lim" true # draw map lim (t or f)
438
+ "grid" true # draw map grid (t or f)
439
+ "vpt_boundary" false # draw viewport boundaries (f, t or
440
+ # 1,2,3.., representing the line width)
441
+ "wwd_boundary" false # draw worksation window boundaries (f, t
442
+ # or 1,2,3.., representing the line width)
443
+ "fill" false # fill the map if coast_world or coast_japan is
444
+ # true (t or f)
445
+ "coast_world" false # draw world coast lines (t or f)
446
+ "border_world" false # draw nation borders (t or f)
447
+ "plate_world" false # draw plate boundaries (t or f)
448
+ "state_usa" false # draw state boundaries of US (t or f)
449
+ "coast_japan" false # draw japanese coast lines (t or f)
450
+ "pref_japan" false # draw japanese prefecture boundaries (t or
451
+ # f)
452
+ "dgridmj" nil # the interval between the major lines of
453
+ # latitudes and longitudes. If nil, internally
454
+ # determined. (units: degrees) (this is a UMPACK
455
+ # parameter, which is nullified when uminit or
456
+ # grfrm is called)
457
+ "dgridmn" nil # the interval between the minor lines of
458
+ # latitudes and longitudes. If nil, internally
459
+ # determined. (units: degrees) (this is a UMPACK
460
+ # parameter, which is nullified when uminit or
461
+ # grfrm is called)
462
+ "help" false # show help message if true
463
+
464
+ RETURN VALUE
465
+ * nil
466
+
467
+ POSSIBLE EXCEPTIONS
468
+ * if called when the coordinate tansformation has not been established or
469
+ the transformation is not a map projection.
470
+ * those from NumRu::DCL if any / TypeError if any
471
+ * options has a key that does not match any of the option names.
472
+ * options has a key that is ambiguous
473
+
474
+ ---set_map(options)
475
+ Change the default option values for ((<map>)).
476
+
477
+ ARGUMENTS
478
+ * options (Hash) : The usage is the same as (({options})) for ((<map>)).
479
+
480
+ RETURN VALUE
481
+ * a Hash containing the values replaced (the ones before calling this
482
+ method)
483
+
484
+ POSSIBLE EXCEPTIONS
485
+ * see ((<map>)).
486
+
487
+ ---next_map(options)
488
+ Set the option values effective only in the next call of ((<map>))
489
+ (cleared then).
490
+
491
+ These value are overwritten if specified explicitly in the next
492
+ call of ((<map>)).
493
+
494
+ ARGUMENTS
495
+ * options (Hash) : The usage is the same as (({options})) for ((<map>)).
496
+
497
+ RETURN VALUE
498
+ * nil
499
+
500
+ POSSIBLE EXCEPTIONS
501
+ * see ((<map>)).
502
+
503
+ ---line(gphys, newframe=true, options=nil)
504
+ Plot a poly-line by selecting the first dimension (with GPhys#first1D)
505
+ if (({gphys})) is more than 2D.
506
+
507
+ ARGUMENTS
508
+ * gphys (GPhys) : a GPhys whose data is plotted.
509
+ * newframe (true/false) : if true, calls ((<fig>)), ((<axes>)),
510
+ ((<title>)), and ((<annotate>)) internally; if false, only
511
+ the poly-line is drawn (overlaid to the exiting figure).
512
+ * options (Hash) : options to change the default behavior if specified.
513
+ It is a Hash with option names (String) as keys and their values.
514
+ Options are interpreted by a NumRu::Misc::KeywordOptAutoHelp,
515
+ so you can shorten the keys (by omitting tails) as long as it is
516
+ unambiguous.
517
+ option name default value # description:
518
+ "title" nil # Title of the figure(if nil, internally
519
+ # determined)
520
+ "annotate" true # if false, do not put texts on the right
521
+ # margin even when newframe==true
522
+ "exchange" false # whether to exchange x and y axes
523
+ "index" 1 # line/mark index
524
+ "type" 1 # line type
525
+ "label" nil # if a String is given, it is shown as the label
526
+ "max" nil # maximum data value
527
+ "min" nil # minimum data value
528
+ "legend" nil # legend to annotate the line type and index. nil
529
+ # (defalut -- do not show); a String as the legend;
530
+ # true to use the name of the GPhys as the legend
531
+ "legend_vx" nil # (effective if legend) viewport x values of
532
+ # the lhs of the legend line (positive float); or
533
+ # nil for automatic settting (shown to the right of
534
+ # vpt); or move it to the left relatively (negtive
535
+ # float)
536
+ "legend_dx" nil # (effective if legend) length of the legend
537
+ # line
538
+ "legend_vy" nil # (effective if legend) viewport y value of the
539
+ # legend (Float; or nil for automatic settting)
540
+ "legend_size" nil # (effective if legend) character size of the
541
+ # legend
542
+ "map_axes" false # [USE IT ONLY WHEN itr=10 (cylindrical)] If
543
+ # true, draws axes by temprarilly switching to
544
+ # itr=1 and calling GGraph::axes.
545
+ "help" false # show help message if true
546
+
547
+ RETURN VALUE
548
+ * nil
549
+
550
+ ---mark(gphys, newframe=true, options=nil)
551
+ Similar to ((<line>)) but plots marks instead of drawing a poly-line.
552
+
553
+ ARGUMENTS
554
+ * gphys (GPhys) : a GPhys whose data is plotted.
555
+ * newframe (true/false) : if true, calls ((<fig>)), ((<axes>)),
556
+ ((<title>)), and ((<annotate>)) internally; if false, only
557
+ the poly-line is drawn (overlaid to the exiting figure).
558
+ * options (Hash) : options to change the default behavior if specified.
559
+ It is a Hash with option names (String) as keys and their values.
560
+ Options are interpreted by a NumRu::Misc::KeywordOptAutoHelp,
561
+ so you can shorten the keys (by omitting tails) as long as it is
562
+ unambiguous.
563
+ option name default value # description:
564
+ "title" nil # Title of the figure(if nil, internally
565
+ # determined)
566
+ "annotate" true # if false, do not put texts on the right
567
+ # margin even when newframe==true
568
+ "exchange" false # whether to exchange x and y axes
569
+ "index" 1 # mark index
570
+ "type" 2 # mark type
571
+ "size" 0.01 # marks size
572
+ "max" nil # maximum data value
573
+ "min" nil # minimum data value
574
+ "legend" nil # legend to annotate the mark type, index, and
575
+ # size. nil (defalut -- do not to show); a String
576
+ # as the legend; true to use the name of the GPhys
577
+ # as the legend
578
+ "legend_vx" nil # (effective if legend) viewport x values of
579
+ # the lhs of the legend line (positive float); or
580
+ # nil for automatic settting (shown to the right of
581
+ # vpt); or move it to the left relatively (negtive
582
+ # float)
583
+ "legend_vy" nil # (effective if legend) viewport y value of the
584
+ # legend (Float; or nil for automatic settting)
585
+ "legend_size" nil # (effective if legend) character size of the
586
+ # legend
587
+ "map_axes" false # [USE IT ONLY WHEN itr=10 (cylindrical)] If
588
+ # true, draws axes by temprarilly switching to
589
+ # itr=1 and calling GGraph::axes.
590
+ "help" false # show help message if true
591
+
592
+ RETURN VALUE
593
+ * nil
594
+
595
+ ---tone_and_contour(gphys, newframe=true, options=nil)
596
+ Calls ((<tone>)) and ((<contour>)) successively. You can
597
+ specify the options for any of these.
598
+
599
+ NOTE:
600
+ * The option keys that are not existent in these methods
601
+ are simply neglected -- thus no spell-check-like feedback
602
+ is made, contrary to the indivisual call of contour or tone.
603
+ Also, only the help menu of ((<tone>)) can be shown.
604
+ * Requires numru-misc-0.0.6 or later.
605
+
606
+ ---contour(gphys, newframe=true, options=nil)
607
+ Contour plot by selecting the first 2 dimensions (with GPhys#first2D)
608
+ if (({gphys})) is more than 3D.
609
+
610
+ Contour levels are determined as follows:
611
+ * contour levels are set in this method if not set by
612
+ ((<set_contour_levels>)) or the option (({"levels"})) is specified
613
+ explicitly.
614
+ * When contour levels are set in this method, the option (({"levels"}))
615
+ has the highest precedence. If it is specified, options
616
+ (({"index"})), (({"line_type"})), (({"label"})), and (({"label_height"}))
617
+ are used.
618
+ If (({"levels"})) are not specified, contour levels with a linear
619
+ increment are set by using the options (({"min"})), (({"max"})),
620
+ (({"nlev"})), (({"interval"})), (({"nozero"})), (({"coloring"})),
621
+ (({"clr_min"})), and (({"clr_max"})), which are interpreted by
622
+ DCLExt::((<ud_set_linear_levs>)). The default values
623
+ of the linear level setting can be changed with
624
+ ((<set_linear_contour_options>)).
625
+
626
+ ARGUMENTS
627
+ * gphys (GPhys) : a GPhys whose data is plotted.
628
+ * newframe (true/false) : if true, calls ((<fig>)), ((<axes>)) (or ((<map>))),
629
+ ((<title>)), and ((<annotate>)) internally; if false, only
630
+ the poly-line is drawn (overlaid to the exiting figure).
631
+ * options (Hash) : options to change the default behavior if specified.
632
+ It is a Hash with option names (String) as keys and their values.
633
+ Options are interpreted by a NumRu::Misc::KeywordOptAutoHelp,
634
+ so you can shorten the keys (by omitting tails) as long as it is
635
+ unambiguous.
636
+ option name default value # description:
637
+ "title" nil # Title of the figure(if nil, internally
638
+ # determined)
639
+ "annotate" true # if false, do not put texts on the right
640
+ # margin even when newframe==true
641
+ "transpose" false # if true, exchange x and y axes
642
+ "exchange" false # same as the option transpose
643
+ "map_axes" false # [USE IT ONLY WHEN itr=10 (cylindrical)] If
644
+ # true, draws axes by temprarilly switching to
645
+ # itr=1 and calling GGraph::axes.
646
+ "keep" false # Use the contour levels used previously
647
+ "min" nil # minimum contour level
648
+ "max" nil # maximum contour level
649
+ "nlev" nil # number of levels
650
+ "interval" nil # contour interval
651
+ "nozero" nil # delete zero contour
652
+ "coloring" false # set color contours with ud_coloring
653
+ "clr_min" 13 # (if coloring) minimum color number for the
654
+ # minimum data values
655
+ "clr_max" 99 # (if coloring) maximum color number for the
656
+ # maximum data values
657
+ "help" false # show help message if true
658
+ "levels" nil # contour levels (Array/NArray of Numeric)
659
+ "index" nil # (if levels) line index(es) (Array/NArray of
660
+ # integers, Integer, or nil)
661
+ "line_type" nil # (if levels) line type(s) (Array/NArray of
662
+ # integers, Integer, or nil)
663
+ "label" nil # (if levels) contour label(s) (Array/NArray of
664
+ # String, String, true, false, nil). nil is
665
+ # recommended.
666
+ "label_height" nil # (if levels) label height(s)
667
+ # (Array/NArray of Numeric, Numeric, or nil).
668
+ # nil is recommended.
669
+
670
+ RETURN VALUE
671
+ * nil
672
+
673
+ ---set_contour_levels(options)
674
+ Set contour levels for ((<contour>)) explicitly by values with the option (({levels})).
675
+
676
+ ARGUMENTS
677
+ * options (Hash) : options to change the default behavior.
678
+ The option (({"levels"})) is mandatory (so it is not optional!).
679
+ Supported options are (({"levels"})), (({"index"})),
680
+ (({"line_type"})), (({"label"})), and (({"label_height"})).
681
+ See ((<contour>)) for their description.
682
+
683
+ ---clear_contour_levels
684
+ Clear contour levels set by ((<set_contour_levels>)).
685
+
686
+ ---set_linear_contour_options(options)
687
+ Change the default option values regarding linear contour level
688
+ setting in ((<contour>)).
689
+
690
+ ARGUMENTS
691
+ * options (Hash) : The usage is the same as (({options}))
692
+ for ((<contour>)) but supported options here are limited to
693
+ (({"min"})), (({"max"})), (({"nlev"})), (({"interval"})),
694
+ (({"nozero"})), (({"coloring"})), (({"clr_min"})), and (({"clr_max"})).
695
+
696
+ RETURN VALUE
697
+ * a Hash containing the values replaced (the ones before calling this
698
+ method)
699
+
700
+ ---next_linear_contour_options(options)
701
+ Similar to ((<set_linear_contour_options>)) but the setting
702
+ is effective only for the next call of ((<contour>)).
703
+
704
+ ---tone(gphys, newframe=true, options=nil)
705
+ Color tone or shading by selecting the first 2 dimensions
706
+ (with GPhys#first2D) if (({gphys})) is more than 3D.
707
+
708
+ Tone levels are determined as follows:
709
+ * Tone levels are set in this method if not set by
710
+ ((<set_tone_levels>)) or the option (({"levels"})) (and
711
+ optionally, (({"patterns"}))) is (are) specified explicitly.
712
+ * When contour levels & patterns are set in this method,
713
+ * (({"levels"})) has the highest precedence. If it is specified,
714
+ tone levels and patterns are determined by DCLExt::((<ue_set_tone>)).
715
+ Here, tone patterns can be specified with the option (({"patterns"})).
716
+ * Currently, option (({"patterns"})) is effective only if (({"levels"}))
717
+ is specified. Otherwise, it is ignored and patterns are
718
+ determined internally (by using DCL.uegtlb).
719
+ * If not, a linear tone levels are set if (({"ltone"=true}))
720
+ (this is the default), or shading is made if (({"ltone"=false})).
721
+ Shading is determined by following the parameters in the UDPACK
722
+ in DCL. Therefore, coloring is made if DCL.udpget('ltone')==true
723
+ regardless the option (({"ltone"=false})) here.
724
+ When linear levels are set in this method, options
725
+ (({"min"})), (({"max"})), (({"nlev"})), and (({"interval"}))
726
+ are used if specified, which are interpreted by
727
+ DCLExt::((<ue_set_linear_levs>)).
728
+ Their default values can be changed by
729
+ ((<set_linear_tone_options>)).
730
+
731
+ ARGUMENTS
732
+ * gphys (GPhys) : a GPhys whose data is plotted.
733
+ * newframe (true/false) : if true, calls ((<fig>)), ((<axes>)) (or ((<map>))),
734
+ ((<title>)), and ((<annotate>)) internally; if false, only
735
+ the poly-line is drawn (overlaid to the exiting figure).
736
+ * options (Hash) : options to change the default behavior if specified.
737
+ It is a Hash with option names (String) as keys and their values.
738
+ Options are interpreted by a NumRu::Misc::KeywordOptAutoHelp,
739
+ so you can shorten the keys (by omitting tails) as long as it is
740
+ unambiguous.
741
+ option name default value # description:
742
+ "title" nil # Title of the figure(if nil, internally
743
+ # determined)
744
+ "annotate" true # if false, do not put texts on the right
745
+ # margin even when newframe==true
746
+ "ltone" true # Same as udpack parameter ltone
747
+ "tonf" false # Use DCL.uetonf instead of DCL.uetone
748
+ "tonc" false # Use DCL.uetonc instead of DCL.uetone
749
+ "clr_min" nil # if an integer (in 10..99) is specified, used as
750
+ # the color number for the minimum data values.
751
+ # (the same can be done by setting the uepack
752
+ # parameter "icolor1")
753
+ "clr_max" nil # if an integer (in 10..99) is specified, used as
754
+ # the color number for the maximum data values.
755
+ # (the same can be done by setting the uepack
756
+ # parameter "icolor2")
757
+ "transpose" false # if true, exchange x and y axes
758
+ "exchange" false # same as the option transpose
759
+ "map_axes" false # [USE IT ONLY WHEN itr=10 (cylindrical)] If
760
+ # true, draws axes by temprarilly switching to
761
+ # itr=1 and calling GGraph::axes.
762
+ "keep" false # Use the tone levels and patterns used previously
763
+ "min" nil # minimum tone level
764
+ "max" nil # maximum tone level
765
+ "nlev" nil # number of levels
766
+ "interval" nil # contour interval
767
+ "help" false # show help message if true
768
+ "levels" nil # tone levels (Array/NArray of Numeric). Works
769
+ # together with patterns
770
+ "patterns" nil # tone patters (Array/NArray of Numeric). Works
771
+ # together with levels
772
+
773
+ RETURN VALUE
774
+ * nil
775
+
776
+ ---color_bar (options=nil)
777
+ * Descroption:
778
+ Draws color bars. Calls (({DCLext.color_bar})).
779
+
780
+ ---set_tone_levels(options)
781
+ Set tone levels for ((<tone>)) explicitly by values.
782
+
783
+ ARGUMENTS
784
+ * options (Hash) : options to change the default behavior.
785
+ Supported options are (({"levels"})) and (({"patterns"})).
786
+ Both of them must be specified explicitly (so they are
787
+ not optional!).
788
+
789
+ ---clear_tone_levels
790
+ Clear tone levels set by ((<set_tone_levels>)).
791
+
792
+ ---set_linear_tone_options(options)
793
+ Change the default option values regarding linear tone level
794
+ setting in ((<tone>)).
795
+
796
+ ARGUMENTS
797
+ * options (Hash) : The usage is the same as (({options}))
798
+ for ((<tone>)) but supported options here are limited to
799
+ (({"min"})), (({"max"})), (({"nlev"})), and (({"interval"})).
800
+
801
+ RETURN VALUE
802
+ * a Hash containing the values replaced (the ones before calling this
803
+ method)
804
+
805
+ ---next_linear_tone_options(options)
806
+ Similar to ((<set_linear_tone_options>)) but the setting
807
+ is effective only for the next call of ((<tone>)).
808
+
809
+ ---vector(fx, fy, newframe=true, options=nil)
810
+ 2-D vector plot using DCL_Ext::((<flow_vect>)),
811
+ which scales vectors in physical ("U") coordinates.
812
+
813
+ ARGUMENTS
814
+ * fx, fy (GPhys) : represent vectors
815
+ * newframe (true/false) : if true, calls ((<fig>)), ((<axes>)) (or ((<map>))),
816
+ ((<title>)), and ((<annotate>)) internally; if false, only
817
+ the poly-line is drawn (overlaid to the exiting figure).
818
+ * options (Hash) : options to change the default behavior if specified.
819
+ It is a Hash with option names (String) as keys and their values.
820
+ Options are interpreted by a NumRu::Misc::KeywordOptAutoHelp,
821
+ so you can shorten the keys (by omitting tails) as long as it is
822
+ unambiguous.
823
+ option name default value # description:
824
+ "title" nil # Title of the figure(if nil, internally
825
+ # determined)
826
+ "annotate" true # if false, do not put texts on the right
827
+ # margin even when newframe==true
828
+ "transpose" false # if true, exchange x and y axes
829
+ "exchange" false # same as the option transpose
830
+ "map_axes" false # [USE IT ONLY WHEN itr=10 (cylindrical)] If
831
+ # true, draws axes by temprarilly switching to
832
+ # itr=1 and calling GGraph::axes.
833
+ "flow_vect" true # If true, use DCLExt::flow_vect to draw
834
+ # vectors; otherwise, DCL::ugvect is used.
835
+ "flow_itr5" false # If true, use DCLExt::flow_itr5 to draw
836
+ # vectors; otherwise, DCLExt::flow_vect or
837
+ # DCL::ugvect is used.
838
+ "keep" false # Use the same vector scaling as in the previous
839
+ # call. -- Currently, works only when "flow_vect"
840
+ # is true
841
+ "xintv" 1 # (Effective only if flow_vect) interval of data
842
+ # sampling in x
843
+ "yintv" 1 # (Effective only if flow_vect) interval of data
844
+ # sampling in y
845
+ "factor" 1.0 # (Effective only if flow_vect) scaling factor to
846
+ # strech/reduce the arrow lengths
847
+ "unit_vect" false # Show the unit vector
848
+ "max_unit_vect" false # (Effective only if flow_vect &&
849
+ # unit_vect) If true, use the maximum arrows to
850
+ # scale the unit vector; otherwise, normalize in V
851
+ # coordinate.
852
+ "help" false # show help message if true
853
+
854
+ RETURN VALUE
855
+ * nil
856
+
857
+ =module NumRu::DCLExt
858
+
859
+ Collection of various compound DCL functions for convenience.
860
+ This module is to be separated but temporarily included in ggraph.rb
861
+ while it is premature.
862
+
863
+ ==Index
864
+ MATH1
865
+ * ((<glpack>))
866
+ GRPH1
867
+ * ((<sgpack>))
868
+ * ((<slpack>))
869
+ * ((<swpack>))
870
+ GRPH2
871
+ * ((<uzpack>))
872
+ * ((<ulpack>))
873
+ * ((<ucpack>))
874
+ * ((<uupack>))
875
+ * ((<uspack>))
876
+ * ((<udpack>))
877
+ * ((<uepack>))
878
+ * ((<ugpack>))
879
+ * ((<umpack>))
880
+
881
+ ==Module Functions
882
+
883
+ ===glpack
884
+ ---gl_set_params(hash)
885
+ Calls (({DCL.glpset})) multiple times (for each key and val of (({hash}))).
886
+
887
+ ARGUMENTS
888
+ * hash (Hash) : combinations of parameter names and values for udpset
889
+
890
+ RETURN VALUE
891
+ * a Hash containing the parameter names and their old values that were
892
+ replaced.
893
+
894
+ EXAMPLES
895
+ * You can modify parameters temporarily as follows.
896
+
897
+ before = DCLExt.gl_set_params({'lmiss'=>true,'rmiss'=>9999.0})
898
+ ....
899
+ DCLExt.gl_set_params(before) # reset the change
900
+
901
+ ===sgpack
902
+ ---sg_set_params(hash)
903
+ Calls (({DCL.sgpset})) multiple times (for each key and val of (({hash}))).
904
+
905
+ See ((<gl_set_params>)) for usage.
906
+
907
+ ===slpack
908
+ ---sl_set_params(hash)
909
+ Calls (({DCL.slpset})) multiple times (for each key and val of (({hash}))).
910
+
911
+ See ((<gl_set_params>)) for usage.
912
+
913
+ ===swpack
914
+ ---sw_set_params(hash)
915
+ Calls (({DCL.swpset})) multiple times (for each key and val of (({hash}))).
916
+
917
+ See ((<gl_set_params>)) for usage.
918
+
919
+ ===uzpack
920
+ ---uz_set_params(hash)
921
+ Calls (({DCL.uzpset})) multiple times (for each key and val of (({hash}))).
922
+
923
+ See ((<gl_set_params>)) for usage.
924
+
925
+ ===ulpack
926
+ ---ul_set_params(hash)
927
+ Calls (({DCL.ulpset})) multiple times (for each key and val of (({hash}))).
928
+
929
+ See ((<gl_set_params>)) for usage.
930
+
931
+ ===ucpack
932
+ ---uc_set_params(hash)
933
+ Calls (({DCL.ucpset})) multiple times (for each key and val of (({hash}))).
934
+
935
+ See ((<gl_set_params>)) for usage.
936
+
937
+ ===uupack
938
+ ---uu_set_params(hash)
939
+ Calls (({DCL.uupset})) multiple times (for each key and val of (({hash}))).
940
+
941
+ See ((<gl_set_params>)) for usage.
942
+
943
+ ===uspack
944
+ ---us_set_params(hash)
945
+ Calls (({DCL.uspset})) multiple times (for each key and val of (({hash}))).
946
+
947
+ See ((<gl_set_params>)) for usage.
948
+
949
+ ===udpack
950
+ ---ud_set_params(hash)
951
+ Calls (({DCL.udpset})) multiple times (for each key and val of (({hash}))).
952
+
953
+ ARGUMENTS
954
+ * hash (Hash) : combinations of parameter names and values for udpset
955
+
956
+ RETURN VALUE
957
+ * a Hash containing the parameter names and their old values that were
958
+ replaced.
959
+
960
+ EXAMPLES
961
+ * You can modify parameters temporarily as follows.
962
+
963
+ before = DCLExt.ud_set_params('indxmj'=>4,'lmsg'=>false)
964
+ DCL.udcntz(data)
965
+ DCLExt.ud_set_params(before) # reset the change
966
+
967
+ ---ud_set_linear_levs(v, options)
968
+ Set contour levels with a constant interval
969
+
970
+ ARGUMENTS
971
+ * v : Data values to be fed to udcnt[rz]
972
+ * options (Hash) : option specification by keys and values. Available
973
+ options are
974
+ name default value description
975
+ 'min' nil minimum contour value (Numeric)
976
+ 'max' nil maximum contour value (Numeric)
977
+ 'nlev' nil number of levels (Integer)
978
+ 'interval' nil contour interval (Numeric)
979
+ 'nozero' nil delete zero contour (true/false)
980
+ 'coloring' false set color contours with ud_coloring (true/false)
981
+ 'clr_min' 13 (if coloring) minimum color id (Integer)
982
+ 'clr_max' 99 (if coloring) maximum color id (Integer)
983
+ Here, (({interval})) has a higher precedence over (({nlev})).
984
+ Since all the default values are nil, only those explicitly specified
985
+ are interpreted. If no option is provided, the levels generated will
986
+ be the default ones set by udcnt[rz] without any level specification.
987
+
988
+ ---ud_set_contour(levels,index=nil,line_type=nil,label=nil,label_height=nil)
989
+ Set contours of at specified levels.
990
+
991
+ Normally you do not have to specify (({label})) and (({label_height})).
992
+
993
+ It calls DCL.udsclv for each level. So the arguments are basically
994
+ the same as DCL.udsclv, but only levels are mandatory here.
995
+
996
+ ARGUMENTS
997
+ * levels (Array, NArray, or Numeric) : contour levels to be set.
998
+ If Numeric, a single level is set.
999
+ * index (Array of integers, Integer, or nil) :
1000
+ index(es) of the contours. If it is an Array and its length is
1001
+ shorter than that of (({levels})), the same Array is repeated (so
1002
+ for instance [1,1,3] is interpreted as [1,1,3,1,1,3,1,1,3,...]).
1003
+ If it is a single Integer, all the contour will have the same index.
1004
+ If nil, the value of 'indxmn' is used.
1005
+ * line_type (Array of integers, Integer, or nil) :
1006
+ line type(s) of the contours. If it is an Array and its length is
1007
+ shorter than that of (({levels})), the same Array is repeated.
1008
+ the length must agree with that of (({levels})).
1009
+ If it is a single Integer, all the contour will have the same type.
1010
+ If nil, set to be 1.
1011
+ * label (Array of String, String, true, false, nil) :
1012
+ Label(s) of the contours. If it is an Array and its length is
1013
+ shorter than that of (({levels})), the same Array is repeated.
1014
+ the length must agree with that of (({levels})).
1015
+ If it is a single String, all the contour will have the same label.
1016
+ If true, all the contours will have the labels representing the levels.
1017
+ If false, no label will be drawn (set to "").
1018
+ If nil, same as true for the contours whose index is equal to "INDXMJ",
1019
+ and same as false otherwise.
1020
+ * label_height (Array of Numeric, Numeric, or nil) :
1021
+ Heigh of Labels. Normally you do not have to use this.
1022
+ If it is an Array and its length is
1023
+ shorter than that of (({levels})), the same Array is repeated.
1024
+ If nil, the default value ("RSIZEL") is used for non-empty labels.
1025
+ If a single Numeric, the same value is used for all the contours.
1026
+ Note that it is recommended to not to use this parameter but
1027
+ use DCL.udpset('RZISEL'. label_height), since a positive value
1028
+ here always means to draw labels even when the label is empty.
1029
+
1030
+ RETURN VALUE
1031
+ * nil
1032
+
1033
+ ---ud_add_contour(levels,index=nil,line_type=nil,label=nil,label_height=nil)
1034
+ Same as ((<ud_set_contour>)), but does not clear the contour levels that have
1035
+ been set.
1036
+
1037
+ ===uepack
1038
+ ---ue_set_params(hash)
1039
+ Calls (({DCL.uepset})) multiple times (for each key and val of (({hash}))).
1040
+
1041
+ See ((<gl_set_params>)) for usage.
1042
+
1043
+ ---ue_set_linear_levs(v, options)
1044
+ Set tone levels with a constant interval
1045
+
1046
+ ARGUMENTS
1047
+ * v : Data values to be fed to udcnt[rz]
1048
+ * options (Hash) : option specification by keys and values. Available
1049
+ options are
1050
+ name default value description
1051
+ 'min' nil minimum tone level (Numeric)
1052
+ 'max' nil maximum tone level (Numeric)
1053
+ 'nlev' nil number of levels (Integer)
1054
+ 'interval' nil tone-level interval (Numeric)
1055
+ Here, (({interval})) has a higher precedence over (({nlev})).
1056
+ Since all the default values are nil, only those explicitly specified
1057
+ are interpreted. If no option is provided, the levels generated will
1058
+ be the default ones set by udcnt[rz] without any level specification.
1059
+
1060
+ ---ue_set_tone(levels, patterns)
1061
+ Set tone levels and patterns.
1062
+
1063
+ patterns are set between levels as follows:
1064
+
1065
+ when (levels.length == patterns.length+1)
1066
+
1067
+ levels[0] | levels[1] | levels[2] ... | levels[-2] | levels[-1]
1068
+ patterns[0] patterns[1] ... patterns[-2] patterns[-1]
1069
+
1070
+ when (levels.length == patterns.length)
1071
+
1072
+ levels[0] | levels[1] | levels[2] ... | levels[-1] | +infty
1073
+ patterns[0] patterns[1] ... patterns[-2] patterns[-1]
1074
+
1075
+ when (levels.length == patterns.length-1)
1076
+
1077
+ -infty | levels[0] | levels[1] ... | levels[-1] | +infty
1078
+ patterns[0] patterns[1] ... patterns[-2] patterns[-1]
1079
+
1080
+ else
1081
+ error (exception raised)
1082
+
1083
+ ARGUMENTS
1084
+ * levels (Array or NArray of Numeric) : tone levels. Its length must be
1085
+ either 1 larger than, equal to, or 1 smaller than the length of patterns
1086
+ * patterns (Array or NArray of Numeric) : tone patterns
1087
+
1088
+ RETURN VALUE
1089
+ * nil
1090
+
1091
+ ---ue_add_tone(levels, patterns)
1092
+ Same as ((<ue_set_tone>)), but does not clear the tone levels that have
1093
+ been set.
1094
+
1095
+ ===ugpack
1096
+ ---ug_set_params(hash)
1097
+ Calls (({DCL.ugpset})) multiple times (for each key and val of (({hash}))).
1098
+ See ((<gl_set_params>)) for usage.
1099
+
1100
+ ===umpack
1101
+ ---um_set_params(hash)
1102
+ Calls (({DCL.umpset})) multiple times (for each key and val of (({hash}))).
1103
+
1104
+ See ((<gl_set_params>)) for usage.
1105
+
1106
+ ==Original methods:
1107
+
1108
+ ===Longitude/Latitude Axes
1109
+ ---lon_ax( options=nil )
1110
+
1111
+ Draw longitude axis. (label format: degrees + 'E' or 'W')
1112
+
1113
+ ARGUMENTS
1114
+ * options (Hash) : options to change the default behavior if specified.
1115
+ It is a Hash with option names (String) as keys and their values.
1116
+ Options are interpreted by a NumRu::Misc::KeywordOptAutoHelp,
1117
+ so you can shorten the keys (by omitting tails) as long as it is
1118
+ unambiguous.
1119
+ option name default value # description:
1120
+ "yax" false # true => draw y-axis, false => draw x-axis
1121
+ "cside" nil # "b", "t", "l", "r",
1122
+ # nil (=>left/bottom), or false (=>right/top)
1123
+ "dtick1" nil # Interval of small tickmark
1124
+ # (if nil, internally determined)
1125
+ "dtick2" nil # Interval of large tickmark with labels
1126
+ # (if nil, internally determined)
1127
+
1128
+ ---lat_ax( options=nil )
1129
+
1130
+ Draw latitude axis. (label format: degrees + 'N' or 'S')
1131
+
1132
+ ARGUMENTS
1133
+ * options (Hash) : options to change the default behavior if specified.
1134
+ It is a Hash with option names (String) as keys and their values.
1135
+ Options are interpreted by a NumRu::Misc::KeywordOptAutoHelp,
1136
+ so you can shorten the keys (by omitting tails) as long as it is
1137
+ unambiguous.
1138
+ option name default value # description:
1139
+ "xax" false # true => draw x-axis, false => draw y-axis
1140
+ "cside" nil # "b", "t", "l", "r",
1141
+ # nil (=>left/bottom), or false (=>right/top)
1142
+ "dtick1" nil # Interval of small tickmark
1143
+ # (if nil, internally determined)
1144
+ "dtick2" nil # Interval of large tickmark with labels
1145
+ # (if nil, internally determined)
1146
+
1147
+ ===Vectors
1148
+ ---unit_vect( vxfxratio, vyfyratio, fxunit=nil, fyunit=nil, options=nil )
1149
+
1150
+ Show the "unit vector", which indicate the vector scaling.
1151
+
1152
+ ARGUMENTS
1153
+ * vxfxratio (Float) : (V cood length)/(actual length) in x
1154
+ * vyfyratio (Float) : (V cood length)/(actual length) in y
1155
+ * fxunit (Float) : If specified, x unit vect len
1156
+ * fyunit (Float) : If specified, y unit vect len
1157
+ * options (Hash) : options to change the default behavior if specified.
1158
+ It is a Hash with option names (String) as keys and their values.
1159
+ Options are interpreted by a NumRu::Misc::KeywordOptAutoHelp,
1160
+ so you can shorten the keys (by omitting tails) as long as it is
1161
+ unambiguous.
1162
+ option name default value # description:
1163
+ "vxunit" 0.05 # x unit vect len in V coord. Used only when
1164
+ # fxunit is omitted (default)
1165
+ "vyunit" 0.05 # y unit vect len in V coord. Used only when
1166
+ # fyunit is omitted (default)
1167
+ "vxuloc" nil # Starting x position of unit vect
1168
+ "vyuloc" nil # Starting y position of unit vect
1169
+ "vxuoff" 0.05 # Specify vxuloc by offset from right-bottom
1170
+ # corner
1171
+ "vyuoff" 0.0 # Specify vyuloc by offset from right-bottom
1172
+ # corner
1173
+ "inplace" true # Whether to print labels right by the unit
1174
+ # vector (true) or below the x axis (false)
1175
+ "rsizet" nil # Label size(default taken from uz-parameter
1176
+ # 'rsizel1')
1177
+ "index" 3 # Line index of the unit vector
1178
+ "help" false # show help message if true
1179
+
1180
+ ---set_unit_vect_options(options)
1181
+ Change the default option values for ((<unit_vect>)).
1182
+
1183
+ ---next_unit_vect_options(options)
1184
+ Set the option values effective only in the next call of ((<unit_vect>))
1185
+
1186
+ ---flow_vect( fx, fy, factor=1.0, xintv=1, yintv=1)
1187
+
1188
+ 2D Vector plot. Unlike (({DCL::ugvect})), scaling are made in term of the physical (or "U") coordinate.
1189
+
1190
+ This method is meant to substitute (({DCL::ugvect})). The scaling
1191
+ is made in terms of the U coordinate. This method is suitable to
1192
+ show vectors such as velocity, since the arrow direction represets
1193
+ the direction in the U coordinate. Also, one can re-scale the
1194
+ vector length easily by using the argument (({factor})).
1195
+
1196
+ Currently, this method is not compatible with map projection,
1197
+ since it calls (({DCL::ugvect})) internally.
1198
+
1199
+ ARGUMENTS
1200
+ * fx, fy (2D NArray or Array) : the vector field.
1201
+ * factor (Integer) : factor to change the arrow length.
1202
+ By default, arrows are scaled so that the longest one
1203
+ match the grid interval.
1204
+ * xintv, yintv (Interger) : interval to thin out (({fx})) and (({fy})),
1205
+ respectively. Useful if the grid points are too many.
1206
+
1207
+ ---flow_itr5( fx, fy, factor=1.0, unit_vect=false )
1208
+
1209
+ 2D Vector plot on the polar coodinate.
1210
+
1211
+ This method just perform rotatation of the vector in U-coordinate
1212
+ to N-coordinate and passed to DCL.ugvect.
1213
+
1214
+ ARGUMENTS
1215
+ * fx, fy (2D GPhys) : the vector field.
1216
+ * factor (Integer) : factor for scaling in ugvect. When it equals 1,
1217
+ vector field will be scaled in DCL.ugvect automatically.
1218
+ * unit_vect() : Show the unit vector
1219
+
1220
+ ===Color bars
1221
+ ---set_color_bar_options(options)
1222
+ To set options of ((<color_bar>)) effective in the rest.
1223
+
1224
+ ---color_bar(options=nil)
1225
+ * Descroption:
1226
+ Draws color bars
1227
+
1228
+ * Example
1229
+ Here is the simplest case, where no argument is given to color_bar.
1230
+
1231
+ DCL.uetone(hoge)
1232
+ DCL.usdaxs
1233
+ ...
1234
+ DCL.color_bar
1235
+
1236
+ This draws a color bar by using the levels and tone patterns(colors)
1237
+ set previously. There are many parameters you can set manually,
1238
+ as introduced below:
1239
+
1240
+ * Description of options
1241
+ option name default value # description:
1242
+ "levels" nil # tone levels (if omitted, latest ones are used)
1243
+ "patterns" nil # tone patterns (~colors) (if omitted, latest
1244
+ # ones are used)
1245
+ "voff" nil # how far is the bar from the viewport in the V
1246
+ # coordinate
1247
+ "vcent" nil # center position of the bar in the V coordinate
1248
+ # (VX or VY)
1249
+ "vlength" 0.3 # bar length in the V coordinate
1250
+ "vwidth" 0.02 # bar width in the V coordinate
1251
+ "landscape" false # if true, horizonlly long (along x axes)
1252
+ "portrait" true # if true, vertically long (along y axes)
1253
+ "top" false # place the bar at the top (effective if
1254
+ # landscape)
1255
+ "left" false # place the bar in the left (effective if
1256
+ # portrait)
1257
+ "units" nil # units of the axis of the color bar
1258
+ "title" nil # title of the color bar
1259
+ "tickintv" 1 # 0,1,2,3,.. to specify how frequently the
1260
+ # dividing tick lines are drawn (0: no tick lines,
1261
+ # 1: every time, 2: ever other:,...)
1262
+ "labelintv" nil # 0,1,2,3,.. to specify how frequently labels are
1263
+ # drawn (0: no labels, 1: every time, 2: ever
1264
+ # other:,... default: internally determined)
1265
+ "labels_ud" nil # user-defined labels for replacing the default
1266
+ # labels (Array of String)
1267
+ "charfact" 0.9 # factor to change the label/units/title character
1268
+ # size (relative to 'rsizel1'/'rsizel1'/'rsizec1')
1269
+ "log" false # set the color bar scale to logarithmic
1270
+ "constwidth" false # if true, each color is drawn with the same width
1271
+ "index" nil # line index of tick lines and bar frame
1272
+ "charindex" nil # line index of labels, units, and title
1273
+ "chval_fmt" nil # string to specify the DCL.chval format for
1274
+ # labeling
1275
+ "help" false # show help message if true
1276
+
1277
+ =end
1278
+ ############################################################
1279
+
1280
+ module NumRu
1281
+
1282
+ module DCLExt
1283
+ # to be included in the RubyDCL distribution
1284
+
1285
+ module_function
1286
+
1287
+ #<<< for many packages >>>
1288
+
1289
+ %w!gl sg sl sw uz ul uc uu us ud ue ug um!.each do |pkg|
1290
+ eval <<-EOS, nil, __FILE__, __LINE__+1
1291
+ def #{pkg}_set_params(hash)
1292
+ before = Hash.new
1293
+ hash.each{|k,v|
1294
+ before[k]=DCL.#{pkg}pget(k)
1295
+ if(v.is_a? String) then
1296
+ DCL.#{pkg}cset(k,v)
1297
+ else
1298
+ DCL.#{pkg}pset(k,v)
1299
+ end
1300
+ }
1301
+ before
1302
+ end
1303
+ EOS
1304
+ end
1305
+
1306
+ #<<< module data >>>
1307
+
1308
+ @@empty_hash = Hash.new
1309
+
1310
+ #<<< udpack >>>
1311
+
1312
+ def ud_coloring(clr_min=13, clr_max=99)
1313
+ # change the colors of existing contours to make a gradation
1314
+ # (rainbow colors with the default color map).
1315
+ nlev = DCL.udqcln
1316
+ cont_params = Array.new
1317
+ for i in 1..nlev
1318
+ cont_params.push( DCL.udqclv(i) ) # => [zlev,indx,ityp,clv,hl]
1319
+ end
1320
+ DCL.udiclv # clear the contours
1321
+
1322
+ colors = clr_min +
1323
+ NArray.int(nlev).indgen! * (clr_max-clr_min) / nlev
1324
+
1325
+ cont_params.sort!
1326
+ for i in 0...nlev
1327
+ cont_params[i][1] += colors[i]*10 # indx += colors[i]*10
1328
+ DCL.udsclv(*cont_params[i])
1329
+ end
1330
+ end
1331
+
1332
+ def ud_set_linear_levs(v, options=nil)
1333
+ #Accepted options
1334
+ # name default description
1335
+ # 'min' nil minimum contour value (Numeric)
1336
+ # 'max' nil maximum contour value (Numeric)
1337
+ # 'nlev' nil number of levels (Integer)
1338
+ # 'interval' nil contour interval (Numeric)
1339
+ # 'nozero' false delete zero contour (true/false)
1340
+ # 'coloring' false set color contours with ud_coloring (true/false)
1341
+ # 'clr_min' 13 (if coloring) minimum color number for the
1342
+ # maximum data values (Integer)
1343
+ # 'clr_max' 99 (if coloring) maximum color number for the
1344
+ # maximum data values (Integer)
1345
+ options = @@empty_hash if !options
1346
+ raise TypeError, "options must be a Hash" if !options.is_a?(Hash)
1347
+ min = options['min']
1348
+ max = options['max']
1349
+ nlev = options['nlev']
1350
+ interval = options['interval']
1351
+ nozero = options['nozero']
1352
+ if interval
1353
+ dx = interval
1354
+ elsif nlev
1355
+ dx = -nlev
1356
+ else
1357
+ dx = 0
1358
+ end
1359
+ if min || max
1360
+ min = v.min if !min
1361
+ max = v.max if !max
1362
+ DCL.udgcla(min, max, dx)
1363
+ else
1364
+ DCL.udgclb(v, dx)
1365
+ end
1366
+ if nozero
1367
+ DCL.uddclv(0.0)
1368
+ end
1369
+ if options['coloring']
1370
+ clr_min = ( options['clr_min'] || 13 )
1371
+ clr_max = ( options['clr_max'] || 99 )
1372
+ ud_coloring( clr_min, clr_max )
1373
+ end
1374
+ end
1375
+
1376
+ def ud_set_contour(*args)
1377
+ DCL.udiclv
1378
+ ud_add_contour(*args)
1379
+ end
1380
+
1381
+ def ud_add_contour(levels,index=nil,line_type=nil,label=nil,label_height=nil)
1382
+
1383
+ # < check levels >
1384
+ case levels
1385
+ when Array, NArray
1386
+ # This is expected. Nothing to do.
1387
+ when Numric
1388
+ levels = [levels]
1389
+ else
1390
+ raise ArgumentError, "invalid level specification (#{levels})"
1391
+ end
1392
+
1393
+ nlev = levels.length
1394
+
1395
+ # < index >
1396
+ index = index.to_a if index.is_a?(NArray)
1397
+ case index
1398
+ when Array
1399
+ raise ArgumentError, "index is an empty array" if index.length == 0
1400
+ while (index.length < nlev )
1401
+ index += index
1402
+ end
1403
+ when Numeric
1404
+ index = [index]*nlev
1405
+ when nil
1406
+ index = [DCL.udpget('indxmn')]*nlev
1407
+ else
1408
+ raise ArgumentError, "unsupported index type (#{index.class})"
1409
+ end
1410
+
1411
+ # < line_type >
1412
+ line_type = line_type.to_a if line_type.is_a?(NArray)
1413
+ case line_type
1414
+ when Array
1415
+ raise ArgumentError, "line_type is an empty array" if line_type.length == 0
1416
+ while (line_type.length < nlev )
1417
+ line_type += line_type
1418
+ end
1419
+ when Numeric
1420
+ line_type = [line_type]*nlev
1421
+ when nil
1422
+ line_type = [1]*nlev
1423
+ else
1424
+ raise ArgumentError, "unsupported index type (#{index.class})"
1425
+ end
1426
+
1427
+ # < label >
1428
+ label = label.to_a if label.is_a?(NArray)
1429
+ case label
1430
+ when Array
1431
+ raise ArgumentError, "label is an empty array" if label.length == 0
1432
+ while (label.length < nlev )
1433
+ label += label
1434
+ end
1435
+ when String
1436
+ label = [label]*nlev
1437
+ when false
1438
+ label = [""]*nlev
1439
+ when true
1440
+ label = (0...nlev).collect{|i|
1441
+ DCL.udlabl(levels[i])
1442
+ }
1443
+ when nil
1444
+ indxmj = DCL.udpget('indxmj')
1445
+ label = (0...nlev).collect{|i|
1446
+ if index[i]==indxmj
1447
+ DCL.udlabl(levels[i])
1448
+ else
1449
+ ""
1450
+ end
1451
+ }
1452
+ else
1453
+ raise ArgumentError, "unsupported index type (#{index.class})"
1454
+ end
1455
+
1456
+ # < label_height >
1457
+ label_height = label_height.to_a if label_height.is_a?(NArray)
1458
+ case label_height
1459
+ when Array
1460
+ raise ArgumentError, "label_height is an empty array" if label_height.length == 0
1461
+ while (label_height.length < nlev )
1462
+ label_height += label_height
1463
+ end
1464
+ when Numeric
1465
+ label_height = [label_height]*nlev
1466
+ when nil
1467
+ label_height = label.collect{|lv| lv=="" ? 0.0 : DCL.udpget('rsizel')}
1468
+ else
1469
+ raise ArgumentError, "unsupported index type (#{index.class})"
1470
+ end
1471
+
1472
+ # < set levels >
1473
+
1474
+ for i in 0...nlev
1475
+ DCL.udsclv(levels[i],index[i],line_type[i],label[i],label_height[i])
1476
+ end
1477
+ nil
1478
+ end
1479
+
1480
+ #<<< uepack >>>
1481
+
1482
+ def ue_set_linear_levs(v, options=nil)
1483
+ # 'min' nil minimum tone level (Numeric)
1484
+ # 'max' nil maximum tone level (Numeric)
1485
+ # 'nlev' nil number of levels (Integer)
1486
+ # 'interval' nil tone-level interval (Numeric)
1487
+ options = @@empty_hash if !options
1488
+ raise TypeError, "options must be a Hash" if !options.is_a?(Hash)
1489
+ min = options['min']
1490
+ max = options['max']
1491
+ nlev = options['nlev']
1492
+ interval = options['interval']
1493
+ if interval
1494
+ dx = interval
1495
+ elsif nlev
1496
+ dx = -nlev
1497
+ else
1498
+ dx = 0
1499
+ end
1500
+ if min || max
1501
+ min = v.min if !min
1502
+ max = v.max if !max
1503
+ DCL.uegtla(min, max, dx)
1504
+ else
1505
+ DCL.uegtlb(v, dx)
1506
+ end
1507
+ end
1508
+
1509
+ def ue_set_tone(levels, patterns)
1510
+ DCL.ueitlv
1511
+ ue_add_tone(levels, patterns)
1512
+ end
1513
+
1514
+ def ue_add_tone(levels, patterns)
1515
+
1516
+ # < check types >
1517
+
1518
+ if !levels.is_a?(Array) && !levels.is_a?(NArray)
1519
+ raise TypeError, "levels: Array or NArray expected (#{levels.inspect})"
1520
+ end
1521
+ if !patterns.is_a?(Array) && !patterns.is_a?(NArray)
1522
+ raise TypeError, "patterns: Array or NArray expected (#{patterns.inspect})"
1523
+ end
1524
+
1525
+ # < set levels >
1526
+
1527
+ nlev = levels.length
1528
+ npat = patterns.length
1529
+
1530
+ case (nlev - npat)
1531
+ when 1
1532
+ for i in 0...nlev-1
1533
+ DCL.uestlv(levels[i],levels[i+1],patterns[i])
1534
+ end
1535
+ when 0
1536
+ for i in 0...nlev-1
1537
+ DCL.uestlv(levels[i],levels[i+1],patterns[i])
1538
+ end
1539
+ DCL.uestlv(levels[-1],DCL.glpget('rmiss'),patterns[-1])
1540
+ when -1
1541
+ DCL.uestlv(DCL.glpget('rmiss'),levels[0],patterns[0])
1542
+ for i in 1...nlev
1543
+ DCL.uestlv(levels[i-1],levels[i],patterns[i])
1544
+ end
1545
+ DCL.uestlv(levels[-1],DCL.glpget('rmiss'),patterns[-1])
1546
+ else
1547
+ raise ArgumentError,
1548
+ "lengths of levels(#{nlev}) and patterns(#{npat}) are inconsistent"
1549
+ end
1550
+ nil
1551
+ end
1552
+
1553
+ ############################################################
1554
+ # RELATIVELY INDEPENDENT OF DCL SUBLIBRARIES
1555
+ ############################################################
1556
+
1557
+ # <<< longitude/latitude axes package >>>
1558
+
1559
+ @@lon_ax_options = Misc::KeywordOptAutoHelp.new(
1560
+ ['yax', false, 'true => y-axis, false => x-axis'],
1561
+ ['cside', nil, '"b", "t", "l", "r", nil (=>left/bottom), or false (=>right/top)'],
1562
+ ['dtick1', nil, 'Interval of small tickmark (if nil, internally determined)'],
1563
+ ['dtick2', nil, 'Interval of large tickmark with labels (if nil, internally determined)']
1564
+ )
1565
+
1566
+ def lon_ax(options=nil)
1567
+ opt = @@lon_ax_options.interpret(options)
1568
+
1569
+ yax = opt['yax']
1570
+ xax = !yax
1571
+ if xax
1572
+ xy='x'
1573
+ else
1574
+ xy='y'
1575
+ end
1576
+
1577
+ if opt['cside']
1578
+ cside = opt['cside']
1579
+ elsif opt['cside'].nil?
1580
+ if xax
1581
+ cside='b'
1582
+ else
1583
+ cside='l'
1584
+ end
1585
+ else
1586
+ if xax
1587
+ cside='t'
1588
+ else
1589
+ cside='r'
1590
+ end
1591
+ end
1592
+
1593
+ vxmin, vxmax, vymin, vymax = DCL.sgqvpt
1594
+ uxmin, uxmax, uymin, uymax = DCL.sgqwnd
1595
+ if xax
1596
+ vmin, vmax = [vxmin,vxmax].min, [vxmin,vxmax].max
1597
+ umin, umax = [uxmin,uxmax].min, [uxmin,uxmax].max
1598
+ else
1599
+ vmin, vmax = [vymin,vymax].min, [vymin,vymax].max
1600
+ umin, umax = [uymin,uymax].min, [uymin,uymax].max
1601
+ end
1602
+
1603
+ # get dtick1 & dtick2
1604
+ dtick1 = opt['dtick1']
1605
+ dtick2 = opt['dtick2']
1606
+ unless dtick1 && dtick2
1607
+ irota = DCL.uzpget("irotl#{xy}#{cside}")
1608
+ irota += 1 if yax
1609
+ mode = irota.modulo(2)
1610
+ DCL.ususcu(xy.capitalize,umin,umax,vmin,vmax,mode)
1611
+ dtick1 = DCL.uspget("d#{xy}t") unless dtick1
1612
+ dtick2 = DCL.uspget("d#{xy}l") unless dtick2
1613
+ end
1614
+
1615
+ lepsl = DCL.glpget('lepsl')
1616
+ repsl = DCL.glpget('repsl')
1617
+ DCL.glpset('lepsl',true)
1618
+
1619
+ # generate numbers for small tickmarks
1620
+ nn = 0
1621
+ rx = DCL.irle(umin/dtick1)*dtick1
1622
+ if DCL.lreq(umin,rx)
1623
+ x = rx
1624
+ else
1625
+ x = rx + dtick1
1626
+ end
1627
+ u1 = []
1628
+ while DCL.lrle(x,umax)
1629
+ if x.abs < dtick1*repsl*nn
1630
+ x = 0.0
1631
+ end
1632
+ u1[nn] = x
1633
+ nn = nn + 1
1634
+ x = x + dtick1
1635
+ end
1636
+
1637
+ # generate numbers for large tickmarks and labels
1638
+ nn = 0
1639
+ rx = DCL.irle(umin/dtick2)*dtick2
1640
+ if DCL.lreq(umin,rx)
1641
+ x = rx
1642
+ else
1643
+ x = rx + dtick2
1644
+ end
1645
+ u2 = []
1646
+ while DCL.lrle(x,umax)
1647
+ if x.abs < dtick2*repsl*nn
1648
+ x = 0
1649
+ end
1650
+ u2[nn] = x
1651
+ nn = nn + 1
1652
+ x = x + dtick2
1653
+ end
1654
+
1655
+ # generate labels
1656
+ c2 = NArray.to_na(u2)
1657
+ c2[c2.gt(180)] -= 360.0
1658
+ c2[c2.lt(-180)] += 360.0
1659
+ c2[c2.eq(-180)] = 180.0
1660
+ c2 = c2.to_a.collect do |c|
1661
+ if c == 0 || c == 180
1662
+ c.to_i.to_s
1663
+ elsif c > 0
1664
+ c.to_i.to_s + 'E'
1665
+ else
1666
+ c.abs.to_i.to_s + 'W'
1667
+ end
1668
+ end
1669
+ nc = c2.collect{|c| c.size}.max
1670
+
1671
+ # call DCL.u[xy]axlb
1672
+ if xax
1673
+ DCL.uxaxlb(cside,u1,u2,c2,nc)
1674
+ else
1675
+ DCL.uyaxlb(cside,u1,u2,c2,nc)
1676
+ end
1677
+ end
1678
+
1679
+ @@lat_ax_options = Misc::KeywordOptAutoHelp.new(
1680
+ ['xax', false, 'true => x-axis, false => y-axis'],
1681
+ ['cside', nil, '"b", "t", "l", "r", nil (=>left/bottom), or false (=>right/top)'],
1682
+ ['dtick1', nil, 'Interval of small tickmark (if nil, internally determined)'],
1683
+ ['dtick2', nil, 'Interval of large tickmark with labels (if nil, internally determined)']
1684
+ )
1685
+
1686
+ def lat_ax(options=nil)
1687
+ opt = @@lat_ax_options.interpret(options)
1688
+
1689
+ xax = opt['xax']
1690
+ yax = !xax
1691
+ if xax
1692
+ xy='x'
1693
+ else
1694
+ xy='y'
1695
+ end
1696
+
1697
+ if opt['cside']
1698
+ cside = opt['cside']
1699
+ elsif opt['cside'].nil?
1700
+ if xax
1701
+ cside='b'
1702
+ else
1703
+ cside='l'
1704
+ end
1705
+ else
1706
+ if xax
1707
+ cside='t'
1708
+ else
1709
+ cside='r'
1710
+ end
1711
+ end
1712
+
1713
+ vxmin, vxmax, vymin, vymax = DCL.sgqvpt
1714
+ uxmin, uxmax, uymin, uymax = DCL.sgqwnd
1715
+ if xax
1716
+ vmin, vmax = [vxmin,vxmax].min, [vxmin,vxmax].max
1717
+ umin, umax = [uxmin,uxmax].min, [uxmin,uxmax].max
1718
+ else
1719
+ vmin, vmax = [vymin,vymax].min, [vymin,vymax].max
1720
+ umin, umax = [uymin,uymax].min, [uymin,uymax].max
1721
+ end
1722
+
1723
+ # get dtick1 & dtick2
1724
+ dtick1 = opt['dtick1']
1725
+ dtick2 = opt['dtick2']
1726
+ unless dtick1 && dtick2
1727
+ irota = DCL.uzpget("irotl#{xy}#{cside}")
1728
+ irota += 1 if yax
1729
+ mode = irota.modulo(2)
1730
+ DCL.ususcu(xy.capitalize,umin,umax,vmin,vmax,mode)
1731
+ dtick1 = DCL.uspget("d#{xy}t") unless dtick1
1732
+ dtick2 = DCL.uspget("d#{xy}l") unless dtick2
1733
+ end
1734
+
1735
+ lepsl = DCL.glpget('lepsl')
1736
+ repsl = DCL.glpget('repsl')
1737
+ DCL.glpset('lepsl',true)
1738
+
1739
+ # generate numbers for small tickmarks
1740
+ nn = 0
1741
+ rx = DCL.irle(umin/dtick1)*dtick1
1742
+ if DCL.lreq(umin,rx)
1743
+ x = rx
1744
+ else
1745
+ x = rx + dtick1
1746
+ end
1747
+ u1 = []
1748
+ while DCL.lrle(x,umax)
1749
+ if x.abs < dtick1*repsl*nn
1750
+ x = 0.0
1751
+ end
1752
+ u1[nn] = x
1753
+ nn = nn + 1
1754
+ x = x + dtick1
1755
+ end
1756
+
1757
+ # generate numbers for large tickmarks and labels
1758
+ nn = 0
1759
+ rx = DCL.irle(umin/dtick2)*dtick2
1760
+ if DCL.lreq(umin,rx)
1761
+ x = rx
1762
+ else
1763
+ x = rx + dtick2
1764
+ end
1765
+ u2 = []
1766
+ while DCL.lrle(x,umax)
1767
+ if x.abs < dtick2*repsl*nn
1768
+ x = 0
1769
+ end
1770
+ u2[nn] = x
1771
+ nn = nn + 1
1772
+ x = x + dtick2
1773
+ end
1774
+
1775
+ # generate labels
1776
+ c2 = NArray.to_na(u2)
1777
+ c2 = c2.to_a.collect do |c|
1778
+ if c == 0
1779
+ 'EQ'
1780
+ elsif c > 0
1781
+ c.to_i.to_s + 'N'
1782
+ else
1783
+ c.abs.to_i.to_s + 'S'
1784
+ end
1785
+ end
1786
+ nc = c2.collect{|c| c.size}.max
1787
+
1788
+ # call DCL.u[xy]axlb
1789
+ if xax
1790
+ DCL.uxaxlb(cside,u1,u2,c2,nc)
1791
+ else
1792
+ DCL.uyaxlb(cside,u1,u2,c2,nc)
1793
+ end
1794
+ end
1795
+
1796
+ # <<< flow vector package >>>
1797
+
1798
+ def __truncate(float, order=2)
1799
+ # truncate (round) a floating number with the number digits
1800
+ # specified by "order".
1801
+ # e.g., if order=3, -0.012345 => -0.0123; 6.6666 => 6.67
1802
+ exponent = 10**(-Math::log10(float.abs).floor+order-1)
1803
+ (float * exponent).round.to_f/exponent
1804
+ end
1805
+
1806
+ @@unit_vect_options = Misc::KeywordOptAutoHelp.new(
1807
+ ['vxunit', 0.05, "x unit vect len in V coord. Used only when fxunit is omitted (default)"],
1808
+ ['vyunit', 0.05, "y unit vect len in V coord. Used only when fyunit is omitted (default)"],
1809
+ ['vxuloc', nil, "Starting x position of unit vect"],
1810
+ ['vyuloc', nil, "Starting y position of unit vect"],
1811
+ ['vxuoff', 0.05, "Specify vxuloc by offset from right-bottom corner"],
1812
+ ['vyuoff', 0.0, "Specify vyuloc by offset from right-bottom corner"],
1813
+ ['inplace',true, "Whether to print labels right by the unit vector (true) or below the x axis (false)"],
1814
+ ['rsizet', nil, "Label size(default taken from uz-parameter 'rsizel1')"],
1815
+ ['index', 3," Line index of the unit vector"]
1816
+ )
1817
+
1818
+ def set_unit_vect_options(options)
1819
+ @@unit_vect_options.set(options)
1820
+ end
1821
+
1822
+ @@next_unit_vect_options = nil
1823
+ def next_unit_vect_options(options)
1824
+ if options.is_a?(Hash)
1825
+ @@next_unit_vect_options = options
1826
+ else
1827
+ raise TypeError,"Hash expected"
1828
+ end
1829
+ nil
1830
+ end
1831
+
1832
+ def unit_vect( vxfxratio, # (V cood length)/(actual length) in x
1833
+ vyfyratio, # (V cood length)/(actual length) in y
1834
+ fxunit=nil, # If specified, x unit vect len
1835
+ fyunit=nil, # If specified, y unit vect len
1836
+ options=nil )
1837
+ #< options >
1838
+ if @@next_unit_vect_options
1839
+ options = ( options ? @@next_unit_vect_options.update(options) :
1840
+ @@next_unit_vect_options )
1841
+ @@next_unit_vect_options = nil
1842
+ end
1843
+ opt = @@unit_vect_options.interpret(options)
1844
+ vxunit = opt['vxunit']
1845
+ vyunit = opt['vyunit']
1846
+ vxuloc = opt['vxuloc']
1847
+ vyuloc = opt['vyuloc']
1848
+ rsizet = opt['rsizet']
1849
+ index = opt['index']
1850
+
1851
+ #< unit vector >
1852
+ if fxunit
1853
+ vxunit = vxfxratio * fxunit
1854
+ else
1855
+ fxunit = vxunit / vxfxratio
1856
+ end
1857
+ if fyunit
1858
+ vyunit = vyfyratio * fyunit
1859
+ else
1860
+ fyunit = vyunit / vyfyratio
1861
+ end
1862
+ fxunit = __truncate( (uxusv=fxunit) )
1863
+ fyunit = __truncate( (uyusv=fyunit) )
1864
+ vxunit = vxunit * (fxunit/uxusv)
1865
+ vyunit = vyunit * (fyunit/uyusv)
1866
+ if !(vxuloc && vyuloc)
1867
+ vx0,vx1,vy0,vy1 = DCL.sgqvpt
1868
+ vxuloc = vx1 + opt['vxuoff'] if !vxuloc
1869
+ vyuloc = vy0 + opt['vyuoff'] if !vyuloc
1870
+ end
1871
+ DCL.sglazv( vxuloc, vyuloc, vxuloc+vxunit, vyuloc, 1, index )
1872
+ DCL.sglazv( vxuloc, vyuloc, vxuloc, vyuloc+vyunit, 1, index )
1873
+
1874
+ #< labelling >
1875
+ sfxunit = sprintf("%.2g",fxunit)
1876
+ sfyunit = sprintf("%.2g",fyunit)
1877
+ rsizet = DCL.uzpget('rsizel1') if !rsizet
1878
+ if opt['inplace']
1879
+ DCL.sgtxzv(vxuloc, vyuloc-1.2*rsizet,
1880
+ sfxunit, rsizet, 0, -1, index)
1881
+ DCL.sgtxzv(vxuloc+1.2*rsizet, vyuloc+0.5*rsizet,
1882
+ sfyunit, rsizet, 90, -1, index)
1883
+ else
1884
+ msg= "UNIT VECTOR X:#{sfxunit} Y:#{sfyunit}"
1885
+ before = uz_set_params({'rsizec1'=>rsizet})
1886
+ DCL.uxsttl('b',' ',0.0)
1887
+ DCL.uxsttl('b',msg,0.0)
1888
+ uz_set_params(before)
1889
+ end
1890
+ end
1891
+
1892
+ def flow_vect( fx, fy, factor=1.0, xintv=1, yintv=1,
1893
+ vxfxratio=nil, vyfyratio=nil)
1894
+ raise ArgumentError,"Expect 2D arrays" if fx.rank != 2 || fy.rank != 2
1895
+ raise ArgumentError,"fx.shape != fy.shape" if fx.shape != fy.shape
1896
+ raise ArgumentError,"xintv must be a positive integer" if xintv < 0
1897
+ raise ArgumentError,"yintv must be a positive integer" if yintv < 0
1898
+ nx, ny = fx.shape
1899
+ if xintv >= 2
1900
+ idx = NArray.int(nx/xintv).indgen!*xintv # [0,xintv,2*xintv,..]
1901
+ fx = fx[idx, true]
1902
+ fy = fy[idx, true]
1903
+ end
1904
+ if yintv >= 2
1905
+ idx = NArray.int(ny/yintv).indgen!*yintv # [0,yintv,2*yintv,..]
1906
+ fx = fx[true, idx]
1907
+ fy = fy[true, idx]
1908
+ end
1909
+ nx, ny = fx.shape # again, because of xintv & yintv
1910
+ vx0,vx1,vy0,vy1 = DCL.sgqvpt
1911
+ wnd = DCL.sgqwnd
1912
+ if wnd.include?(DCL.glrget('rundef'))
1913
+ ux0,ux1,uy0,uy1 = DCL.sgqtxy
1914
+ else
1915
+ ux0,ux1,uy0,uy1 = wnd
1916
+ end
1917
+ dvx = (vx1-vx0)/nx
1918
+ dvy = (vy1-vy0)/ny
1919
+ ax = (vx1-vx0)/(ux1-ux0) # factor to convert from U to V coordinate
1920
+ ay = (vy1-vy0)/(uy1-uy0) # factor to convert from U to V coordinate
1921
+ fxmx = fx.abs.max
1922
+ fymx = fy.abs.max
1923
+ raise "fx has no data or all zero" if fxmx == 0
1924
+ raise "fy has no data or all zero" if fymx == 0
1925
+ cn = [ dvx/(ax*fxmx), dvy/(ay*fymx) ].min # normarization constant
1926
+ vxfxratio = factor*cn*ax if !vxfxratio
1927
+ vyfyratio = factor*cn*ay if !vyfyratio
1928
+ before = ug_set_params( {'LNRMAL'=>false, 'LMSG'=>false,
1929
+ 'XFACT1'=>1.0, 'YFACT1'=>1.0} )
1930
+ DCL.ugvect( vxfxratio*fx, vyfyratio*fy )
1931
+ ug_set_params( before )
1932
+ unit_vect_info = [ vxfxratio, vyfyratio, fxmx, fymx ]
1933
+ return unit_vect_info
1934
+ end
1935
+
1936
+ def flow_itr5( gpx, gpy, factor=1.0, unit_vect=false )
1937
+ raise ArgumentError,"Expect 2D arrays" if gpx.rank != 2 || gpy.rank != 2
1938
+ raise ArgumentError,"gpx.shape != gpy.shape" if gpx.shape != gpy.shape
1939
+
1940
+ raise "Transform. No. should be 5" if DCL.sgpget('itr') != 5
1941
+
1942
+ theta = gpx.coord(1) / 180 * Math::PI
1943
+ theta = theta.reshape(1,theta.shape[0])
1944
+
1945
+ vx = gpx * theta.cos - gpy * theta.sin # UC component -> VC
1946
+ vy = gpx * theta.sin + gpy * theta.cos # UC component -> VC
1947
+
1948
+ DCL.sglset('LCLIP',false)
1949
+ before1 = DCLExt.ug_set_params(
1950
+ {'LUNIT'=>true, 'LUMSG'=>true} ) if unit_vect
1951
+ before2 = DCLExt.ug_set_params(
1952
+ {'LNRMAL'=>false,
1953
+ 'XFACT1'=>factor, 'YFACT1'=>factor} ) if factor != 1.0
1954
+ DCL.ugvect( vx.val, vy.val )
1955
+
1956
+ if unit_vect
1957
+ uxunit = sprintf("%.2g",DCL.ugrget('UXUNIT'))
1958
+ uyunit = sprintf("%.2g",DCL.ugrget('UXUNIT'))
1959
+ vxuloc = DCL.ugrget('VXULOC')
1960
+ vyuloc = DCL.ugrget('VYULOC')
1961
+ rsize = DCL.ugrget('RSIZET')
1962
+ dv = rsize
1963
+ DCL.sgtxzv(vxuloc, vyuloc-dv, uxunit, rsize, 0, -1, 3 )
1964
+ DCL.sgtxzv(vxuloc-dv, vyuloc, uyunit, rsize, 90, -1, 3 )
1965
+ end
1966
+
1967
+ ug_set_params( before2 ) if factor != 1.0
1968
+ ug_set_params( before1 ) if unit_vect
1969
+ end
1970
+
1971
+ ######################################
1972
+
1973
+ # <<< color bar >>>
1974
+
1975
+ @@color_bar_options = Misc::KeywordOptAutoHelp.new(
1976
+ ["levels", nil, "tone levels (if omitted, latest ones are used)"],
1977
+ ["patterns", nil, "tone patterns (~colors) (if omitted, latest ones are used)"],
1978
+ ["voff", nil, "how far is the bar from the viewport in the V coordinate"],
1979
+ ["vcent",nil, "center position of the bar in the V coordinate (VX or VY)"],
1980
+ ["vlength", 0.3, "bar length in the V coordinate"],
1981
+ ["vwidth", 0.02, "bar width in the V coordinate"],
1982
+ ["landscape", false, "if true, horizonlly long (along x axes)"],
1983
+ ["portrait", true, "if true, vertically long (along y axes)"],
1984
+ ["top", false, "place the bar at the top (effective if landscape)"],
1985
+ ["left", false, "place the bar in the left (effective if portrait)"],
1986
+ ["units", nil, "units of the axis of the color bar"],
1987
+ ["title", nil, "title of the color bar"],
1988
+ ["tickintv", 1, "0,1,2,3,.. to specify how frequently the dividing tick lines are drawn (0: no tick lines, 1: every time, 2: ever other:,...)"],
1989
+ ["labelintv", nil, "0,1,2,3,.. to specify how frequently labels are drawn (0: no labels, 1: every time, 2: ever other:,... default: internally determined)"],
1990
+ ["labels_ud", nil, "user-defined labels for replacing the default labels (Array of String)"],
1991
+ ["charfact", 0.9, "factor to change the label/units/title character size (relative to 'rsizel1'/'rsizel1'/'rsizec1')"],
1992
+ ["log", false, "set the color bar scale to logarithmic"],
1993
+ ["constwidth", false, "if true, each color is drawn with the same width"],
1994
+ ["index", nil, "index of tick lines and bar frame"],
1995
+ ["charindex", nil, "index of labels, units, and title"],
1996
+ ["chval_fmt", nil, "string to specify the DCL.chval format for labeling"]
1997
+ )
1998
+
1999
+ def set_color_bar_options(options)
2000
+ @@color_bar_options.set(options)
2001
+ end
2002
+
2003
+ def level_chval_fmt(max,min,dx)
2004
+ # returns a format for DCL.chval suitable for color-ba labels
2005
+ eps = 1e-4 * dx.abs
2006
+ if ( dx.abs % 10**Math::log10(dx.abs) < eps )
2007
+ # 1 keta
2008
+ least_order = Math::log10(dx.abs).floor
2009
+ else
2010
+ # >=2 keta --> limit to 2 keta
2011
+ least_order = Math::log10(dx.abs).floor - 1
2012
+ end
2013
+ ng = Math::log10([max.abs,min.abs,eps].max).floor - least_order + 1
2014
+ if ng <= 3
2015
+ fmt = 'b'
2016
+ else
2017
+ n = Math::log10([max.abs,min.abs].max).floor
2018
+ nn = Math::log10([max.abs,min.abs].min).floor
2019
+ if least_order >= 0 and nn >= 0
2020
+ ifg = 'i'
2021
+ elsif 0 <= n and n <= 4
2022
+ ifg = 'f'
2023
+ else
2024
+ ifg = 'g'
2025
+ end
2026
+ case(ifg)
2027
+ when 'i'
2028
+ fmt = '(i15)'
2029
+ when 'g'
2030
+ ng = Math::log10([max.abs,min.abs,eps].max).floor - least_order + 1
2031
+ ng = [ ng, 2 ].max
2032
+ fmt = "(g15.#{ng})"
2033
+ when 'f'
2034
+ nf = [ -least_order, 0].max
2035
+ fmt = "(f15.#{nf})"
2036
+ end
2037
+ end
2038
+ fmt
2039
+ end
2040
+
2041
+ def sprintf_level(x,max,min,dx)
2042
+ # format a float for color-bar labels.
2043
+ # like DCL.hval('b',x) but changes according to dx
2044
+ if x==0
2045
+ fg = 'f'
2046
+ else
2047
+ n = Math::log10(x.abs).floor
2048
+ if 0 <= n and n <= 4
2049
+ fg = 'f'
2050
+ else
2051
+ fg = 'g'
2052
+ end
2053
+ end
2054
+ eps = 1e-6
2055
+ if ( dx.abs % 10**Math::log10(dx.abs) < eps )
2056
+ # 1 keta
2057
+ least_order = Math::log10(dx.abs).floor
2058
+ else
2059
+ # >=2 keta --> limit to 2 keta
2060
+ least_order = Math::log10(dx.abs).floor - 1
2061
+ end
2062
+ if fg == 'g'
2063
+ ng = Math::log10([max.abs,min.abs,eps].max).floor - least_order + 1
2064
+ ng = [ ng, 2 ].max
2065
+ fmt = "%.#{ng}g"
2066
+ else
2067
+ nf = [ -least_order, 0].max
2068
+ fmt = "%.#{nf}f"
2069
+ end
2070
+ sprintf(fmt,x).sub(/\.0*$/,'')
2071
+ end
2072
+
2073
+ def color_bar(options=nil)
2074
+
2075
+ # < set parameters >
2076
+ opt = @@color_bar_options.interpret(options)
2077
+ lsetx = DCL.uwqgxz
2078
+ lsety = DCL.uwqgyz
2079
+
2080
+ rmiss = DCL.glrget('rmiss')
2081
+
2082
+ levels = opt['levels']
2083
+ patterns = opt['patterns']
2084
+
2085
+ if (levels.nil? && !patterns.nil?) || (!levels.nil? && patterns.nil?)
2086
+ raise "levels and patterns must be set at same time\n"
2087
+ end
2088
+
2089
+ landscape = opt["landscape"] || !opt["portrait"]
2090
+ portrait = ! landscape
2091
+
2092
+ if !levels.nil?
2093
+ ue_set_tone(levels,patterns)
2094
+ end
2095
+
2096
+ labels_ud = opt["labels_ud"]
2097
+ if !labels_ud.nil?
2098
+ if labels_ud.class != Array
2099
+ raise ArgumentError,"'labels_ud' must be an Array of String"
2100
+ elsif labels_ud.size == 0
2101
+ raise ArgumentError,"'labels_ud' must be an Array of String"
2102
+ else
2103
+ labels_ud.each do |lbl_ud|
2104
+ if lbl_ud.class != String
2105
+ raise ArgumentError,"'labels_ud' must be an Array of String"
2106
+ end
2107
+ end
2108
+ end
2109
+ end
2110
+
2111
+ if opt["index"]
2112
+ index = opt["index"]
2113
+ index = 1 if index <= 0
2114
+ else
2115
+ index = DCL::uziget("indext2")
2116
+ end
2117
+ indext1_bk = DCL::uziget("indext1")
2118
+ indext2_bk = DCL::uziget("indext2")
2119
+ DCL::uziset("indext1",index)
2120
+ DCL::uziset("indext2",index)
2121
+
2122
+ if opt["charindex"]
2123
+ charindex = opt["charindex"]
2124
+ charindex = 1 if charindex <= 0
2125
+ else
2126
+ charindex = DCL::uziget("indexl1")
2127
+ end
2128
+ indexl1_bk = DCL::uziget("indexl1")
2129
+ DCL::uziset("indexl1",charindex)
2130
+
2131
+ charfact = opt["charfact"]
2132
+ rsizel1_bk = DCL::uzrget("rsizel1")
2133
+ rsizec1_bk = DCL::uzrget("rsizec1")
2134
+ DCL::uzrset("rsizel1",charfact*rsizel1_bk)
2135
+ DCL::uzrset("rsizec1",charfact*rsizec1_bk)
2136
+
2137
+ nton = DCL::ueqntl
2138
+ if nton==0
2139
+ raise "no tone patern was set\n"
2140
+ end
2141
+ lev1 = Array.new
2142
+ lev2 = Array.new
2143
+ patterns = Array.new if !opt['patterns']
2144
+ for n in 0..nton-1
2145
+ tlev1,tlev2,ipat = DCL::ueqtlv(n+1)
2146
+ lev1.push(tlev1)
2147
+ lev2.push(tlev2)
2148
+ patterns.push(ipat) if !opt['patterns']
2149
+ end
2150
+
2151
+ #levels = lev1+lev2
2152
+ #levels = levels.uniq.sort
2153
+ #levels.delete(rmiss)
2154
+ #if levels.ne(levels.sort).any?
2155
+ # raise "levels is not in order\n"
2156
+ #end
2157
+
2158
+ levels = lev1.push(lev2[-1]) if !levels
2159
+ levels = NArray.to_na(levels) if levels.is_a?(Array)
2160
+ patterns = NArray.to_na(patterns) if patterns.is_a?(Array)
2161
+
2162
+ vx1, vx2, vy1, vy2 = DCL.sgqvpt
2163
+
2164
+ if opt['log']
2165
+ lv = levels[levels.ne(rmiss).where]
2166
+ if lv.length >= 4 && lv[0]*lv[-1]<0
2167
+ iturn = 0
2168
+ for i in 0...levels.length
2169
+ if levels[i] != rmiss
2170
+ if levels[i]*lv[0] < 0
2171
+ iturn = i
2172
+ break
2173
+ end
2174
+ end
2175
+ end
2176
+ opt['vlength'] /= 2
2177
+ vc0 = opt['vcent'] || ( portrait && (vy1+vy2)/2) || (vx1+vx2)/2
2178
+
2179
+ opt["voff"] ||=
2180
+ DCL.uzrget('pad1')*DCL::uzrget("rsizec2") +
2181
+ ( portrait ? DCL.uzrget('roffyr') : - DCL.uzrget('roffxb') )
2182
+
2183
+ vsep2 = 0.02
2184
+
2185
+ opt['levels'] = levels[0..iturn-1]
2186
+ opt['patterns'] = patterns[0..iturn-2]
2187
+ opt['vcent'] = vc0 - opt['vlength']/2 - vsep2
2188
+ color_bar(opt)
2189
+
2190
+ opt['levels'] = levels[iturn..-1]
2191
+ opt['patterns'] = patterns[iturn..-1]
2192
+ opt['vcent'] = vc0 + opt['vlength']/2 + vsep2
2193
+ color_bar(opt)
2194
+
2195
+ # fill between the two bars
2196
+ if portrait
2197
+ x1 = vx2 + opt["voff"]
2198
+ x2 = x1 + opt['vwidth']
2199
+ y1 = vc0 - vsep2
2200
+ y2 = vc0 + vsep2
2201
+ else
2202
+ x1 = vc0 - vsep2
2203
+ x2 = vc0 + vsep2
2204
+ y1 = vy1 - opt["voff"]
2205
+ y2 = y1 - opt['vwidth']
2206
+ end
2207
+ bk = DCLExt.sg_set_params({'lclip'=>false})
2208
+ DCL.sgtnzv([x1,x2,x2,x1],[y1,y1,y2,y2],patterns[iturn-1])
2209
+ DCL.sgplzv([x1,x2,x2,x1,x1],[y1,y1,y2,y2,y1],1,3)
2210
+ DCLExt.sg_set_params(bk)
2211
+ return
2212
+ end
2213
+ end
2214
+
2215
+ if levels.length <= 1
2216
+ $stderr.print( "WARNING #{__FILE__}:#{__LINE__}: # of levels <= 1. No color bar is drawn." )
2217
+ return
2218
+ end
2219
+
2220
+ itrsv = DCL::sgqtrn
2221
+ if itrsv <= 4
2222
+ ux1sv, ux2sv, uy1sv, uy2sv = DCL.sgqwnd
2223
+ else
2224
+ simfacsv, vxoffsv, vyoffsv = DCL.sgqsim
2225
+ plxsv, plysv, plrotsv = DCL.sgqmpl()
2226
+ end
2227
+
2228
+ vwidth = opt["vwidth"]
2229
+ vlength = opt["vlength"]
2230
+
2231
+ if portrait
2232
+ if !opt["left"]
2233
+ # left
2234
+ voff = opt["voff"] ||
2235
+ DCL.uzrget('roffyr') + DCL.uzrget('pad1')*DCL::uzrget("rsizec2")
2236
+ vxmin = vx2 + voff
2237
+ vxmax = vx2 + voff + vwidth
2238
+ else
2239
+ # right
2240
+ voff = opt["voff"] ? -opt["voff"] : \
2241
+ DCL.uzrget('roffyl') - DCL.uzrget('pad1')*DCL::uzrget("rsizec2")
2242
+ vxmax = vx1 + voff
2243
+ vxmin = vx1 + voff - vwidth
2244
+ end
2245
+ vymin =( opt["vcent"] ? opt["vcent"]-vlength/2 : vy1 )
2246
+ vymax =( opt["vcent"] ? opt["vcent"]+vlength/2 : vy1+vlength )
2247
+ else ## landscape ##
2248
+ vxmin =( opt["vcent"] ? opt["vcent"]-vlength/2 : (vx1+vx2)/2-vlength/2 )
2249
+ vxmax =( opt["vcent"] ? opt["vcent"]+vlength/2 : (vx1+vx2)/2+vlength/2 )
2250
+ if opt["top"]
2251
+ # top
2252
+ voff = opt["voff"] ||
2253
+ DCL.uzrget('roffxt') + DCL.uzrget('pad1')*DCL::uzrget("rsizec2")
2254
+ vymin = vy2 + voff
2255
+ vymax = vy2 + voff + vwidth
2256
+ else
2257
+ # bottom
2258
+ voff = opt["voff"] ? -opt["voff"] : \
2259
+ DCL.uzrget('roffxb') - DCL.uzrget('pad1')*DCL::uzrget("rsizec2")
2260
+ vymax = vy1 + voff
2261
+ vymin = vy1 + voff - vwidth
2262
+ end
2263
+ end
2264
+
2265
+ min = levels[levels.ne(rmiss).where].min
2266
+ max = levels[levels.ne(rmiss).where].max
2267
+ if levels[0] == rmiss
2268
+ inf0 = true
2269
+ dummy1,dummy2,ipat0 = DCL::ueqtlv(1)
2270
+ else
2271
+ inf0 = false
2272
+ end
2273
+ if levels[-1] == rmiss
2274
+ inf1 = true
2275
+ dummy1,dummy2,ipat1 = DCL::ueqtlv(nton)
2276
+ else
2277
+ inf1 = false
2278
+ end
2279
+
2280
+ # < paint color tones >
2281
+
2282
+ lclip_bk = DCL::sglget("lclip")
2283
+ DCL::sglset("lclip", false)
2284
+
2285
+ if opt["constwidth"]
2286
+
2287
+ if inf0
2288
+ levels = levels[1..-1]
2289
+ patterns = patterns[1..-1]
2290
+ end
2291
+ if inf1
2292
+ levels = levels[0..-2]
2293
+ patterns = patterns[0..-2]
2294
+ end
2295
+ nlev = levels.length
2296
+ npat = patterns.length
2297
+
2298
+ if portrait
2299
+ vy = (NArray.sfloat(npat+1).indgen!)*(vymax-vymin)/npat + vymin
2300
+
2301
+ # paint color tones for infinity (with drawing frame)
2302
+ if inf0
2303
+ vy3 = [vymin, vymin-vwidth*2.25, vymin]
2304
+ vx3 = [vxmax, (vxmax+vxmin)/2, vxmin]
2305
+ DCL.sgtnzv(vx3,vy3,ipat0)
2306
+ DCL.sgplzv(vx3,vy3,1,index)
2307
+ end
2308
+ if inf1
2309
+ vy3 = [vymax, vymax+vwidth*2.25, vymax]
2310
+ vx3 = [vxmax, (vxmax+vxmin)/2, vxmin]
2311
+ DCL.sgtnzv(vx3,vy3,ipat1)
2312
+ DCL.sgplzv(vx3,vy3,1,index)
2313
+ end
2314
+
2315
+ # paint color tones for each range (with drawing long-side frame)
2316
+ for i in 0..npat-1
2317
+ DCL::sgtnzv([vxmin,vxmax,vxmax,vxmin],[vy[i],vy[i],vy[i+1],vy[i+1]],patterns[i])
2318
+ DCL::sgplzv([vxmin,vxmin],[vy[i],vy[i+1]],1,index)
2319
+ DCL::sgplzv([vxmax,vxmax],[vy[i],vy[i+1]],1,index)
2320
+ end
2321
+
2322
+ else ## landscape ##
2323
+ vx = (NArray.sfloat(npat+1).indgen!)*(vxmax-vxmin)/npat + vxmin
2324
+
2325
+ # paint color tones for infinity (with drawing frame)
2326
+ if inf0
2327
+ vx3 = [vxmin, vxmin-vwidth*2.25, vxmin]
2328
+ vy3 = [vymax, (vymax+vymin)/2, vymin]
2329
+ DCL.sgtnzv(vx3,vy3,ipat0)
2330
+ DCL.sgplzv(vx3,vy3,1,index)
2331
+ end
2332
+ if inf1
2333
+ vx3 = [vxmax, vxmax+vwidth*2.25, vxmax]
2334
+ vy3 = [vymax, (vymax+vymin)/2, vymin]
2335
+ DCL.sgtnzv(vx3,vy3,ipat1)
2336
+ DCL.sgplzv(vx3,vy3,1,index)
2337
+ end
2338
+
2339
+ # paint color tones for each range (with drawing long-side frame)
2340
+ for i in 0..npat-1
2341
+ DCL::sgtnzv([vx[i],vx[i],vx[i+1],vx[i+1]],[vymin,vymax,vymax,vymin],patterns[i])
2342
+ DCL::sgplzv([vx[i],vx[i+1]],[vymin,vymin],1,index)
2343
+ DCL::sgplzv([vx[i],vx[i+1]],[vymax,vymax],1,index)
2344
+ end
2345
+ end
2346
+
2347
+ else ### opt["constwidth"] == false ###
2348
+
2349
+ # paint color tones for infinity (with drawing frame)
2350
+ if portrait
2351
+ if inf0
2352
+ vy3 = [vymin, vymin-vwidth*2.25, vymin]
2353
+ vx3 = [vxmax, (vxmax+vxmin)/2, vxmin]
2354
+ DCL.sgtnzv(vx3,vy3,ipat0)
2355
+ DCL.sgplzv(vx3,vy3,1,index)
2356
+ end
2357
+ if inf1
2358
+ vy3 = [vymax, vymax+vwidth*2.25, vymax]
2359
+ vx3 = [vxmax, (vxmax+vxmin)/2, vxmin]
2360
+ DCL.sgtnzv(vx3,vy3,ipat1)
2361
+ DCL.sgplzv(vx3,vy3,1,index)
2362
+ end
2363
+ else ## landscape ##
2364
+ if inf0
2365
+ vx3 = [vxmin, vxmin-vwidth*2.25, vxmin]
2366
+ vy3 = [vymax, (vymax+vymin)/2, vymin]
2367
+ DCL.sgtnzv(vx3,vy3,ipat0)
2368
+ DCL.sgplzv(vx3,vy3,1,index)
2369
+ end
2370
+ if inf1
2371
+ vx3 = [vxmax, vxmax+vwidth*2.25, vxmax]
2372
+ vy3 = [vymax, (vymax+vymin)/2, vymin]
2373
+ DCL.sgtnzv(vx3,vy3,ipat1)
2374
+ DCL.sgplzv(vx3,vy3,1,index)
2375
+ end
2376
+ end
2377
+
2378
+ # paint color tones for each range
2379
+ nbar = 100
2380
+ bar = NArray.float(nbar,2)
2381
+ for i in 0..nbar-1
2382
+ bar[i,true] = min + (max-min).to_f/(nbar-1)*i
2383
+ end
2384
+
2385
+ xb = DCL::uzlget("labelxb")
2386
+ yl = DCL::uzlget("labelyl")
2387
+ if portrait
2388
+ xmin = 0.0
2389
+ xmax = 1.0
2390
+ ymin = min
2391
+ ymax = max
2392
+ DCL::uzlset("labelxb",false)
2393
+ DCL::uzlset("labelyl",true)
2394
+ bar = bar.transpose(-1,0)
2395
+ DCL::uwsgxa([0,1])
2396
+ DCL::uwsgya(bar[0,true])
2397
+ else
2398
+ xmin = min
2399
+ xmax = max
2400
+ ymin = 0.0
2401
+ ymax = 1.0
2402
+ DCL::uzlset("labelxb",true)
2403
+ DCL::uzlset("labelyl",false)
2404
+ DCL::uwsgxa(bar[true,0])
2405
+ DCL::uwsgya([0,1])
2406
+ end
2407
+
2408
+ type = 1
2409
+ if opt["log"]
2410
+ type +=1
2411
+ type +=1 if !portrait
2412
+ end
2413
+
2414
+ DCL::grfig
2415
+ DCL::grsvpt(vxmin,vxmax,vymin,vymax)
2416
+ DCL::grswnd(xmin,xmax,ymin,ymax)
2417
+ DCL::grstrn(type)
2418
+ DCL::grstrf
2419
+
2420
+ DCL::uetone(bar)
2421
+ DCL.uwsgxz(false)
2422
+ DCL.uwsgyz(false)
2423
+
2424
+ end
2425
+
2426
+ # < set ticking and labeling levels >
2427
+
2428
+ if opt["labelintv"]
2429
+ labelintv = opt["labelintv"]
2430
+ else
2431
+ ntn = nton
2432
+ ntn -= 1 if inf0
2433
+ ntn -= 1 if inf1
2434
+ if portrait
2435
+ labelintv = (ntn-1) / 9 + 1
2436
+ else
2437
+ labelintv = (ntn-1) / 5 + 1
2438
+ end
2439
+ end
2440
+ if labelintv <= 0
2441
+ no_label = true
2442
+ labelintv = 1
2443
+ else
2444
+ no_label = false
2445
+ end
2446
+
2447
+ tickintv = opt["tickintv"]
2448
+ if tickintv <= 0
2449
+ no_tick = true
2450
+ tickintv = labelintv
2451
+ else
2452
+ no_tick = false
2453
+ end
2454
+
2455
+ eps = 1e-5
2456
+ dummy = -9.9e-38
2457
+ dz = dzp = dzc = dummy
2458
+ idu = Array.new
2459
+ (1...levels.length).each do |i|
2460
+ dzc = (levels[i] - levels[i-1]).abs
2461
+ if (dzc-dzp).abs <= eps * [dzc.abs,dzp.abs].max
2462
+ dz = dzc # set dz if two consecutive inrements are the same
2463
+ idu.push( i-1 )
2464
+ end
2465
+ dzp = (levels[i] - levels[i-1]).abs
2466
+ end
2467
+ if idu.length > 0
2468
+ idumin = idu.min - 1
2469
+ idumax = idu.max + 1
2470
+ else
2471
+ idumin = 0
2472
+ idumax = levels.length-1
2473
+ end
2474
+ if dz != dummy
2475
+ # if idumin == 1 and levels[0] != rmiss
2476
+ # # to correct non-uniform intv at the beginning
2477
+ # levels[0] = levels[1] - dz
2478
+ # idumin = 0
2479
+ # min = levels[0]
2480
+ # end
2481
+ # if idumax == levels.length-2 and levels[-1] != rmiss
2482
+ # # to correct non-uniform intv at the end
2483
+ # levels[-1] = levels[-2] + dz
2484
+ # idumax = levels.length-1
2485
+ # max = levels[-1]
2486
+ # end
2487
+ # use the algorithm used in DCL.udgcla
2488
+ offs_tick = ( (-levels[idumin]/dz).round % tickintv + idumin ) % tickintv
2489
+ offs_label = ( (-levels[idumin]/dz).round % labelintv + idumin ) % labelintv
2490
+ else
2491
+ md = 0
2492
+ if ( (idx=levels.eq(0.0).where).length > 0 )
2493
+ md = idx[0] % labelintv
2494
+ else
2495
+ a = levels[0...([labelintv,levels.length].min)]
2496
+ b = a * 10**( -NMath.log10(a.abs).floor.min )
2497
+ (0...b.length).each{|i| md=i if (b[i].round-b[i]).abs < 1e-5 }
2498
+ end
2499
+ offs_tick = (md % tickintv)
2500
+ offs_label = md
2501
+ end
2502
+
2503
+ if levels.length >= 4
2504
+ lvmx = levels[1..-2].max
2505
+ lvmn = levels[1..-2].min
2506
+ dlv = (lvmx-lvmn) / (levels.length-3)
2507
+ elsif levels.length == 3 or levels.length == 2
2508
+ lvmn = lvmx = dlv = levels[1]
2509
+ else
2510
+ lvmn = lvmx = dlv = levels[0]
2511
+ end
2512
+
2513
+ # < draw units, title, labels, and tick lines>
2514
+
2515
+ if opt["constwidth"]
2516
+
2517
+ if !no_label && labels_ud
2518
+ ilbl = 0
2519
+ for i in 0..nlev-1
2520
+ if (i % labelintv) == offs_label
2521
+ ilbl += 1
2522
+ end
2523
+ end
2524
+ if labels_ud.size != ilbl
2525
+ raise ArgumentError, "'labels_ud' must be an Array of length==#{ilbl} in this case"
2526
+ end
2527
+ end
2528
+
2529
+ if portrait
2530
+
2531
+ if voff > 0
2532
+ cent = -1
2533
+ vxlabel = vxmax+DCL::uzrget('pad1')*DCL::uzrget('rsizel1')
2534
+ # title
2535
+ DCL::sgtxzr(vxmin-(0.5+DCL::uzrget('pad1'))*DCL::uzrget('rsizec1'), (vymin+vymax)/2.0, opt['title'], DCL::uzrget('rsizec1'), 90, 0, charindex) if opt['title']
2536
+ # units
2537
+ DCL::sgtxzr(vxmax+DCL::uzrget('pad1')*DCL::uzrget('rsizel1'), vymax+3.0*DCL::uzrget('rsizel1'), opt['units'], DCL::uzrget('rsizel1'), 0, -1, charindex) if opt['units']
2538
+ else
2539
+ cent = 1
2540
+ vxlabel = vxmin-DCL::uzrget('pad1')*DCL::uzrget('rsizel1')
2541
+ # title
2542
+ DCL::sgtxzr(vxmax+(0.5+DCL::uzrget('pad1'))*DCL::uzrget('rsizec1'), (vymin+vymax)/2.0, opt['title'], DCL::uzrget('rsizec1'), -90, 0, charindex) if opt['title']
2543
+ # units
2544
+ DCL::sgtxzr(vxmin-DCL::uzrget('pad1')*DCL::uzrget('rsizel1'), vymax+3.0*DCL::uzrget('rsizel1'), opt['units'], DCL::uzrget('rsizel1'), 0, 1, charindex) if opt['units']
2545
+ end
2546
+
2547
+ ilbl_ud = 0
2548
+ for i in 0..nlev-1
2549
+ # labels
2550
+ if !no_label && (i % labelintv) == offs_label
2551
+ if labels_ud
2552
+ char = labels_ud[ilbl_ud]
2553
+ DCL::sgtxzr(vxlabel,vy[i],char,DCL::uzrget('rsizel1'),0,cent,charindex)
2554
+ ilbl_ud += 1
2555
+ else
2556
+ begin
2557
+ if(opt['chval_fmt'])
2558
+ char = DCL::chval(opt['chval_fmt'],levels[i])
2559
+ else
2560
+ char = sprintf_level(levels[i],lvmx,lvmn,dlv)
2561
+ end
2562
+ DCL::sgtxzr(vxlabel,vy[i],char,DCL::uzrget('rsizel1'),0,cent,charindex)
2563
+ rescue
2564
+ DCL::sgtxzr(vxlabel,vy[i],levels[i].to_s,DCL::uzrget('rsizel1'),0,cent,charindex)
2565
+ end
2566
+ end
2567
+ end
2568
+ # tick lines and short-side frame
2569
+ if (!no_tick && (i % tickintv) == offs_tick) || (!inf0 && i == 0) || (!inf1 && i == nlev-1)
2570
+ DCL::sgplzv([vxmin,vxmax],[vy[i],vy[i]],1,index)
2571
+ end
2572
+ end
2573
+
2574
+ else ## landscape ##
2575
+ if voff > 0
2576
+ vylabel = vymax+(0.5+DCL::uzrget('pad1'))*DCL::uzrget('rsizel1')
2577
+ # title
2578
+ DCL::sgtxzr((vxmin+vxmax)/2.0, vymin-(0.5+DCL::uzrget('pad1'))*DCL::uzrget('rsizec1'), opt['title'], DCL::uzrget('rsizec1'), 0, 0, charindex) if opt['title']
2579
+ # units
2580
+ DCL::sgtxzr(vxmax+3.0*DCL::uzrget('rsizel1'), vymax+(0.5+DCL::uzrget('pad1'))*DCL::uzrget('rsizel1'), opt['units'], DCL::uzrget('rsizel1'), 0, -1, charindex) if opt['units']
2581
+ else
2582
+ vylabel = vymin-(0.5+DCL::uzrget('pad1'))*DCL::uzrget('rsizel1')
2583
+ # title
2584
+ DCL::sgtxzr((vxmin+vxmax)/2.0, vymax+(0.5+DCL::uzrget('pad1'))*DCL::uzrget('rsizec1'), opt['title'], DCL::uzrget('rsizec1'), 0, 0, charindex) if opt['title']
2585
+ # units
2586
+ DCL::sgtxzr(vxmax+3.0*DCL::uzrget('rsizel1'), vymin-(0.5+DCL::uzrget('pad1'))*DCL::uzrget('rsizel1'), opt['units'], DCL::uzrget('rsizel1'), 0, -1, charindex) if opt['units']
2587
+ end
2588
+
2589
+ ilbl_ud = 0
2590
+ for i in 0..nlev-1
2591
+ # labels
2592
+ if !no_label && (i % labelintv) == offs_label
2593
+ if labels_ud
2594
+ char = labels_ud[ilbl_ud]
2595
+ DCL::sgtxzr(vx[i],vylabel,char,DCL::uzrget('rsizel1'),0,0,charindex)
2596
+ ilbl_ud += 1
2597
+ else
2598
+ begin
2599
+ if(opt['chval_fmt'])
2600
+ char = DCL::chval(opt['chval_fmt'],levels[i])
2601
+ else
2602
+ char = sprintf_level(levels[i],lvmx,lvmn,dlv)
2603
+ end
2604
+ DCL::sgtxzr(vx[i],vylabel,char,DCL::uzrget('rsizel1'),0,0,charindex)
2605
+ rescue
2606
+ DCL::sgtxzr(vx[i],vylabel,levels[i].to_s,DCL::uzrget('rsizel1'),0,0,charindex)
2607
+ end
2608
+ end
2609
+ end
2610
+ # tick lines and short-side frame
2611
+ if (!no_tick && (i % tickintv) == offs_tick) || (!inf0 && i == 0) || (!inf1 && i == nlev-1)
2612
+ DCL::sgplzv([vx[i],vx[i]],[vymin,vymax],1,index)
2613
+ end
2614
+ end
2615
+ end
2616
+
2617
+ else ### opt["constwidth"] == false ###
2618
+
2619
+ inner_bk = DCL::uziget('inner')
2620
+ uz_set_params('inner'=>1)
2621
+
2622
+ tick1 = Array.new
2623
+ tick2 = Array.new
2624
+ for i in 0..levels.length-1
2625
+ # if i>=idumin && i<=idumax && levels[i]!=rmiss
2626
+ if levels[i]!=rmiss
2627
+ tick1.push(levels[i]) if (i % tickintv) == offs_tick
2628
+ tick2.push(levels[i]) if (i % labelintv) == offs_label
2629
+ end
2630
+ end
2631
+
2632
+ if portrait
2633
+
2634
+ if voff > 0
2635
+ before = uz_set_params('labelyl'=>false,'labelyr'=>true,'icentyr'=>-1.0)
2636
+ else
2637
+ before = uz_set_params('labelyl'=>true,'labelyr'=>false,'icentyl'=>1.0)
2638
+ end
2639
+
2640
+ # draw frame, tick lines, and labels
2641
+ cfmt_bk = DCL::uyqfmt
2642
+ if opt["log"]
2643
+ fmt = opt['chval_fmt'] || "b"
2644
+ else
2645
+ fmt = opt['chval_fmt'] || level_chval_fmt(lvmx,lvmn,dlv)
2646
+ end
2647
+ DCL::uysfmt(fmt)
2648
+
2649
+ rsizet1_bk = DCL::uzrget("rsizet1")
2650
+ rsizet2_bk = DCL::uzrget("rsizet2")
2651
+ uz_set_params('rsizet1'=>vwidth,'rsizet2'=>0.0)
2652
+ if no_label
2653
+ nl_labelxt = DCL::uzlget('labelxt')
2654
+ nl_labelxb = DCL::uzlget('labelxb')
2655
+ nl_labelyl = DCL::uzlget('labelyl')
2656
+ nl_labelyr = DCL::uzlget('labelyr')
2657
+ uz_set_params('labelxt'=>false,'labelxb'=>false,'labelyl'=>false,'labelyr'=>false)
2658
+ end
2659
+ if no_tick
2660
+ nt_rsizet1 = DCL::uzrget('rsizet1')
2661
+ DCL::uzrset("rsizet1",0.0)
2662
+ end
2663
+
2664
+ if labels_ud
2665
+ if labels_ud.size != tick2.size
2666
+ raise ArgumentError, "'labels_ud' must be an Array of length==#{tick2.size} in this case"
2667
+ end
2668
+ nc = labels_ud.collect{|c| c.size}.max
2669
+ DCL::uyaxlb("l",tick1,tick2,labels_ud,nc)
2670
+ DCL::uyaxlb("r",tick1,tick2,labels_ud,nc)
2671
+ else
2672
+ DCL::uyaxnm("l",tick1,tick2)
2673
+ DCL::uyaxnm("r",tick1,tick2)
2674
+ end
2675
+ DCL::uxaxdv("b",1,index) if !inf0
2676
+ DCL::uxaxdv("t",1,index) if !inf1
2677
+
2678
+ if no_tick
2679
+ DCL::uzrset("rsizet1",nt_rsizet1)
2680
+ end
2681
+ if no_label
2682
+ uz_set_params('labelxt'=>nl_labelxt,'labelxb'=>nl_labelxb,'labelyl'=>nl_labelyl,'labelyr'=>nl_labelyr)
2683
+ end
2684
+ DCL::uzrset("rsizet1",rsizet1_bk)
2685
+ DCL::uzrset("rsizet2",rsizet2_bk)
2686
+
2687
+ DCL::uysfmt(cfmt_bk)
2688
+
2689
+ # units and title
2690
+ if voff > 0
2691
+ DCL::uysttl("l", opt["title"], 0.0) if opt["title"]
2692
+ DCL::sgtxzr(vxmax+DCL::uzrget('pad1')*DCL::uzrget('rsizel1'), vymax+3.0*DCL::uzrget('rsizel1'), opt['units'], DCL::uzrget('rsizel1'), 0, -1, charindex) if opt['units']
2693
+ else
2694
+ irotcyr_bk = DCL::uziget('irotcyr')
2695
+ DCL::uziset('irotcyr', 3)
2696
+ DCL::uysttl("r", opt["title"], 0.0) if opt["title"]
2697
+ DCL::uziset('irotcyr', irotcyr_bk)
2698
+ DCL::sgtxzr(vxmin-DCL::uzrget('pad1')*DCL::uzrget('rsizel1'), vymax+3.0*DCL::uzrget('rsizel1'), opt['units'], DCL::uzrget('rsizel1'), 0, 1, charindex) if opt['units']
2699
+ end
2700
+
2701
+ uz_set_params(before)
2702
+
2703
+ else ## landscape ##
2704
+
2705
+ if voff > 0
2706
+ before = uz_set_params('labelxt'=>true,'labelxb'=>false)
2707
+ else
2708
+ before = uz_set_params('labelxt'=>false,'labelxb'=>true)
2709
+ end
2710
+
2711
+ # draw frame, tick lines, and labels
2712
+ cfmt_bk = DCL::uxqfmt
2713
+ if opt["log"]
2714
+ fmt = opt['chval_fmt'] || "b"
2715
+ else
2716
+ fmt = opt['chval_fmt'] || level_chval_fmt(lvmx,lvmn,dlv)
2717
+ end
2718
+ DCL::uxsfmt(fmt)
2719
+
2720
+ rsizet1_bk = DCL::uzrget("rsizet1")
2721
+ rsizet2_bk = DCL::uzrget("rsizet2")
2722
+ uz_set_params('rsizet1'=>vwidth,'rsizet2'=>0.0)
2723
+ if no_label
2724
+ nl_labelxt = DCL::uzlget('labelxt')
2725
+ nl_labelxb = DCL::uzlget('labelxb')
2726
+ nl_labelyl = DCL::uzlget('labelyl')
2727
+ nl_labelyr = DCL::uzlget('labelyr')
2728
+ uz_set_params('labelxt'=>false,'labelxb'=>false,'labelyl'=>false,'labelyr'=>false)
2729
+ end
2730
+ if no_tick
2731
+ nt_rsizet1 = DCL::uzrget('rsizet1')
2732
+ DCL::uzrset("rsizet1",0.0)
2733
+ end
2734
+
2735
+ if labels_ud
2736
+ if labels_ud.size != tick2.size
2737
+ raise ArgumentError, "'labels_ud' must be an Array of length==#{tick2.size} in this case"
2738
+ end
2739
+ nc = labels_ud.collect{|c| c.size}.max
2740
+ DCL::uxaxlb("t",tick1,tick2,labels_ud,nc)
2741
+ DCL::uxaxlb("b",tick1,tick2,labels_ud,nc)
2742
+ else
2743
+ DCL::uxaxnm("t",tick1,tick2)
2744
+ DCL::uxaxnm("b",tick1,tick2)
2745
+ end
2746
+ DCL::uyaxdv("l",1,index) if !inf0
2747
+ DCL::uyaxdv("r",1,index) if !inf1
2748
+
2749
+ if no_tick
2750
+ DCL::uzrset("rsizet1",nt_rsizet1)
2751
+ end
2752
+ if no_label
2753
+ uz_set_params('labelxt'=>nl_labelxt,'labelxb'=>nl_labelxb,'labelyl'=>nl_labelyl,'labelyr'=>nl_labelyr)
2754
+ end
2755
+ DCL::uzrset("rsizet1",rsizet1_bk)
2756
+ DCL::uzrset("rsizet2",rsizet2_bk)
2757
+
2758
+ DCL::uxsfmt(cfmt_bk)
2759
+
2760
+ # units and title
2761
+ if voff > 0
2762
+ DCL::uxsttl("b", opt["title"], 0.0) if opt["title"]
2763
+ DCL::sgtxzr(vxmax+3.0*DCL::uzrget('rsizel1'), vymax+(0.5+DCL::uzrget('pad1'))*DCL::uzrget('rsizel1'), opt['units'], DCL::uzrget('rsizel1'), 0, -1, charindex) if opt['units']
2764
+ else
2765
+ DCL::uxsttl("t", opt["title"], 0.0) if opt["title"]
2766
+ DCL::sgtxzr(vxmax+3.0*DCL::uzrget('rsizel1'), vymin-(0.5+DCL::uzrget('pad1'))*DCL::uzrget('rsizel1'), opt['units'], DCL::uzrget('rsizel1'), 0, -1, charindex) if opt['units']
2767
+ end
2768
+
2769
+ uz_set_params(before)
2770
+
2771
+ end
2772
+
2773
+ DCL::uzlset("labelxb",xb)
2774
+ DCL::uzlset("labelyl",yl)
2775
+
2776
+ DCL::grsvpt(vx1,vx2,vy1,vy2)
2777
+ if itrsv <= 4
2778
+ DCL::grswnd(ux1sv, ux2sv, uy1sv, uy2sv)
2779
+ DCL::grstrn(itrsv)
2780
+ else
2781
+ DCL.sgssim(simfacsv,vxoffsv,vyoffsv)
2782
+ DCL.sgsmpl(plxsv,plysv,plrotsv)
2783
+ end
2784
+ DCL::grstrf
2785
+
2786
+ uz_set_params('inner'=>inner_bk)
2787
+ end
2788
+
2789
+ DCL::uziset("indext1",indext1_bk)
2790
+ DCL::uziset("indext2",indext2_bk)
2791
+ DCL::uziset("indexl1",indexl1_bk)
2792
+ DCL::uzrset("rsizel1",rsizel1_bk)
2793
+ DCL::uzrset("rsizec1",rsizec1_bk)
2794
+
2795
+ DCL::sglset("lclip", lclip_bk)
2796
+ nil
2797
+ end
2798
+
2799
+ # Annotates line/mark type and index (and size if mark).
2800
+ # By defualt it is shown in the right margin of the viewport.
2801
+ #
2802
+ # * str is a String to show
2803
+ # * line: true->line ; false->mark
2804
+ # * vx: vx of the left-hand point of legend line (or mark position).
2805
+ # * nil : internally determined
2806
+ # * Float && > 0 : set explicitly
2807
+ # * Float && < 0 : move it relatively to the left from the defualt
2808
+ # * dx: length of the legend line (not used if mark).
2809
+ # * nil : internally determined
2810
+ # * Float && > 0 : set explicitly
2811
+ # * vy: vy of the legend (not used if !first -- see below).
2812
+ # * nil : internally determined
2813
+ # * Float && > 0 : set explicitly
2814
+ # * Float && < 0 : move it relatively lower from the defualt
2815
+ # * first : if false, vy is moved lower relatively from the previous vy.
2816
+ # * mark_size : size of the mark. if nil, size is used.
2817
+ def legend(str, type, index, line=false, size=nil,
2818
+ vx=nil, dx=nil, vy=nil, first=true, mark_size=nil)
2819
+
2820
+ size = DCL::uzrget("rsizel1")*0.95 if !size
2821
+ mark_size = size if !mark_size
2822
+
2823
+ vpx1,vpx2,vpy1,vpy2 = DCL.sgqvpt
2824
+ if first
2825
+ if !vy
2826
+ vy = vpy2 - 0.04
2827
+ elsif vy < 0
2828
+ vy = ( vpy2 - 0.04 ) + vy
2829
+ end
2830
+ @vy = vy
2831
+ else
2832
+ vy = @vy - 1.5*size
2833
+ end
2834
+
2835
+ if !vx
2836
+ vx = vpx2 + 0.015
2837
+ elsif vx < 0
2838
+ vx = (vpx2 + 0.015) + vx
2839
+ end
2840
+
2841
+ if line
2842
+ dx=0.06 if !dx
2843
+ vx2 = vx + dx
2844
+ DCL::sgplzv([vx,vx2],[vy,vy],type,index)
2845
+ DCL.sgtxzv(vx2+0.01,vy,str,size,0,-1,3)
2846
+ else # --> mark
2847
+ DCL::sgpmzv([vx],[vy],type,index,mark_size)
2848
+ DCL.sgtxzv(vx+0.015+mark_size*0.5,vy,str,size,0,-1,3)
2849
+ end
2850
+ nil
2851
+ end
2852
+
2853
+ # Driver of quasi_log_levels with data values
2854
+ def quasi_log_levels_z(vals, nlev=nil, max=nil, min=nil, cycle=1)
2855
+ if max && min
2856
+ quasi_log_levels(max.to_f, min.to_f, cycle)
2857
+ else
2858
+ if nlev
2859
+ eps = 0.1
2860
+ norder = (nlev-1.0+eps)/cycle
2861
+ else
2862
+ norder = 3
2863
+ end
2864
+ mx1 = vals.max
2865
+ mx2 = vals.min
2866
+ if min && min < 0
2867
+ max = min
2868
+ min = nil
2869
+ elsif max && max < 0
2870
+ min = max
2871
+ max = nil
2872
+ end
2873
+ maxsv = max
2874
+ minsv = min
2875
+ if !max
2876
+ max = [ mx1.abs, mx2.abs ].max.to_f
2877
+ max = -max if mx1<0
2878
+ end
2879
+ if !min
2880
+ min = max/10**norder
2881
+ else
2882
+ max = min*10**norder if nlev
2883
+ end
2884
+ if !(minsv && minsv>0) && !(maxsv && maxsv <0) && ( mx2<0 && mx1>0 )
2885
+ min = -min
2886
+ end
2887
+ quasi_log_levels(max, min, cycle)
2888
+ end
2889
+ end
2890
+
2891
+ # Returns approximately log-scaled contour/tone levels as well as
2892
+ # major/minor flags for contours. No DCL call is made in here.
2893
+ #
2894
+ # * cycle (Integer; 1, or 2 or 3) : number of level in one-order.
2895
+ # e.g. 1,10,100,.. for cycle==1; 1,3,10,30,.. for cycle==2;
2896
+ # 1,2,5,10,20,50,.. for cycle==3
2897
+ # * lev0, lev1 (Float) : levels are set between this two params
2898
+ # * if lev0 & lev1 > 0 : positive only
2899
+ # * if lev0 & lev1 < 0 : negative only
2900
+ # * if lev0 * lev1 < 0 : both positive and negative
2901
+ # such as over -lev0..-lev1, lev1..lev2
2902
+ # RETURN VALUE:
2903
+ # * [ levels, mjmn ]
2904
+ def quasi_log_levels(lev0, lev1, cycle=1)
2905
+ raise(ArgumentError, "lev0 is zero (non-zero required)") if lev0 == 0.0
2906
+ raise(ArgumentError, "lev1 is zero (non-zero required)") if lev1 == 0.0
2907
+ case cycle
2908
+ when 1
2909
+ cycl_levs = [1.0]
2910
+ when 2
2911
+ cycl_levs = [1.0, 3.0]
2912
+ when 3
2913
+ cycl_levs = [1.0, 2.0, 5.0]
2914
+ else
2915
+ raise(ArgumentError, "cycle must be 1,2,or 3, which is now #{cycle}")
2916
+ end
2917
+
2918
+ if lev0 > 0 and lev1 > 0
2919
+ positive = true
2920
+ negative = false
2921
+ elsif lev0 < 0 and lev1 < 0
2922
+ positive = false
2923
+ negative = true
2924
+ else
2925
+ positive = true
2926
+ negative = true
2927
+ end
2928
+ sml, big = [lev0.abs,lev1.abs].sort
2929
+
2930
+ expsml = Math::log10(sml).floor
2931
+ expbig = Math::log10(big).ceil
2932
+
2933
+ levels = Array.new
2934
+ mjmn = Array.new
2935
+
2936
+ for i in expsml..expbig-1
2937
+ for k in 0..cycle-1
2938
+ lev = cycl_levs[k] * 10**i
2939
+ if lev >= sml && lev <= big
2940
+ levels.push( lev )
2941
+ mjmn.push( k==0 ? 1 : 0 )
2942
+ end
2943
+ end
2944
+ end
2945
+ lev = 10**expbig
2946
+ if lev == big
2947
+ levels.push( lev )
2948
+ mjmn.push( 1 )
2949
+ end
2950
+
2951
+ if negative && !positive
2952
+ levels = levels.reverse.collect{|x| -x}
2953
+ mjmn = mjmn.reverse
2954
+ elsif negative && positive
2955
+ levels.dup.each{|x| levels.unshift(-x)}
2956
+ mjmn.dup.each{|x| mjmn.unshift(x)}
2957
+ end
2958
+
2959
+ [ levels, mjmn ]
2960
+ end
2961
+ end
2962
+
2963
+ ####################################################################
2964
+ ####################################################################
2965
+ ####################################################################
2966
+
2967
+ module GGraph
2968
+
2969
+ class << self
2970
+ ## private methods in the module
2971
+ def __shorten_path(str,maxlen)
2972
+ return str if str.length <= maxlen
2973
+ astr = str.split(/\//)
2974
+ while(str.length > maxlen)
2975
+ astr.length!=2 ? at = (astr.length)/2 : at = 0
2976
+ astr.delete_at( at )
2977
+ (a = astr.dup)[at, 0] = '...' # insert(at,'...') if Ruby>=1.8
2978
+ str = a.join('/')
2979
+ end
2980
+ str
2981
+ end
2982
+ private :__shorten_path
2983
+ end
2984
+
2985
+ module_function
2986
+
2987
+ def gropn_1_if_not_yet
2988
+ begin
2989
+ DCL.stqwrc
2990
+ rescue
2991
+ DCL.gropn(1)
2992
+ end
2993
+ end
2994
+
2995
+ def margin_info(program=nil, data_source=nil, char_height=nil, date=nil,
2996
+ xl=0.0, xr=0.0, yb=nil, yt=0.0)
2997
+
2998
+ program = File.expand_path($0) if !program
2999
+ if date
3000
+ program = __shorten_path(program,77) + ' ' + Date.today.to_s
3001
+ else
3002
+ program = __shorten_path(program,99)
3003
+ if date.nil?
3004
+ program = program + ' ' + Date.today.to_s if program.length < 77
3005
+ end
3006
+ end
3007
+ if !data_source
3008
+ data_source = Dir.pwd
3009
+ data_source = '' if data_source == program.sub(/\/[^\/]+$/,'')
3010
+ end
3011
+ data_source = __shorten_path(data_source,99)
3012
+ sz = 1.0/( program.length + data_source.length )
3013
+ char_height = [0.008, sz].min if !char_height
3014
+ yb = 2.0 * char_height if !yb
3015
+
3016
+ DCL.slmgn(xl, xr, yb, yt)
3017
+ DCL.slsttl(program, 'b', -1.0, -1.0, char_height, 1)
3018
+ DCL.slsttl(data_source, 'b', 1.0, -1.0, char_height, 2)
3019
+ nil
3020
+ end
3021
+
3022
+ def color_bar(*args)
3023
+ DCLExt.color_bar(*args)
3024
+ end
3025
+
3026
+ def title(string)
3027
+ if string
3028
+ if map_trn? || itr_is?(5)
3029
+ v = DCL::sgqvpt
3030
+ txhgt = DCL.uzpget('rsizec2') # rsizec2: larger text
3031
+ vx = (v[0]+v[1])/2
3032
+ vy = v[3] + (0.5 + DCL.uzpget('pad1')) * txhgt
3033
+ DCL::sgtxzr(vx , vy, string, txhgt, 0, 0, 3)
3034
+ else
3035
+ DCL.uxmttl('t',string,0.0)
3036
+ end
3037
+ end
3038
+ nil
3039
+ end
3040
+
3041
+ def annotate(str_ary, noff=nil)
3042
+ charsize = 0.7 * DCL.uzpget('rsizec1')
3043
+ vxmin,vxmax,vymin,vymax = DCL.sgqvpt
3044
+ vx = vxmax + 0.01
3045
+ vy = vymax - charsize/2
3046
+ annotate_at(str_ary,vx,vy,charsize,-1.0,-1.5,noff)
3047
+ end
3048
+
3049
+ def annotate_at(str_ary,vx,vy,charsize=nil, align=-1.0, dvyfact=-1.5, noff=nil)
3050
+ raise TypeError,"Array expected" if ! str_ary.is_a?(Array)
3051
+ charsize = 0.7 * DCL.uzpget('rsizec1') unless(charsize)
3052
+ dvy = charsize*dvyfact
3053
+ vy += noff*dvy if noff
3054
+ str_ary.each{|str|
3055
+ DCL::sgtxzr(vx,vy,str,charsize,0,align,1)
3056
+ vy += dvy
3057
+ }
3058
+ nannot = str_ary.length
3059
+ nannot += noff if noff
3060
+ nannot
3061
+ end
3062
+
3063
+ @@fig = Misc::KeywordOptAutoHelp.new(
3064
+ ['new_frame',true, 'whether to define a new frame by DCL.grfrm (otherwise, DCL.grfig is called)'],
3065
+ ['no_new_fig',false, 'If true, neither DCL.grfrm nor DCL.grfig is called (overrides new_frame) -- Then, you need to call one of them in advance. Convenient to set DCL parameters that are reset by grfrm or grfig.'],
3066
+ ['itr', 1, 'coordinate transformation number'],
3067
+ ['viewport',[0.2,0.8,0.2,0.8], '[vxmin, vxmax, vymin, vymax]'],
3068
+ ['eqdistvpt',false, 'modify viewport to equidistant for x and y (only for itr=1--4)'],
3069
+ ['window', nil, '(for itr<10,>50) [uxmin, uxmax, uymin, uymax]. each element allowd nil (only for itr<5,>50)'],
3070
+ ['xreverse','positive:down,units:hPa', '(for itr<10,>50) Assign max value to UXMIN and min value to UXMAX if condition is satisfied (nil:never, true:always, String: when an attibute has the value specified ("key:value,key:value,..")'],
3071
+ ['yreverse','positive:down,units:hPa', '(for itr<10,>50) Assign max value to UYMIN and min value to UYMAX if condition is satisfied (nil:never, true:always, String: when an attibute has the value specified ("key:value,key:value,..")'],
3072
+ ['round0', false, 'expand window range to good numbers (effective only to internal window settings)'],
3073
+ ['round1', false, 'expand window range to good numbers (effective even when "window" is explicitly specified)'],
3074
+ # for 5<=itr<=7 (Rectangular Curvilinear Coordinates)
3075
+ ['similar', nil, '3-element float array for similar transformation in a rectangular curvilinear coordinate, which is fed in DCL:grssim:[simfac,vxoff,vyoff], where simfac and [vxoff,vyoff] represent scaling factor and origin shift, respectively.'],
3076
+ # for 10<=itr<=50 (map projection):
3077
+ ['map_axis', nil, '(for all map projections) 3-element float array to be fed in DCL::umscnt: [uxc, uxy, rot], where [uxc, uyc] represents the tangential point (or the pole at top side for cylindrical projections), and rot represents the rotation angle. If nil, internally determined. (units: degrees)'],
3078
+ ['map_radius', nil, '(for itr>=20: conical/azimuhal map projections) raidus around the tangential point. (units: degrees)'],
3079
+ ['map_fit',nil,'(Only for itr=10(cylindrical) and 11 (Mercator)) true: fit the plot to the data window (overrides map_window and map_axis); false: do not fit (then map_window and map_axis are used); nil: true if itr==10, false if itr==11'],
3080
+ ['map_window', [-180,180,-75,75], '(for itr<20: cylindrical map projections) lon-lat window [lon_min, lon_max, lat_min, lat_max ] to draw the map (units: degres)']
3081
+ )
3082
+
3083
+ def set_fig(options)
3084
+ @@fig.set(options)
3085
+ end
3086
+
3087
+ @@next_fig = nil
3088
+ def next_fig(options)
3089
+ if options.is_a?(Hash)
3090
+ @@next_fig = options
3091
+ else
3092
+ raise TypeError,"Hash expected"
3093
+ end
3094
+ nil
3095
+ end
3096
+
3097
+ def map_trn?( fig_yet_to_be_called=false )
3098
+ if fig_yet_to_be_called
3099
+ itr = ( @@next_fig && @@next_fig['itr'] ) || @@fig['itr']
3100
+ else
3101
+ itr = DCL.sgqtrn
3102
+ end
3103
+ case itr
3104
+ when 1..9,51..99
3105
+ false
3106
+ else
3107
+ true
3108
+ end
3109
+ end
3110
+
3111
+ def itr_is?( itr, fig_yet_to_be_called=false )
3112
+ if fig_yet_to_be_called
3113
+ current_itr = ( @@next_fig && @@next_fig['itr'] ) || @@fig['itr']
3114
+ else
3115
+ current_itr = DCL.sgqtrn
3116
+ end
3117
+ current_itr == itr
3118
+ end
3119
+
3120
+ def sim_trn?
3121
+ itr = DCL.sgqtrn
3122
+ case itr
3123
+ when 5..7
3124
+ true
3125
+ else
3126
+ false
3127
+ end
3128
+ end
3129
+
3130
+ def fig(xax=nil, yax=nil, options=nil)
3131
+
3132
+ # xax and yax are needed (i.e. Axis objects) if not map projection
3133
+
3134
+ if @@next_fig
3135
+ options = ( options ? @@next_fig.update(options) : @@next_fig )
3136
+ @@next_fig = nil
3137
+ end
3138
+ opts = @@fig.interpret(options)
3139
+
3140
+ if opts['no_new_fig']
3141
+ # do nothing
3142
+ elsif opts['new_frame']
3143
+ DCL.grfrm
3144
+ else
3145
+ DCL.grfig
3146
+ end
3147
+ raise "viewport's length must be 4" if opts['viewport'].length != 4
3148
+ DCL.grsvpt(*opts['viewport'])
3149
+
3150
+ if opts['window']
3151
+ if !opts['window'].is_a?(Array) || opts['window'].length!=4
3152
+ raise "Option 'window' must be an Array of length==4"
3153
+ end
3154
+ end
3155
+
3156
+ itr = opts['itr']
3157
+ DCL.grstrn(itr)
3158
+
3159
+ map_fit = ( (itr==10 and opts['map_fit']!=false) or
3160
+ (itr==11 and opts['map_fit']==true) )
3161
+
3162
+ if ( (1<=itr and itr<=4) or (51<=itr and itr<=99) or map_fit )
3163
+ window = opts['window']
3164
+ window = ( window ? window.dup : [nil, nil, nil, nil])
3165
+ if window.include?(nil)
3166
+ raise(ArgumentError, "xax and yax must be provided") if !xax or !yax
3167
+ if (xreverse=opts['xreverse']).is_a?(String)
3168
+ atts = opts['xreverse'].split(',').collect{|v| v.split(':')}
3169
+ xreverse = false
3170
+ atts.each{|key,val|
3171
+ xreverse = ( xax.get_att(key) == val )
3172
+ break if xreverse
3173
+ }
3174
+ end
3175
+ if (yreverse=opts['yreverse']).is_a?(String)
3176
+ atts = opts['yreverse'].split(',').collect{|v| v.split(':')}
3177
+ yreverse = false
3178
+ atts.each{|key,val|
3179
+ yreverse = ( yax.get_att(key) == val )
3180
+ break if yreverse
3181
+ }
3182
+ end
3183
+ if xreverse
3184
+ xrange = [ xax.max, xax.min ]
3185
+ else
3186
+ xrange = [ xax.min, xax.max ]
3187
+ end
3188
+ if yreverse
3189
+ yrange = [ yax.max, yax.min ]
3190
+ else
3191
+ yrange = [ yax.min, yax.max ]
3192
+ end
3193
+ [ xrange, yrange ].each do |range|
3194
+ r0 = range[0]
3195
+ r1 = range[1]
3196
+ if r0 == r1
3197
+ if r0.nil?
3198
+ raise("Cannot set a window. Maybe plotting all-missing data?")
3199
+ end
3200
+ # if the max and min of the range is the same, shift them a bit
3201
+ range[0] = DCL.rgnlt(r0)
3202
+ range[1] = DCL.rgngt(r0)
3203
+ end
3204
+ end
3205
+ default_window=[xrange[0], xrange[1], yrange[0], yrange[1]]
3206
+ default_window = __round_window(default_window) if opts['round0']
3207
+ if window.nitems == 0 # if all elements is nil
3208
+ window = default_window
3209
+ else
3210
+ window.each_index do |i|
3211
+ window[i] = default_window[i] if window[i] == nil
3212
+ end
3213
+ end
3214
+ window = __round_window(window) if opts['round1']
3215
+ end
3216
+ end
3217
+
3218
+ case itr
3219
+ when 1..4,51..99
3220
+ # all but for map projections and curvilinear coordinates
3221
+ DCL.grswnd(*window)
3222
+ if itr <= 4 and opts['eqdistvpt']
3223
+ # modify viewport to equidistant
3224
+ vx1,vx2,vy1,vy2 = opts['viewport']
3225
+ wx1,wx2,wy1,wy2 = window
3226
+ vxw = (vx2-vx1).abs
3227
+ vyw = (vy2-vy1).abs
3228
+ wxw = (wx2-wx1).abs
3229
+ wyw = (wy2-wy1).abs
3230
+ if ( [vxw,vyw,wxw,wyw].min > 0 )
3231
+ rx = wxw / vxw
3232
+ ry = wyw / vyw
3233
+ if rx > ry
3234
+ rc = ry/rx
3235
+ vym = (vy1+vy2)/2.0
3236
+ vy1 = vym - rc*vyw/2.0
3237
+ vy2 = vym + rc*vyw/2.0
3238
+ elsif rx < ry
3239
+ rc = rx/ry
3240
+ vxm = (vx1+vx2)/2.0
3241
+ vx1 = vxm - rc*vxw/2.0
3242
+ vx2 = vxm + rc*vxw/2.0
3243
+ end
3244
+ DCL.grsvpt(vx1,vx2,vy1,vy2)
3245
+ end
3246
+ end
3247
+ when 5,6
3248
+ if opts['similar']
3249
+ similar=opts['similar']
3250
+ DCL.grssim(*similar)
3251
+ elsif opts['window']
3252
+ if defined?(DCL::DCLVERSION) && DCL::DCLVERSION >= '5.3'
3253
+ DCL.sgscwd(*opts['window'])
3254
+ else
3255
+ raise "You need DCL 5.3 or later to use the 'window' parameter in this transform (#{itr}). Use 'similar' instead."
3256
+ end
3257
+ else
3258
+ case itr
3259
+ when 5
3260
+ vxmin,vxmax,vymin,vymax=DCL.sgqvpt
3261
+ raise(ArgumentError, "xax must be provided") if !xax
3262
+ simfac = (vymax-vymin)/(xax.max*2) # only xax is used
3263
+ similar = [simfac,0.0,0.0]
3264
+ DCL.grssim(*similar)
3265
+ else
3266
+ raise NotImplementedError, "Sorry, automatic window setting is yet to be available for the transform #{itr}. Please specify the 'similar' or 'window' parameter"
3267
+ end
3268
+ end
3269
+
3270
+ when 10..15
3271
+ if !map_fit
3272
+ map_axis = opts['map_axis'] || [180.0, 0.0, 0.0]
3273
+ DCL::umscnt( *map_axis )
3274
+ map_window = opts['map_window']
3275
+ raise "map_window's length must be 4" if map_window.length != 4
3276
+ map_lat_range = [ map_window[2], map_window[3] ]
3277
+ if map_lat_range.is_a?(Range)
3278
+ map_lat_range = [map_lat_range.first, map_lat_range.end]
3279
+ end
3280
+ case ( map_axis[2] - map_axis[1] ) % 360
3281
+ when 0
3282
+ tyrange = map_lat_range
3283
+ when 180
3284
+ tyrange = [ -map_lat_range[1], -map_lat_range[0] ]
3285
+ else
3286
+ tyrange = [ -75, 75 ] # latange is ignored
3287
+ end
3288
+ DCL::grstxy(map_window[0], map_window[1], tyrange[0], tyrange[1])
3289
+ else
3290
+ lon_cent =( window[0] + window[1] ) / 2.0
3291
+ dlon2 = ( window[1] - window[0] ) / 2.0
3292
+ map_axis = [ lon_cent, 0.0, 0.0 ]
3293
+ DCL::sgswnd(*window)
3294
+ DCL::umscnt( *map_axis )
3295
+ DCL::grstxy( -dlon2, dlon2, window[2], window[3] )
3296
+ end
3297
+ sv = DCL.umpget('lglobe')
3298
+ DCL.umpset('lglobe', true)
3299
+ DCL::umpfit
3300
+ when 20..33
3301
+ map_axis = opts['map_axis'] || [180.0, 90.0, 0.0]
3302
+ map_radius = opts['map_radius'] || 70.0
3303
+ DCL::umscnt( *map_axis )
3304
+ case itr
3305
+ when 31
3306
+ v = opts['viewport']
3307
+ vptsize = [ v[1]-v[0], v[3]-v[2] ].min
3308
+ DCL::grssim( vptsize*0.25/Math::tan(0.5*Math::PI*map_radius/180.0), 0.0, 0.0 )
3309
+ when 22
3310
+ v = opts['viewport']
3311
+ vptsize = [ v[1]-v[0], v[3]-v[2] ].min
3312
+ DCL::grssim( vptsize*0.35*(90.0/map_radius), 0.0, 0.0 )
3313
+ DCL::grstxy(-180.0, 180.0, 90.0-map_radius, 90.0)
3314
+ else
3315
+ DCL::grstxy(-180.0, 180.0, 90.0-map_radius, 90.0)
3316
+ end
3317
+ sv = DCL.umpget('lglobe')
3318
+ DCL.umpset('lglobe', true)
3319
+ DCL::umpfit
3320
+ DCL.umpset('lglobe', sv)
3321
+ else
3322
+ raise "unsupported transformation number: #{itr}"
3323
+ end
3324
+
3325
+ DCL.grstrf
3326
+ DCL.umpset('lglobe', sv)
3327
+ nil
3328
+ end
3329
+
3330
+ def __good_range(x0,x1)
3331
+ x0 = x0.to_f
3332
+ x1 = x1.to_f
3333
+ xw = (x1-x0).abs
3334
+ e10, lx = (Math::log10(xw)).divmod(1.0)
3335
+ ef = 5.0 * 10**(-e10)
3336
+ [(x0*ef).floor/ef,(x1*ef).ceil/ef]
3337
+ end
3338
+ private :__good_range
3339
+ def __round_window(window)
3340
+ x0,x1 = __good_range(window[0],window[1])
3341
+ y0,y1 = __good_range(window[2],window[3])
3342
+ [ x0, x1, y0, y1 ]
3343
+ end
3344
+ private :__round_window
3345
+
3346
+ @@axes = Misc::KeywordOptAutoHelp.new(
3347
+ ['xside', 'tb', 'Where to draw xaxes (combination of t, b and u)'],
3348
+ ['yside', 'lr', 'Where to draw yaxes (combination of l, r and u)'],
3349
+ ['xtitle', nil, 'Title of x axis (if nil, internally determined)'],
3350
+ ['ytitle', nil, 'Title of y axis (if nil, internally determined)'],
3351
+ ['xunits', nil, 'Units of x axis (if nil, internally determined)'],
3352
+ ['yunits', nil, 'Units of y axis (if nil, internally determined)'],
3353
+ ['xtickint', nil,
3354
+ 'Interval of x axis tickmark (if nil, internally determined)'],
3355
+ ['ytickint', nil,
3356
+ 'Interval of y axis tickmark (if nil, internally determined)'],
3357
+ ['xlabelint', nil,
3358
+ 'Interval of x axis label (if nil, internally determined)'],
3359
+ ['ylabelint', nil,
3360
+ 'Interval of y axis label (if nil, internally determined)'],
3361
+ ['xmaplabel', false,
3362
+ 'If "lon"("lat"), use DCLExt::lon_ax(DCLExt::lat_ax) to draw xaxes; otherwise, DCL::usxaxs is used.'],
3363
+ ['ymaplabel', false,
3364
+ 'If "lon"("lat"), use DCLExt::lon_ax(DCLExt::lat_ax) to draw yaxes; otherwise, DCL::usyaxs is used.'],
3365
+ ['time_ax', nil, 'Type of calendar-type time axis: nil (=> auto slection), false (do not use the time axis even if the units of the axis is a time one with since field), "h" (=> like nil, but always use the hour-resolving datetime_ax method in dclext_datetime_ax.rb), or "ymd" (=> like "h" but for y-m-d type using DCL.uc[xy]acl)']
3366
+ )
3367
+ def set_axes(options)
3368
+ @@axes.set(options)
3369
+ end
3370
+
3371
+ @@next_axes = nil
3372
+ def next_axes(options)
3373
+ if options.is_a?(Hash)
3374
+ @@next_axes = options
3375
+ else
3376
+ raise TypeError,"Hash expected"
3377
+ end
3378
+ nil
3379
+ end
3380
+
3381
+ # axtype: nil (-->auto), 'h' (to resolve hours), or 'ymd'
3382
+ def __calendar_ax(axtype, xax, side, sunits, ttl, \
3383
+ tickint=nil, labelint=nil)
3384
+ window = DCL.sgqwnd
3385
+ viewport = DCL.sgqvpt
3386
+ /(.*) *since *(.*)/ =~ sunits
3387
+ if (!$1 or !$2)
3388
+ raise("Units mismatch. Requires time units that includes 'since'")
3389
+ end
3390
+ tun = Units[$1]
3391
+ dayun = Units['days']
3392
+ since = DateTime.parse($2)
3393
+ if xax
3394
+ t0 = window[0]
3395
+ t1 = window[1]
3396
+ else
3397
+ t0 = window[2]
3398
+ t1 = window[3]
3399
+ end
3400
+ tstr = since + tun.convert( t0, dayun )
3401
+ jd0 = tstr.strftime('%Y%m%d').to_i
3402
+ tlen = tun.convert( t1-t0, dayun )
3403
+ if !axtype
3404
+ if tlen < 5
3405
+ axtype = 'h'
3406
+ else
3407
+ axtype = 'ymd'
3408
+ end
3409
+ end
3410
+
3411
+ if xax
3412
+ DCL.grswnd(0.0, tlen, window[2], window[3] )
3413
+ DCL.grstrf
3414
+ if axtype == 'h'
3415
+ opts = {'cside'=>side}
3416
+ opts['dtick1'] = tickint if tickint
3417
+ opts['dtick2'] = labelint if labelint
3418
+ DCLExt.datetime_ax(tstr, tstr+tlen, opts )
3419
+ else
3420
+ DCL.ucxacl(side,jd0,tlen)
3421
+ end
3422
+ DCL.grswnd(*window)
3423
+ DCL.grstrf
3424
+ else
3425
+ DCL.grswnd(window[0], window[1], 0.0, tlen)
3426
+ DCL.grstrf
3427
+ if axtype == 'h'
3428
+ opts = {'yax'=>true, 'cside'=>side}
3429
+ opts['dtick1'] = tickint if tickint
3430
+ opts['dtick2'] = labelint if labelint
3431
+ DCLExt.datetime_ax(tstr, tstr+tlen, opts )
3432
+ else
3433
+ DCL.ucyacl(side,jd0,tlen)
3434
+ end
3435
+ DCL.grswnd(*window)
3436
+ DCL.grstrf
3437
+ end
3438
+ end
3439
+ private :__calendar_ax
3440
+
3441
+ def axes(xax=nil, yax=nil, options=nil)
3442
+ if @@next_axes
3443
+ options = ( options ? @@next_axes.update(options) : @@next_axes )
3444
+ @@next_axes = nil
3445
+ end
3446
+ opts = @@axes.interpret(options)
3447
+ if opts['xside'].length > 0
3448
+ xai = _get_axinfo(xax)
3449
+ if opts['xmaplabel'] == "lon"
3450
+ opts['xside'].split('').each{|s| # scan('.') also works
3451
+ DCLExt.lon_ax('cside'=>s, 'dtick1'=>opts['xtickint'], 'dtick2'=>opts['xlabelint'])
3452
+ }
3453
+ DCL.uxsttl('b', (opts['xtitle'] || xai['title']), 0.0)
3454
+ elsif opts['xmaplabel'] == "lat"
3455
+ opts['xside'].split('').each{|s| # scan('.') also works
3456
+ DCLExt.lat_ax('xax'=>true, 'cside'=>s, 'dtick1'=>opts['xtickint'], 'dtick2'=>opts['xlabelint'])
3457
+ }
3458
+ DCL.uxsttl('b', (opts['xtitle'] || xai['title']), 0.0)
3459
+ else
3460
+ sunits = opts['xunits'] || xai['units']
3461
+ units = Units[sunits]
3462
+ if opts['time_ax'] != false && \
3463
+ /since/ =~ sunits && units =~ Units['days since 0001-01-01']
3464
+ opts['xside'].split('').each do |s| # scan('.') also works
3465
+ ttl = opts['xtitle'] || xai['title']
3466
+ __calendar_ax(opts['time_ax'], true, s, sunits, ttl,
3467
+ opts['xtickint'], opts['xlabelint'])
3468
+ end
3469
+ else
3470
+ DCL.uscset('cxttl', (opts['xtitle'] || xai['title']) )
3471
+ DCL.uscset('cxunit', sunits)
3472
+ DCL.uspset('dxt', opts['xtickint']) if(opts['xtickint'])
3473
+ DCL.uspset('dxl', opts['xlabelint']) if(opts['xlabelint'])
3474
+ opts['xside'].split('').each{|s| # scan('.') also works
3475
+ DCL.usxaxs(s)
3476
+ }
3477
+ end
3478
+ end
3479
+ end
3480
+ if opts['yside'].length > 0
3481
+ yai = _get_axinfo(yax)
3482
+ if opts['ymaplabel'] == "lon"
3483
+ opts['yside'].split('').each{|s| # scan('.') also works
3484
+ DCLExt.lon_ax('yax'=>true, 'cside'=>s, 'dtick1'=>opts['ytickint'], 'dtick2'=>opts['ylabelint'])
3485
+ }
3486
+ DCL.uysttl('l', (opts['ytitle'] || yai['title']), 0.0)
3487
+ elsif opts['ymaplabel'] == "lat"
3488
+ opts['yside'].split('').each{|s| # scan('.') also works
3489
+ DCLExt.lat_ax('cside'=>s, 'dtick1'=>opts['ytickint'], 'dtick2'=>opts['ylabelint'])
3490
+ }
3491
+ DCL.uysttl('l', (opts['ytitle'] || yai['title']), 0.0)
3492
+ else
3493
+ sunits=(opts['yunits'] || yai['units'])
3494
+ units = Units[sunits]
3495
+ if opts['time_ax'] != false && \
3496
+ /since/ =~ sunits && units =~ Units['days since 0001-01-01']
3497
+ opts['yside'].split('').each do |s| # scan('.') also works
3498
+ ttl = opts['ytitle'] || yai['title']
3499
+ __calendar_ax(opts['time_ax'], false, s, sunits, ttl,
3500
+ opts['ytickint'], opts['ylabelint'])
3501
+ end
3502
+ else
3503
+ DCL.uscset('cyttl', (opts['ytitle'] || yai['title']) )
3504
+ DCL.uscset('cyunit', sunits )
3505
+ DCL.uspset('dyt', opts['ytickint']) if(opts['ytickint'])
3506
+ DCL.uspset('dyl', opts['ylabelint']) if(opts['ylabelint'])
3507
+ opts['yside'].split('').each{|s| # scan('.') also works
3508
+ DCL.usyaxs(s)
3509
+ if s=='l' && sunits && sunits != ''
3510
+ DCL.uzpset('roffxt', DCL.uzpget('rsizec1')*1.5 )
3511
+ end
3512
+ }
3513
+ end
3514
+ end
3515
+ end
3516
+ nil
3517
+ end
3518
+
3519
+ def _get_axinfo(vary)
3520
+ if vary.nil?
3521
+ hash = {
3522
+ 'title'=>'',
3523
+ 'units'=>''
3524
+ }
3525
+ else
3526
+ raise "Not 1D" if vary.rank!=1
3527
+ hash = {
3528
+ 'title'=>(vary.get_att('long_name') || vary.name), #.gsub('_','' )
3529
+ 'units'=>(vary.get_att('units') || '') #.gsub('_',' ')
3530
+ }
3531
+ end
3532
+ hash
3533
+ end
3534
+
3535
+ def polar_coordinate_boundaries(xax=nil,yax=nil)
3536
+
3537
+ slln=DCL.sgpget('LLNINT') ; slgc=DCL.sgpget('LGCINT')
3538
+ DCL.sgpset('LLNINT',true) ; DCL.sgpset('LGCINT',true)
3539
+
3540
+ xmin=xax.min ; xmax=xax.max ; ymin=yax.min ; ymax=yax.max
3541
+ azimuth_len = ymax-ymin
3542
+ azimuth_len = azimuth_len.val if azimuth_len.is_a?(UNumeric)
3543
+ unless( (azimuth_len - 360.0).abs < 1e-2 )
3544
+ # not a full circle
3545
+ DCL.sgplzu([xmin,xmax],[ymin,ymin],1,5)
3546
+ DCL.sgplzu([xmin,xmax],[ymax,ymax],1,5)
3547
+ end
3548
+
3549
+ DCL.sgplzu([xmin,xmin],[ymin,ymax],1,5)
3550
+ DCL.sgplzu([xmax,xmax],[ymin,ymax],1,5)
3551
+
3552
+ DCL.sgpset('LLNINT',slln) ; DCL.sgpset('LGCINT',slgc)
3553
+ nil
3554
+ end
3555
+
3556
+ @@map = Misc::KeywordOptAutoHelp.new(
3557
+ ['lim', true, 'draw map lim (t or f)'],
3558
+ ['grid', true, 'draw map grid (t or f)'],
3559
+ ['vpt_boundary', false, 'draw viewport boundaries (f, t or 1,2,3.., representing the line width)'],
3560
+ ['wwd_boundary', false, 'draw worksation window boundaries (f, t or 1,2,3.., representing the line width)'],
3561
+ ['fill', false, 'fill the map if coast_world or coast_japan is true (t or f)'],
3562
+ ['coast_world', false, 'draw world coast lines (t or f)'],
3563
+ ['border_world', false, 'draw nation borders (t or f)'],
3564
+ ['plate_world', false, 'draw plate boundaries (t or f)'],
3565
+ ['state_usa', false, 'draw state boundaries of US (t or f)'],
3566
+ ['coast_japan', false, 'draw japanese coast lines (t or f)'],
3567
+ ['pref_japan', false, 'draw japanese prefecture boundaries (t or f)'],
3568
+ ['dgridmj', nil, 'the interval between the major lines of latitudes and longitudes. If nil, internally determined. (units: degrees) (this is a UMPACK parameter, which is nullified when uminit or grfrm is called)'],
3569
+ ['dgridmn', nil, 'the interval between the minor lines of latitudes and longitudes. If nil, internally determined. (units: degrees) (this is a UMPACK parameter, which is nullified when uminit or grfrm is called)']
3570
+ )
3571
+
3572
+ def set_map(options)
3573
+ @@map.set(options)
3574
+ end
3575
+
3576
+ @@next_map = nil
3577
+ def next_map(options)
3578
+ if options.is_a?(Hash)
3579
+ @@next_map = options
3580
+ else
3581
+ raise TypeError,"Hash expected"
3582
+ end
3583
+ nil
3584
+ end
3585
+
3586
+ def map(options=nil)
3587
+ if @@next_map
3588
+ options = ( options ? @@next_map.update(options) : @@next_map )
3589
+ @@next_map = nil
3590
+ end
3591
+ opts = @@map.interpret(options)
3592
+ DCL.umplim if opts['lim']
3593
+ DCL.umpset('dgridmj',opts['dgridmj']) if opts['dgridmj']
3594
+ DCL.umpset('dgridmn',opts['dgridmn']) if opts['dgridmn']
3595
+ DCL.umpgrd if opts['grid']
3596
+ if opts['vpt_boundary']
3597
+ if opts['vpt_boundary'].is_a?(Integer)
3598
+ idx = opts['vpt_boundary']
3599
+ else
3600
+ idx = 1
3601
+ end
3602
+ DCL.slpvpr( idx )
3603
+ end
3604
+ if opts['wwd_boundary']
3605
+ if opts['wwd_boundary'].is_a?(Integer)
3606
+ idx = opts['wwd_boundary']
3607
+ else
3608
+ idx = 1
3609
+ end
3610
+ DCL.slpwwr( idx )
3611
+ end
3612
+ DCL.umpmap('coast_world') if opts['coast_world']
3613
+ DCL.umpmap('coast_japan') if opts['coast_japan']
3614
+ if opts['fill']
3615
+ DCL.umfmap('coast_world') if opts['coast_world']
3616
+ DCL.umfmap('coast_japan') if opts['coast_japan']
3617
+ end
3618
+ DCL.umpmap('border_world') if opts['border_world']
3619
+ DCL.umpmap('plate_world') if opts['plate_world']
3620
+ DCL.umpmap('state_usa') if opts['state_usa']
3621
+ DCL.umpmap('pref_japan') if opts['pref_japan']
3622
+ nil
3623
+ end
3624
+
3625
+ def line(gphys, newframe=true, options=nil)
3626
+ gropn_1_if_not_yet
3627
+ if newframe!=true && newframe!=false
3628
+ raise ArgumentError, "2nd arg (newframe) must be true or false"
3629
+ end
3630
+ if ! defined?(@@line_options)
3631
+ @@line_options = Misc::KeywordOptAutoHelp.new(
3632
+ ['title', nil, 'Title of the figure(if nil, internally determined)'],
3633
+ ['annotate', true, 'if false, do not put texts on the right margin even when newframe==true'],
3634
+ ['exchange', false, 'whether to exchange x and y axes'],
3635
+ ['index', 1, 'line/mark index'],
3636
+ ['type', 1, 'line type'],
3637
+ ['label', nil, 'if a String is given, it is shown as the label'],
3638
+ ['max', nil, 'maximam data value'],
3639
+ ['min', nil, 'minimam data value'],
3640
+ ['legend', nil, 'legend to annotate the line type and index. nil (defalut -- do not show); a String as the legend; true to use the name of the GPhys as the legend'],
3641
+ ['legend_vx', nil, '(effective if legend) viewport x values of the lhs of the legend line (positive float); or nil for automatic settting (shown to the right of vpt); or move it to the left relatively (negtive float)'],
3642
+ ['legend_dx', nil, '(effective if legend) length of the legend line'],
3643
+ ['legend_vy', nil, '(effective if legend) viewport y value of the legend (Float; or nil for automatic settting)'],
3644
+ ['legend_size', nil, '(effective if legend) character size of the legend'],
3645
+ ['map_axes', false, '[USE IT ONLY WHEN itr=10 (cylindrical)] If true, draws axes by temprarilly switching to itr=1 and calling GGraph::axes.']
3646
+ )
3647
+ end
3648
+ opts = @@line_options.interpret(options)
3649
+ gp = gphys.first1D
3650
+ window = ( @@next_fig['window'] if @@next_fig ) || @@fig['window']
3651
+ window = ( window ? window.dup : [nil, nil, nil, nil])
3652
+ max = opts['max']; min = opts['min']
3653
+ if !opts['exchange']
3654
+ x = gp.coord(0)
3655
+ y = gp.data
3656
+ window[2] = min if min
3657
+ window[3] = max if max
3658
+ else
3659
+ y = gp.coord(0)
3660
+ x = gp.data
3661
+ window[0] = min if min
3662
+ window[1] = max if max
3663
+ end
3664
+ if newframe
3665
+ fig(x, y, {'window'=>window})
3666
+ axes_or_map_and_ttl(gp, opts, x, y)
3667
+ end
3668
+ if opts['label']
3669
+ lcharbk = DCL.sgpget('lchar')
3670
+ DCL.sgpset('lchar',true)
3671
+ DCL.sgsplc(opts['label'])
3672
+ end
3673
+ DCL.uulinz(x.val, y.val, opts['type'], opts['index'])
3674
+ DCL.sgpset('lchar',lcharbk) if opts['label']
3675
+
3676
+ legend = opts['legend']
3677
+ if legend
3678
+ legend = gp.name if legend==true
3679
+ DCLExt::legend(legend,opts['type'],opts['index'],true,
3680
+ opts['legend_size'],opts['legend_vx'],opts['legend_dx'],
3681
+ opts['legend_vy'],newframe)
3682
+ end
3683
+ nil
3684
+ end
3685
+
3686
+ def mark(gphys, newframe=true, options=nil)
3687
+ gropn_1_if_not_yet
3688
+ if newframe!=true && newframe!=false
3689
+ raise ArgumentError, "2nd arg (newframe) must be true or false"
3690
+ end
3691
+ if ! defined?(@@mark_options)
3692
+ @@mark_options = Misc::KeywordOptAutoHelp.new(
3693
+ ['title', nil, 'Title of the figure(if nil, internally determined)'],
3694
+ ['annotate', true, 'if false, do not put texts on the right margin even when newframe==true'],
3695
+ ['exchange', false, 'whether to exchange x and y axes'],
3696
+ ['index', 1, 'mark index'],
3697
+ ['type', 2, 'mark type'],
3698
+ ['size', 0.01, 'marks size'],
3699
+ ['max', nil, 'maximam data value'],
3700
+ ['min', nil, 'minimam data value'],
3701
+ ['legend', nil, 'legend to annotate the mark type, index, and size. nil (defalut -- do not to show); a String as the legend; true to use the name of the GPhys as the legend'],
3702
+ ['legend_vx', nil, '(effective if legend) viewport x values of the lhs of the legend line (positive float); or nil for automatic settting (shown to the right of vpt); or move it to the left relatively (negtive float)'],
3703
+ ['legend_vy', nil, '(effective if legend) viewport y value of the legend (Float; or nil for automatic settting)'],
3704
+ ['legend_size', nil, '(effective if legend) character size of the legend'],
3705
+ ['map_axes', false, '[USE IT ONLY WHEN itr=10 (cylindrical)] If true, draws axes by temprarilly switching to itr=1 and calling GGraph::axes.']
3706
+ )
3707
+ end
3708
+ opts = @@mark_options.interpret(options)
3709
+ gp = gphys.first1D
3710
+ window = ( @@next_fig['window'] if @@next_fig ) || @@fig['window']
3711
+ window = ( window ? window.dup : [nil, nil, nil, nil])
3712
+ max = opts['max']; min = opts['min']
3713
+ if !opts['exchange']
3714
+ x = gp.coord(0)
3715
+ y = gp.data
3716
+ window[2] = min if min
3717
+ window[3] = max if max
3718
+ else
3719
+ y = gp.coord(0)
3720
+ x = gp.data
3721
+ window[0] = min if min
3722
+ window[1] = max if max
3723
+ end
3724
+ if newframe
3725
+ fig(x, y, {'window'=>window})
3726
+ axes_or_map_and_ttl(gp, opts, x, y)
3727
+ end
3728
+ DCL.uumrkz(x.val, y.val, opts['type'], opts['index'], opts['size'])
3729
+
3730
+ legend = opts['legend']
3731
+ if legend
3732
+ legend = gp.name if legend==true
3733
+ DCLExt::legend(legend,opts['type'],opts['index'],false,
3734
+ opts['legend_size'],opts['legend_vx'],nil,
3735
+ opts['legend_vy'],newframe,opts['size'])
3736
+ end
3737
+ nil
3738
+ end
3739
+
3740
+ @@linear_contour_options = Misc::KeywordOptAutoHelp.new(
3741
+ ['min', nil, 'minimum contour level'],
3742
+ ['max', nil, 'maximum contour level'],
3743
+ ['nlev', nil, 'number of levels'],
3744
+ ['interval', nil, 'contour interval'],
3745
+ ['nozero', nil, 'delete zero contour'],
3746
+ ['coloring', false, 'set color contours with ud_coloring'],
3747
+ ['clr_min', 13, '(if coloring) minimum color number for the minimum data values'],
3748
+ ['clr_max', 99, '(if coloring) maximum color number for the maximum data values']
3749
+ )
3750
+ def set_linear_contour_options(options)
3751
+ @@linear_contour_options.set(options)
3752
+ end
3753
+ @@next_linear_contour_options = nil
3754
+ def next_linear_contour_options(options)
3755
+ if options.is_a?(Hash)
3756
+ @@next_linear_contour_options = options
3757
+ else
3758
+ raise TypeError,"Hash expected"
3759
+ end
3760
+ nil
3761
+ end
3762
+
3763
+ def tone_and_contour(gphys, newframe=true, options=nil)
3764
+ options ? topt=@@contour_options.select_existent(options) : topt=nil
3765
+ options ? copt=@@tone_options.select_existent(options) : copt=nil
3766
+ tone(gphys, newframe, topt)
3767
+ contour(gphys, false, copt)
3768
+ end
3769
+
3770
+ @@contour_levels = Misc::KeywordOptAutoHelp.new(
3771
+ ['log', nil, 'approximately log-scaled levels (by using DCLExt::quasi_log_levels)'],
3772
+ ['log_cycle', 3, '(if log) number of levels in one-order (1 or 2 or 3)'],
3773
+ ['levels', nil, 'contour levels (Array/NArray of Numeric)'],
3774
+ ['index', nil, '(if levels) line index(es) (Array/NArray of integers, Integer, or nil)'],
3775
+ ['line_type',nil, '(if levels) line type(s) (Array/NArray of integers, Integer, or nil)'],
3776
+ ['label', nil, '(if levels) contour label(s) (Array/NArray of String, String, true, false, nil). nil is recommended.'],
3777
+ ['label_height',nil,'(if levels) label height(s) (Array/NArray of Numeric, Numeric, or nil). nil is recommended.']
3778
+ )
3779
+ @@set_contour_levels=false
3780
+ def set_contour_levels(options)
3781
+ opts = @@contour_levels.interpret(options)
3782
+ _set_contour_levels_(opts)
3783
+ end
3784
+ def _set_contour_levels_(opts)
3785
+ raise ArgumentError, "'levels' must be explicitly set" if !opts['levels']
3786
+ DCLExt.ud_set_contour(opts['levels'],opts['index'],opts['line_type'],
3787
+ opts['label'],opts['label_height'])
3788
+ @@set_contour_levels=true
3789
+ nil
3790
+ end
3791
+
3792
+ def clear_contour_levels
3793
+ @@set_contour_levels=false
3794
+ DCL.udiclv # this may not be needed
3795
+ nil
3796
+ end
3797
+
3798
+ def set_contour(options)
3799
+ @@contour_options.set(options)
3800
+ end
3801
+
3802
+ @@next_contour = nil
3803
+ def next_contour(options)
3804
+ if options.is_a?(Hash)
3805
+ @@next_contour = options
3806
+ else
3807
+ raise TypeError,"Hash expected"
3808
+ end
3809
+ nil
3810
+ end
3811
+
3812
+ @@contour_options = Misc::KeywordOptAutoHelp.new(
3813
+ ['title', nil, 'Title of the figure(if nil, internally determined)'],
3814
+ ['annotate', true, 'if false, do not put texts on the right margin even when newframe==true'],
3815
+ ['transpose', false, 'if true, exchange x and y axes'],
3816
+ ['exchange', false, 'same as the option transpose'],
3817
+ ['map_axes', false, '[USE IT ONLY WHEN itr=10 (cylindrical)] If true, draws axes by temprarilly switching to itr=1 and calling GGraph::axes.'],
3818
+ ['keep', false, 'Use the contour levels used previously'],
3819
+ @@linear_contour_options,
3820
+ @@contour_levels
3821
+ )
3822
+
3823
+ def axes_or_map_and_ttl(gp, opts, xax, yax)
3824
+ ttl = (opts['title'] || gp.get_att('long_name'))
3825
+ if map_trn?
3826
+ map
3827
+ if opts['map_axes'] && itr_is?(10)
3828
+ vpt = DCL.sgqvpt
3829
+ wnd = DCL.sgqwnd
3830
+ if wnd.include?(DCL.glrget('rundef'))
3831
+ map_fit = false
3832
+ wnd = DCL.sgqtxy
3833
+ cnt = DCL.umqcnt
3834
+ else
3835
+ map_fit = true
3836
+ end
3837
+ vrat = ( (vpt[3]-vpt[2]) / (vpt[1]-vpt[0]) ).abs
3838
+ wrat = ( (wnd[3]-wnd[2]) / (wnd[1]-wnd[0]) ).abs
3839
+ if wrat < vrat
3840
+ vyoff = (vpt[3]+vpt[2])/2
3841
+ dvy2 = (vpt[1]-vpt[0])*wrat/2
3842
+ vpt[2] = vyoff - dvy2
3843
+ vpt[3] = vyoff + dvy2
3844
+ else
3845
+ vxoff = (vpt[1]+vpt[0])/2
3846
+ dvx2 = (vpt[3]-vpt[2])/wrat/2
3847
+ vpt[0] = vxoff - dvx2
3848
+ vpt[1] = vxoff + dvx2
3849
+ end
3850
+ trn = DCL.sgqtrn
3851
+ if map_fit
3852
+ fig(xax,yax, {'itr'=>1, 'new_frame'=>false, 'viewport'=>vpt})
3853
+ axes(xax, yax)
3854
+ title( ttl )
3855
+ DCL.sgstrn(trn)
3856
+ else
3857
+ xax_map = xax[0..1].copy
3858
+ xax_map[0] = cnt[0] + wnd[0]
3859
+ xax_map[1] = cnt[0] + wnd[1]
3860
+ yax_map = yax[0..1].copy
3861
+ yax_map[0] = wnd[2]
3862
+ yax_map[1] = wnd[3]
3863
+ fig(xax_map,yax_map,{'itr'=>1, 'new_frame'=>false, 'viewport'=>vpt})
3864
+ axes(xax_map,yax_map)
3865
+ title( ttl )
3866
+ fig(xax_map,yax_map,{'itr'=>trn, 'new_frame'=>false, 'viewport'=>vpt, 'map_fit'=>false, 'map_axis'=>cnt, 'map_window'=>wnd})
3867
+ end
3868
+ else
3869
+ title( ttl )
3870
+ end
3871
+ elsif itr_is?(5)
3872
+ polar_coordinate_boundaries(xax,yax)
3873
+ title( ttl )
3874
+ else
3875
+ axes(xax, yax)
3876
+ title( ttl )
3877
+ end
3878
+ annotate(gp.lost_axes) if opts['annotate']
3879
+ end
3880
+
3881
+ def contour(gphys, newframe=true, options=nil)
3882
+ gropn_1_if_not_yet
3883
+ if newframe!=true && newframe!=false
3884
+ raise ArgumentError, "2nd arg (newframe) must be true or false"
3885
+ end
3886
+ if @@next_contour
3887
+ options = ( options ? @@next_contour.update(options) : @@next_contour )
3888
+ @@next_contour = nil
3889
+ end
3890
+ if @@next_linear_contour_options
3891
+ options = ( options ? @@next_linear_contour_options.update(options) :
3892
+ @@next_linear_contour_options )
3893
+ @@next_linear_contour_options = nil
3894
+ end
3895
+ opts = @@contour_options.interpret(options)
3896
+ gp = gphys.first2D
3897
+ gp = gp.transpose(1,0) if opts['transpose'] || opts['exchange']
3898
+ xax = gp.coord(0)
3899
+ yax = gp.coord(1)
3900
+ if map_trn?(newframe)
3901
+ # /// convert to the anti-clockwise coordinate in case for map filling
3902
+ # (Because of a bug in UMFMAP in DCL 5.3) -->
3903
+ if ( (xax[-1].val-xax[0].val)*(yax[-1].val-yax[0].val) < 0 )
3904
+ gp = gp.copy[true,-1..0]
3905
+ yax = gp.coord(1)
3906
+ end
3907
+ # <-- ///
3908
+ gp = gp.cyclic_ext(0, 360.0) #cyclic extention with lon if appropriate
3909
+ xax = gp.coord(0)
3910
+ elsif itr_is?(5, newframe)
3911
+ gp = gp.cyclic_ext(1, 360.0) # cyclic extention along azimuth
3912
+ yax = gp.coord(1)
3913
+ end
3914
+ if newframe
3915
+ fig(xax, yax)
3916
+ end
3917
+ if newframe
3918
+ axes_or_map_and_ttl(gp,opts, xax, yax)
3919
+ end
3920
+ if !opts['keep'] or DCL.udqcln==0
3921
+ if !opts['levels'] && opts['log']
3922
+ levels, mjmn = DCLExt.quasi_log_levels_z(gp.data.val, opts['nlev'],
3923
+ opts['max'], opts['min'], opts['log_cycle'])
3924
+ opts['levels'] = levels
3925
+ opts['index'] = NArray.to_na(mjmn)*2 + 1 if !opts['index']
3926
+ opts['label'] = true if opts['label'].nil?
3927
+ end
3928
+ if (opts['levels'])
3929
+ backup = @@set_contour_levels
3930
+ _set_contour_levels_(opts)
3931
+ @@set_contour_levels = backup
3932
+ elsif !@@set_contour_levels
3933
+ DCLExt.ud_set_linear_levs(gp.data.val, opts)
3934
+ end
3935
+ end
3936
+ saved_udparams = nil
3937
+ if DCL.udqcln >= 3
3938
+ lv1, = DCL.udqclv(1)
3939
+ lv2, = DCL.udqclv(2)
3940
+ lv3, = DCL.udqclv(3)
3941
+ if lv2-lv1 != lv3-lv2
3942
+ saved_udparams = DCLExt.ud_set_params({'lmsg'=>false})
3943
+ end
3944
+ end
3945
+ DCL.uwsgxa(xax.val)
3946
+ DCL.uwsgya(yax.val)
3947
+ DCL.udcntz(gp.data.val)
3948
+ DCLExt.ud_set_params(saved_udparams) if saved_udparams
3949
+ nil
3950
+ end
3951
+
3952
+ @@linear_tone_options = Misc::KeywordOptAutoHelp.new(
3953
+ ['min', nil, 'minimum tone level'],
3954
+ ['max', nil, 'maximum tone level'],
3955
+ ['nlev', nil, 'number of levels'],
3956
+ ['interval', nil, 'contour interval']
3957
+ )
3958
+ def set_linear_tone_options(options)
3959
+ @@linear_tone_options.set(options)
3960
+ end
3961
+ @@next_linear_tone_options = nil
3962
+ def next_linear_tone_options(options)
3963
+ if options.is_a?(Hash)
3964
+ @@next_linear_tone_options = options
3965
+ else
3966
+ raise TypeError,"Hash expected"
3967
+ end
3968
+ nil
3969
+ end
3970
+
3971
+ @@tone_levels = Misc::KeywordOptAutoHelp.new(
3972
+ ['log', nil, 'approximately log-scaled levels (by using DCLExt::quasi_log_levels)'],
3973
+ ['log_cycle', 3, '(if log) number of levels in one-order (1 or 2 or 3)'],
3974
+ ['levels', nil, 'tone levels (Array/NArray of Numeric). Works together with patterns'],
3975
+ ['patterns', nil, 'tone patters (Array/NArray of Numeric). Works together with levels']
3976
+ )
3977
+ @@set_tone_levels=false
3978
+ def set_tone_levels(options)
3979
+ opts = @@tone_levels.interpret(options)
3980
+ _set_tone_levels_(opts)
3981
+ end
3982
+ def _set_tone_levels_(opts)
3983
+ if !opts['levels'] && !opts['patterns']
3984
+ end
3985
+ if opts['levels']
3986
+ levels = opts['levels']
3987
+ else
3988
+ raise ArgumentError,"'levels' must be explicitly set"
3989
+ end
3990
+ if opts['patterns']
3991
+ patterns = opts['patterns']
3992
+ else
3993
+ nlev = levels.length - 1
3994
+ itpat = DCL.ueiget('itpat')
3995
+ iclr1 = DCL.ueiget('icolor1')
3996
+ iclr2 = DCL.ueiget('icolor2')
3997
+ patterns = (0...nlev).collect{|i|
3998
+ (((iclr2-iclr1)/(nlev-1.0)*i+iclr1).round) * 1000 + itpat
3999
+ }
4000
+ end
4001
+ DCLExt.ue_set_tone(levels,patterns)
4002
+ @@set_tone_levels=true
4003
+ nil
4004
+ end
4005
+ def clear_tone_levels
4006
+ @@set_tone_levels=false
4007
+ nil
4008
+ end
4009
+
4010
+ def set_tone(options)
4011
+ @@tone_options.set(options)
4012
+ end
4013
+
4014
+ @@next_tone = nil
4015
+ def next_tone(options)
4016
+ if options.is_a?(Hash)
4017
+ @@next_tone = options
4018
+ else
4019
+ raise TypeError,"Hash expected"
4020
+ end
4021
+ nil
4022
+ end
4023
+
4024
+ @@tone_options = Misc::KeywordOptAutoHelp.new(
4025
+ ['title', nil, 'Title of the figure(if nil, internally determined)'],
4026
+ ['annotate', true, 'if false, do not put texts on the right margin even when newframe==true'],
4027
+ ['ltone', true, 'Same as udpack parameter ltone'],
4028
+ ['tonf', false, 'Use DCL.uetonf instead of DCL.uetone'],
4029
+ ['tonc', false, 'Use DCL.uetonc instead of DCL.uetone'],
4030
+ ['clr_min', nil, 'if an integer (in 10..99) is specified, used as the color number for the minimum data values. (the same can be done by setting the uepack parameter "icolor1")'],
4031
+ ['clr_max', nil, 'if an integer (in 10..99) is specified, used as the color number for the maximum data values. (the same can be done by setting the uepack parameter "icolor2")'],
4032
+ ['transpose', false, 'if true, exchange x and y axes'],
4033
+ ['exchange', false, 'same as the option transpose'],
4034
+ ['map_axes', false, '[USE IT ONLY WHEN itr=10 (cylindrical)] If true, draws axes by temprarilly switching to itr=1 and calling GGraph::axes.'],
4035
+ ['keep', false, 'Use the tone levels and patterns used previously'],
4036
+ @@linear_tone_options,
4037
+ @@tone_levels
4038
+ )
4039
+
4040
+ def tone(gphys, newframe=true, options=nil)
4041
+ gropn_1_if_not_yet
4042
+ if newframe!=true && newframe!=false
4043
+ raise ArgumentError, "2nd arg (newframe) must be true or false"
4044
+ end
4045
+ if @@next_tone
4046
+ options = ( options ? @@next_tone.update(options) : @@next_tone )
4047
+ @@next_tone = nil
4048
+ end
4049
+ if @@next_linear_tone_options
4050
+ options = ( options ? @@next_linear_tone_options.update(options) :
4051
+ @@next_linear_tone_options )
4052
+ @@next_linear_tone_options = nil
4053
+ end
4054
+ opts = @@tone_options.interpret(options)
4055
+
4056
+ if opts['clr_min']
4057
+ icolor1_bak = DCL.uepget('icolor1')
4058
+ DCL.uepset('icolor1', opts['clr_min'])
4059
+ end
4060
+ if opts['clr_max']
4061
+ icolor2_bak = DCL.uepget('icolor2')
4062
+ DCL.uepset('icolor2', opts['clr_max'])
4063
+ end
4064
+ gp = gphys.first2D
4065
+ gp = gp.transpose(1,0) if opts['transpose'] || opts['exchange']
4066
+ xax = gp.coord(0)
4067
+ yax = gp.coord(1)
4068
+ if map_trn?(newframe)
4069
+ # /// convert to the anti-clockwise coordinate in case for map filling
4070
+ # (Because of a bug in UMFMAP in DCL 5.3) -->
4071
+ if ( (xax[-1].val-xax[0].val)*(yax[-1].val-yax[0].val) < 0 )
4072
+ gp = gp.copy[true,-1..0]
4073
+ yax = gp.coord(1)
4074
+ end
4075
+ # <-- ///
4076
+ gp = gp.cyclic_ext(0, 360.0) #cyclic extention with lon if appropriate
4077
+ xax = gp.coord(0)
4078
+ elsif itr_is?(5, newframe) # polar coordinate
4079
+ gp = gp.cyclic_ext(1, 360.0) # cyclic extention along azimuth
4080
+ yax = gp.coord(1)
4081
+ end
4082
+ if newframe
4083
+ fig(xax, yax)
4084
+ end
4085
+ DCL.uwsgxa(xax.val)
4086
+ DCL.uwsgya(yax.val)
4087
+ if !opts['keep'] or DCL.ueqntl==0
4088
+ if !opts['levels'] && opts['log']
4089
+ levels, = DCLExt.quasi_log_levels_z(gp.data.val, opts['nlev'],
4090
+ opts['max'], opts['min'], opts['log_cycle'])
4091
+ rmiss = DCL.glrget('rmiss')
4092
+ levels.unshift(rmiss) if !opts['max'] && levels[0]<0
4093
+ levels.push(rmiss) if !opts['max'] && levels[-1]>0
4094
+ opts['levels'] = levels
4095
+ end
4096
+ if opts['levels']
4097
+ backup = @@set_tone_levels
4098
+ _set_tone_levels_(opts)
4099
+ @@set_tone_levels = backup
4100
+ elsif opts['patterns']
4101
+ raise "option 'patterns' is not effective unless 'levels' is specified"
4102
+ elsif !@@set_tone_levels && opts['ltone']
4103
+ DCL.ueitlv
4104
+ DCLExt.ue_set_linear_levs(gp.data.val, opts)
4105
+ else
4106
+ DCL.ueitlv if !@@set_tone_levels
4107
+ end
4108
+ end
4109
+
4110
+ if opts['tonf'] && opts['ltone']
4111
+ DCL.uetonf(gp.data.val)
4112
+ elsif opts['tonc'] && opts['ltone']
4113
+ DCL.uetonc(gp.data.val)
4114
+ else
4115
+ DCL.uetone(gp.data.val)
4116
+ end
4117
+
4118
+ if newframe
4119
+ axes_or_map_and_ttl(gp,opts, xax, yax)
4120
+ end
4121
+ DCL.uepset('icolor1', icolor1_bak) if opts['clr_min']
4122
+ DCL.uepset('icolor2', icolor2_bak) if opts['clr_max']
4123
+ nil
4124
+ end
4125
+
4126
+ # < vector >
4127
+
4128
+ def set_unit_vect_options(options)
4129
+ DCLExt.set_unit_vect_options(options)
4130
+ end
4131
+ def next_unit_vect_options(options)
4132
+ DCLExt.next_unit_vect_options(options)
4133
+ end
4134
+
4135
+ @@vxfxratio=nil
4136
+ @@vyfyratio=nil
4137
+
4138
+ def vector(fx, fy, newframe=true, options=nil)
4139
+ gropn_1_if_not_yet
4140
+ if newframe!=true && newframe!=false
4141
+ raise ArgumentError, "2nd arg (newframe) must be true or false"
4142
+ end
4143
+ if ! defined?(@@vector_options)
4144
+ @@vector_options = Misc::KeywordOptAutoHelp.new(
4145
+ ['title', nil, 'Title of the figure(if nil, internally determined)'],
4146
+ ['annotate', true, 'if false, do not put texts on the right margin even when newframe==true'],
4147
+ ['transpose', false, 'if true, exchange x and y axes'],
4148
+ ['exchange', false, 'same as the option transpose'],
4149
+ ['map_axes', false, '[USE IT ONLY WHEN itr=10 (cylindrical)] If true, draws axes by temprarilly switching to itr=1 and calling GGraph::axes.'],
4150
+ ['flow_vect', true, 'If true, use DCLExt::flow_vect to draw vectors; otherwise, DCL::ugvect is used.'],
4151
+ ['keep', false, 'Use the same vector scaling as in the previous call. -- Currently, works only when "flow_vect" is true'],
4152
+ ['xintv', 1, '(Effective only if flow_vect) interval of data sampling in x'],
4153
+ ['yintv', 1, '(Effective only if flow_vect) interval of data sampling in y'],
4154
+ ['factor', 1.0, '(Effective only if flow_vect) scaling factor to strech/reduce the arrow lengths'],
4155
+ ['unit_vect', false, 'Show the unit vector'],
4156
+ ['max_unit_vect', false, '(Effective only if flow_vect && unit_vect) If true, use the maximum arrows to scale the unit vector; otherwise, normalize in V coordinate.'],
4157
+ ['flow_itr5', false, 'If true, use DclExt::flow_itr5 to draw vectors on 2-dim polar coordinate. Should be set DCL.sgstrn(5)']
4158
+ )
4159
+ end
4160
+ opts = @@vector_options.interpret(options)
4161
+ fx = fx.first2D.copy
4162
+ fy = fy.first2D.copy
4163
+ fx = fx.transpose(1,0) if opts['transpose'] || opts['exchange']
4164
+ fy = fy.transpose(1,0) if opts['transpose'] || opts['exchange']
4165
+ sh = fx.shape
4166
+ if sh != fy.shape
4167
+ raise ArgumentError, "shapes of fx and fy do not agree with each other"
4168
+ end
4169
+ if ((xi=opts['xintv']) >= 2)
4170
+ idx = NArray.int((sh[0]/xi.to_f).ceil).indgen!*xi # [0,xi,2*xi,..]
4171
+ fx = fx[idx, true]
4172
+ fy = fy[idx, true]
4173
+ end
4174
+ if ((yi=opts['yintv']) >= 2)
4175
+ idx = NArray.int((sh[1]/yi.to_f).ceil).indgen!*yi # [0,yi,2*yi,..]
4176
+ fx = fx[true, idx]
4177
+ fy = fy[true, idx]
4178
+ end
4179
+ xax = fx.coord(0)
4180
+ yax = fy.coord(1)
4181
+ if map_trn?(newframe)
4182
+ # /// convert to the anti-clockwise coordinate in case for map filling
4183
+ # (Because of a bug in UMFMAP in DCL 5.3) -->
4184
+ if ( (xax[-1].val-xax[0].val)*(yax[-1].val-yax[0].val) < 0 )
4185
+ fx = fx.copy[true,-1..0]
4186
+ fy = fy.copy[true,-1..0]
4187
+ yax = fx.coord(1)
4188
+ end
4189
+ # <-- ///
4190
+ fx = fx.cyclic_ext(0, 360.0) #cyclic extention with lon if appropriate
4191
+ fy = fy.cyclic_ext(0, 360.0) #cyclic extention with lon if appropriate
4192
+ xax = fx.coord(0)
4193
+ elsif itr_is?(5, newframe)
4194
+ fx = fx.cyclic_ext(1, 360.0) #cyclic extention along azimuth
4195
+ fy = fy.cyclic_ext(1, 360.0) #cyclic extention along azimuth
4196
+ yax = fx.coord(1)
4197
+ end
4198
+ if newframe
4199
+ fig(xax, yax)
4200
+ end
4201
+ if newframe
4202
+ if opts['title']
4203
+ ttl = opts['title']
4204
+ else
4205
+ fxnm = fx.data.get_att('long_name') || fx.name
4206
+ fynm = fy.data.get_att('long_name') || fy.name
4207
+ ttl = '('+fxnm+','+fynm+')'
4208
+ end
4209
+ if map_trn?
4210
+ map
4211
+ if opts['map_axes'] && itr_is?(10)
4212
+ vpt = DCL.sgqvpt
4213
+ wnd = DCL.sgqwnd
4214
+ if wnd.include?(DCL.glrget('rundef'))
4215
+ map_fit = false
4216
+ wnd = DCL.sgqtxy
4217
+ cnt = DCL.umqcnt
4218
+ else
4219
+ map_fit = true
4220
+ end
4221
+ vrat = ( (vpt[3]-vpt[2]) / (vpt[1]-vpt[0]) ).abs
4222
+ wrat = ( (wnd[3]-wnd[2]) / (wnd[1]-wnd[0]) ).abs
4223
+ if wrat < vrat
4224
+ vyoff = (vpt[3]+vpt[2])/2
4225
+ dvy2 = (vpt[1]-vpt[0])*wrat/2
4226
+ vpt[2] = vyoff - dvy2
4227
+ vpt[3] = vyoff + dvy2
4228
+ else
4229
+ vxoff = (vpt[1]+vpt[0])/2
4230
+ dvx2 = (vpt[3]-vpt[2])/wrat/2
4231
+ vpt[0] = vxoff - dvx2
4232
+ vpt[1] = vxoff + dvx2
4233
+ end
4234
+ trn = DCL.sgqtrn
4235
+ if map_fit
4236
+ fig(xax,yax,{'itr'=>1, 'new_frame'=>false, 'viewport'=>vpt})
4237
+ axes(xax, yax)
4238
+ title( ttl )
4239
+ DCL.sgstrn(trn)
4240
+ else
4241
+ xax_map = xax[0..1].copy
4242
+ xax_map[0] = cnt[0] + wnd[0]
4243
+ xax_map[1] = cnt[0] + wnd[1]
4244
+ yax_map = yax[0..1].copy
4245
+ yax_map[0] = wnd[2]
4246
+ yax_map[1] = wnd[3]
4247
+ fig(xax_map,yax_map,{'itr'=>1, 'new_frame'=>false, 'viewport'=>vpt})
4248
+ axes(xax_map,yax_map)
4249
+ title( ttl )
4250
+ fig(xax_map,yax_map,{'itr'=>trn, 'new_frame'=>false, 'viewport'=>vpt, 'map_fit'=>false, 'map_axis'=>cnt, 'map_window'=>wnd})
4251
+ end
4252
+ else
4253
+ title( ttl )
4254
+ end
4255
+ elsif itr_is?(5)
4256
+ polar_coordinate_boundaries(xax,yax)
4257
+ title(ttl)
4258
+ else
4259
+ axes(xax, yax)
4260
+ title(ttl)
4261
+ end
4262
+ annotate(fx.lost_axes) if opts['annotate']
4263
+ end
4264
+ DCL.uwsgxa(xax.val)
4265
+ DCL.uwsgya(yax.val)
4266
+ if opts['flow_itr5']
4267
+ if itr_is?(5)
4268
+ DCLExt.flow_itr5( fx, fy, opts['factor'], opts['unit_vect'] )
4269
+ else
4270
+ raise "flow_itr5 option should use with itr=5."
4271
+ end
4272
+ elsif opts['flow_vect']
4273
+ uninfo = DCLExt.flow_vect(fx.val, fy.val, opts['factor'], 1, 1,
4274
+ (opts['keep']&& @@vxfxratio), (opts['keep'] && @@vyfyratio) )
4275
+ @@vxfxratio, @@vyfyratio, = uninfo
4276
+ if opts['unit_vect']
4277
+ if opts['max_unit_vect']
4278
+ DCLExt.unit_vect(*uninfo)
4279
+ else
4280
+ DCLExt.unit_vect(*uninfo[0..1])
4281
+ end
4282
+ end
4283
+ else
4284
+ before=DCLExt.ug_set_params({'lunit'=>true}) if opts['unit_vect']
4285
+ DCL.ugvect(fx.val, fy.val)
4286
+ DCLExt.ug_set_params(before) if opts['unit_vect']
4287
+ end
4288
+ nil
4289
+ end
4290
+
4291
+
4292
+ end
4293
+
4294
+ end
4295
+
4296
+ if $0 == __FILE__
4297
+ include NumRu
4298
+
4299
+ # < read command line option if any >
4300
+
4301
+ if ARGV.length == 1
4302
+ iws = ARGV[0].to_i
4303
+ else
4304
+ iws = 1
4305
+ end
4306
+
4307
+ #< graphic initialization >
4308
+
4309
+ DCL.gropn(iws)
4310
+ DCL.sldiv('y',2,2)
4311
+ DCL.sgpset('lcntl', false)
4312
+ DCL.sgpset('lfull',true)
4313
+ DCL.sgpset('lfprop',true)
4314
+ DCL.uzfact(0.9)
4315
+
4316
+ # < show default parameters >
4317
+ xdummy = ydummy = nil
4318
+ begin
4319
+ print "** GGraph::fig options **\n"
4320
+ GGraph.fig(xdummy, ydummy, 'help'=>true)
4321
+ rescue
4322
+ end
4323
+ begin
4324
+ print "** GGraph::axes options **\n"
4325
+ GGraph.axes(xdummy, ydummy, 'help'=>true)
4326
+ rescue
4327
+ end
4328
+ gp_dummy = nil
4329
+ begin
4330
+ print "** GGraph::line options **\n"
4331
+ GGraph.line(gp_dummy,true,'help'=>true)
4332
+ rescue
4333
+ end
4334
+ begin
4335
+ print "** GGraph::mark options **\n"
4336
+ GGraph.mark(gp_dummy,true,'help'=>true)
4337
+ rescue
4338
+ end
4339
+ begin
4340
+ print "** GGraph::contour options **\n"
4341
+ GGraph.contour(gp_dummy,true,'help'=>true)
4342
+ rescue
4343
+ end
4344
+ begin
4345
+ print "** GGraph::tone options **\n"
4346
+ GGraph.tone(gp_dummy,true,'help'=>true)
4347
+ rescue
4348
+ end
4349
+ begin
4350
+ print "** GGraph::map options **\n"
4351
+ GGraph.map('help'=>true)
4352
+ rescue
4353
+ end
4354
+
4355
+ #< graphic test / demonstration >
4356
+
4357
+ file = '../../testdata/T.jan.nc'
4358
+ gphys = GPhys::NetCDF_IO.open(file, 'T')
4359
+
4360
+ #/ graph 1 /
4361
+ GGraph.set_fig('viewport'=>[0.25,0.75,0.12,0.62])
4362
+ GGraph.line(gphys.cut(true,35,true).average(0), true)
4363
+ #/ graph 2 /
4364
+ GGraph.next_fig('itr'=>2)
4365
+ GGraph.next_axes('yunits'=>'','xunits'=>'')
4366
+ GGraph.line(gphys.cut(true,35,true).average(0), true,
4367
+ 'exchange'=>true, 'index'=>3, 'title'=>'TEMPERATURE', 'annotate'=>false, 'min'=>-100, 'max'=>20)
4368
+ GGraph.mark(gphys.cut(true,35,true).average(0), false,
4369
+ 'exchange'=>true, 'type'=>3)
4370
+ #/ graph 3 /
4371
+ GGraph.set_fig('window'=>[nil, 0.1, -70, 20])
4372
+ GGraph.mark(gphys.cut(true,35,true).average(0))
4373
+ #/ graph 4 /
4374
+ GGraph.next_fig('window'=>[nil, nil, -80, 30])
4375
+ GGraph.mark(gphys.cut(true,35,true).average(0), true, 'max'=>25)
4376
+ GGraph.line(gphys.cut(true,35,true).average(0), false)
4377
+ GGraph.set_fig('window'=>nil)
4378
+ #/ graph 5 /
4379
+ GGraph.contour(gphys)
4380
+ #/ graph 6 /
4381
+ GGraph.next_fig('itr'=>2)
4382
+ GGraph.contour(gphys.cut(135,true,true))
4383
+ #/ graph 7 /
4384
+ GGraph.set_axes('xunits'=>'', 'yunits'=>'')
4385
+ GGraph.contour(gphys,true, 'min'=>0, 'coloring'=>true)
4386
+ #/ graph 8 /
4387
+ GGraph.set_fig('viewport'=>[0.2,0.8,0.15,0.55])
4388
+ GGraph.contour(gphys,true, 'nozero'=>true)
4389
+ #/ graph 9 /
4390
+ GGraph.contour(gphys,true, 'min'=>10, 'int'=>3)
4391
+ DCL.udpset('lmsg',false)
4392
+ GGraph.contour(gphys,false, 'max'=>-10, 'int'=>3)
4393
+ DCL.udpset('lmsg',true)
4394
+ #/ graph 10 /
4395
+ GGraph.set_contour_levels('levels'=>[-10,-5,0,5,10],'index'=>[3,1],
4396
+ 'line_type'=>2)
4397
+ GGraph.contour(gphys)
4398
+ GGraph.clear_contour_levels
4399
+ #/ graph 11 /
4400
+ GGraph.contour(gphys, true, 'levels'=>[0,10,20], 'index'=>3)
4401
+ #/ graph 12 /
4402
+ GGraph.set_linear_contour_options('nlev'=>24)
4403
+ GGraph.next_linear_contour_options('coloring'=>true)
4404
+ GGraph.contour(gphys)
4405
+ #/ graph 13 /
4406
+ GGraph.tone(gphys, true, 'min'=>0)
4407
+ sv = DCLExt.ud_set_params('indxmj'=>1,'indxmn'=>1)
4408
+ GGraph.contour(gphys, false)
4409
+ DCLExt.ud_set_params(sv)
4410
+ GGraph.color_bar
4411
+ #/ graph 14 /
4412
+ GGraph.tone(gphys, true, 'ltone'=>false)
4413
+ GGraph.contour(gphys, false)
4414
+ #/ graph 15 /
4415
+ GGraph.next_fig('itr'=>3)
4416
+ GGraph.contour(gphys[1..-1,true,true])
4417
+ #/ graph 16 /
4418
+ GGraph.tone(gphys, true, 'levels'=>[-20,-10,0,10,20],'patterns'=>[12999,30999,45999,65999,75999,85999])
4419
+ GGraph.color_bar('vlength'=>0.25,'landscape'=>true)
4420
+ #/ graph 17 /
4421
+ GGraph.tone(gphys, true, 'levels'=>[-20,-10,0,10,20],'patterns'=>[30999,45999,65999,75999,85999])
4422
+ DCLExt.color_bar('vlength'=>0.25, 'left'=>true)
4423
+ #/ graph 18 /
4424
+ GGraph.tone(gphys, true, 'levels'=>[-20,-10,0,10,20],'patterns'=>[30999,45999,65999,75999])
4425
+ #DCLExt.color_bar('vlength'=>0.25, 'left'=>true)
4426
+ DCLExt.color_bar('vlength'=>0.25, 'levels'=>[-20,-10,0,10,20],'patterns'=>[30999,45999,65999,75999])
4427
+ #/ graph 19 /
4428
+ GGraph.set_fig('viewport'=>[0.3,0.7,0.1,0.6])
4429
+ GGraph.contour(gphys,true, 'min'=>0, 'coloring'=>true, 'transpose'=>true)
4430
+ GGraph.tone(gphys, false, 'levels'=>[10,20], 'patterns'=>[80999], 'transpose'=>true)
4431
+ #/ graph 20 /
4432
+ GGraph.set_fig('viewport'=>[0.25,0.75,0.15,0.6])
4433
+ GGraph.vector(gphys+10,gphys+10,true,
4434
+ {'unit_vect'=>true, 'xintv'=>2, 'yintv'=>2})
4435
+ #/ graph 21 /
4436
+ GGraph.next_unit_vect_options({'inplace'=>false,'vxuloc'=>0.17,'vyuloc'=>0.07})
4437
+ GGraph.vector(gphys+10,gphys-10,true,
4438
+ {'unit_vect'=>true, 'max_unit_vect'=>true, 'xintv'=>2, 'yintv'=>2})
4439
+ #/ graph 22 /
4440
+ GGraph.vector(gphys+10,gphys+10,true,
4441
+ {'unit_vect'=>true, 'flow_vect'=>false, 'xintv'=>2, 'yintv'=>2})
4442
+
4443
+ #GGraph.color_bar('help'=>true)
4444
+ #/ graph 23 /
4445
+ GGraph.set_fig('viewport'=>[0.2,0.8,0.15,0.55])
4446
+ GGraph.tone(gphys, true, 'levels'=>[-16,-4,-1,0,1,4,16],'patterns'=>[12999,21999,30999,45999,65999,75999,85999,95999])
4447
+ GGraph.color_bar('constwidth'=>true,'vlength'=>0.6,'landscape'=>true,'labelintv'=>1)
4448
+ GGraph.color_bar('constwidth'=>true,'vlength'=>0.35,'index'=>1)
4449
+
4450
+ #/ graph 24 /
4451
+
4452
+ GGraph.set_map('coast_world'=>true)
4453
+
4454
+ # -- mercator --
4455
+ GGraph.next_fig('itr'=>11)
4456
+ GGraph.next_map('fill'=>true)
4457
+ GGraph.tone(gphys, true)
4458
+ GGraph.color_bar
4459
+
4460
+ #/ graph 25 /
4461
+
4462
+ # -- orthographic --
4463
+ GGraph.set_fig('viewport'=>[0.25,0.75,0.1,0.6])
4464
+ GGraph.next_fig('itr'=>30,'map_axis'=>[135,60,0],'map_radius'=>60)
4465
+ GGraph.tone(gphys, true)
4466
+ sv = DCLExt.ud_set_params('indxmj'=>991,'indxmn'=>991)
4467
+ GGraph.contour(gphys, false)
4468
+ DCLExt.ud_set_params(sv)
4469
+ GGraph.color_bar('landscape'=>true) # ,'vlength'=>0.6
4470
+
4471
+ #/ graph 26 /
4472
+
4473
+ # -- polar stero --
4474
+ GGraph.next_fig('itr'=>31)
4475
+ DCL.sgpset('lclip',true)
4476
+ GGraph.next_map('vpt_boundary'=>3,'dgridmj'=>20,'dgridmn'=>10)
4477
+ GGraph.tone(gphys, true)
4478
+ GGraph.color_bar
4479
+
4480
+ #/ graph 27 /
4481
+ # axes for itr=10 (lon-lat projection) -- map_fit=T, map_axes=F (default)
4482
+ GGraph.next_fig('itr'=>10)
4483
+ GGraph.contour(gphys,true,'title'=>'map_fit=T, map_axes=F (default)')
4484
+
4485
+ #/ graph 28 /
4486
+ # axes for itr=10 (lon-lat projection) -- map_fit=T, map_axes=T
4487
+ GGraph.next_fig('itr'=>10)
4488
+ GGraph.contour(gphys, true,'map_axes'=>true,'title'=>'map_fit=T map_axes=T')
4489
+ DCL::sgtxzr(0.5,0.64,'Try GPHYSDIR/sample/ggraph_mapfit-axes_dr002687.rb',0.022,0,0.0,22)
4490
+ DCL::sgtxzr(0.5,0.6,'for more examples',0.022,0,0.0,22)
4491
+
4492
+ #/ graph 29 /
4493
+ # [xy]xmaplabel options for itr=10 -- when it is off (default)
4494
+ GGraph.next_fig('itr'=>10)
4495
+ GGraph.tone(gphys, true,'map_axes'=>true,'title'=>'default axes')
4496
+
4497
+ #/ graph 30 /
4498
+ # [xy]xmaplabel options for itr=10 -- label as 90E, 90W, 30N, 30S etc
4499
+ # sample 1
4500
+ GGraph.next_fig('itr'=>10)
4501
+ GGraph.next_axes('xmaplabel'=>'lon','ymaplabel'=>'lat')
4502
+ GGraph.tone(gphys, true,'map_axes'=>true,'title'=>'lon/lat axes')
4503
+ DCL::sgtxzr(0.5,0.64,'Try GPHYSDIR/sample/ggraph_latlon_labelling_dr002690.rb',0.022,0,0.0,22)
4504
+ DCL::sgtxzr(0.5,0.6,'for more options',0.022,0,0.0,22)
4505
+
4506
+ #/ graph 31 /
4507
+ # log-level tone/contour (1)
4508
+ GGraph.set_fig('itr'=>1,'viewport'=>[0.2,0.85,0.22,0.58])
4509
+ GGraph.tone(gphys,true,'log'=>true, 'nlev'=>5, 'log_cycle'=>3 )
4510
+ GGraph.contour(gphys,false,'log'=>true, 'nlev'=>5, 'log_cycle'=>3)
4511
+ GGraph.color_bar('log'=>true, 'landscape'=>true, 'vlength'=>0.35)
4512
+ DCL::sgtxzr(0.5,0.68,"With 'log' option",0.022,0,0.0,22)
4513
+
4514
+ #/ graph 32 /
4515
+ # log-level tone/contour (2)
4516
+ GGraph.set_fig('itr'=>1,'viewport'=>[0.2,0.85,0.22,0.58])
4517
+ GGraph.tone(gphys,true,'log'=>true, 'nlev'=>5, 'min'=>0.03, 'log_cycle'=>2 )
4518
+ GGraph.contour(gphys,false,'log'=>true, 'nlev'=>5, 'min'=>0.05, 'log_cycle'=>3)
4519
+ GGraph.color_bar('log'=>true, 'vlength'=>0.25)
4520
+ DCL::sgtxzr(0.5,0.68,"With 'log' option",0.022,0,0.0,22)
4521
+
4522
+
4523
+ #/ graph 33/
4524
+ # vector field on the polar coordinate (1)
4525
+ # -- demo for flow_itr5 option of GGraph.vector
4526
+
4527
+ #### create longitude, latitude, radial axes #####
4528
+
4529
+ vrad = VArray.new( NArray.float(11).indgen! * 0.06 + 0.4 ).rename("rad")
4530
+ vlat = VArray.new( NArray.float(21).indgen! * 9 - 90 ).rename("lat")
4531
+ vlon = VArray.new( NArray.float(41).indgen! * 9 ).rename("lon")
4532
+ radax = Axis.new().set_pos(vrad)
4533
+ latax = Axis.new().set_pos(vlat)
4534
+ lonax = Axis.new().set_pos(vlon)
4535
+ grid_meridional = Grid.new(radax, latax)
4536
+ grid_equator = Grid.new(radax, lonax)
4537
+
4538
+ #### create vector field in the meridional plane #####
4539
+
4540
+ frad = vrad - 0.7
4541
+ frad = frad.reshape!(vrad.length,1)
4542
+ flat = (3*vlat/180*Math::PI).cos
4543
+ flat = flat.reshape!(1,vlat.length)
4544
+ vellat = frad*flat
4545
+ vellat.rename!('vellat')
4546
+ gp_vellat = GPhys.new(grid_meridional, vellat)
4547
+
4548
+ frad = (vrad-0.4)*(vrad-1)
4549
+ frad = frad.reshape!(vrad.length,1)
4550
+ flat = (3*vlat/180*Math::PI).sin
4551
+ flat = flat.reshape!(1,vlat.length)
4552
+ velrad = frad*flat
4553
+ velrad.rename!('velrad')
4554
+ gp_velrad = GPhys.new(grid_meridional, velrad)
4555
+
4556
+ #### draw vector field in the meridional plane #####
4557
+
4558
+ # DCL.gropn(1)
4559
+ # GGraph.set_fig('viewport'=>[0.25,0.75,0.12,0.62])
4560
+ GGraph.next_fig('itr'=>5)
4561
+ GGraph.vector(gp_velrad, gp_vellat, true,
4562
+ 'flow_itr5'=>true,'factor'=>1e-1)
4563
+
4564
+ GGraph.next_fig('itr'=>5)
4565
+ GGraph.tone(gp_velrad,true)
4566
+ GGraph.vector(gp_velrad, gp_vellat, false,
4567
+ 'flow_itr5'=>true,'factor'=>1e-1)
4568
+
4569
+ #/ graph 34/
4570
+ # vector field on the polar coordinate (2)
4571
+ # -- demo for flow_itr5 option of GGraph.vector
4572
+
4573
+ #### create vector field in the equatorial plane #####
4574
+
4575
+ frad = vrad - 0.7
4576
+ frad = frad.reshape!(vrad.length,1)
4577
+ flon = (3*vlon/180*Math::PI).cos
4578
+ flon = flon.reshape!(1,vlon.length)
4579
+ vellon = frad*flon
4580
+ vellon.rename!('vellon')
4581
+ gp_vellon = GPhys.new(grid_equator, vellon)
4582
+
4583
+ frad = (vrad-0.4)*(vrad-1)
4584
+ frad = frad.reshape!(vrad.length,1)
4585
+ flon = (3*vlon/180*Math::PI).sin
4586
+ flon = flon.reshape!(1,vlon.length)
4587
+ velrad = frad*flon
4588
+ velrad.rename!('velrad')
4589
+ gp_velrad = GPhys.new(grid_equator, velrad)
4590
+
4591
+ #### draw vector field in the equatorial plane #####
4592
+
4593
+ GGraph.next_fig('itr'=>5)
4594
+ GGraph.vector(gp_velrad, gp_vellon, true,
4595
+ 'flow_itr5'=>true,'factor'=>1e-1)
4596
+
4597
+ GGraph.next_fig('itr'=>5)
4598
+ GGraph.tone(gp_velrad,true)
4599
+ GGraph.vector(gp_velrad, gp_vellon, false,
4600
+ 'flow_itr5'=>true,'factor'=>1e-1)
4601
+
4602
+ DCL.grcls
4603
+
4604
+ end