bio 1.0.0 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (340) hide show
  1. data/bin/bioruby +14 -122
  2. data/bin/br_biofetch.rb +2 -2
  3. data/bin/br_bioflat.rb +2 -2
  4. data/bin/br_biogetseq.rb +2 -2
  5. data/bin/br_pmfetch.rb +3 -3
  6. data/doc/Changes-0.7.rd +77 -0
  7. data/doc/KEGG_API.rd +523 -232
  8. data/doc/KEGG_API.rd.ja +529 -207
  9. data/doc/Tutorial.rd +48 -11
  10. data/lib/bio.rb +59 -6
  11. data/lib/bio/alignment.rb +713 -103
  12. data/lib/bio/appl/bl2seq/report.rb +2 -18
  13. data/lib/bio/appl/blast.rb +108 -91
  14. data/lib/bio/appl/blast/format0.rb +33 -18
  15. data/lib/bio/appl/blast/format8.rb +6 -20
  16. data/lib/bio/appl/blast/report.rb +293 -429
  17. data/lib/bio/appl/blast/rexml.rb +8 -22
  18. data/lib/bio/appl/blast/wublast.rb +21 -12
  19. data/lib/bio/appl/blast/xmlparser.rb +180 -183
  20. data/lib/bio/appl/blat/report.rb +127 -30
  21. data/lib/bio/appl/clustalw.rb +87 -59
  22. data/lib/bio/appl/clustalw/report.rb +20 -22
  23. data/lib/bio/appl/emboss.rb +113 -20
  24. data/lib/bio/appl/fasta.rb +173 -198
  25. data/lib/bio/appl/fasta/format10.rb +244 -347
  26. data/lib/bio/appl/gcg/msf.rb +212 -0
  27. data/lib/bio/appl/gcg/seq.rb +195 -0
  28. data/lib/bio/appl/genscan/report.rb +5 -23
  29. data/lib/bio/appl/hmmer.rb +8 -45
  30. data/lib/bio/appl/hmmer/report.rb +2 -20
  31. data/lib/bio/appl/iprscan/report.rb +374 -0
  32. data/lib/bio/appl/mafft.rb +87 -50
  33. data/lib/bio/appl/mafft/report.rb +151 -44
  34. data/lib/bio/appl/muscle.rb +52 -0
  35. data/lib/bio/appl/phylip/alignment.rb +129 -0
  36. data/lib/bio/appl/phylip/distance_matrix.rb +96 -0
  37. data/lib/bio/appl/probcons.rb +41 -0
  38. data/lib/bio/appl/psort.rb +89 -96
  39. data/lib/bio/appl/psort/report.rb +6 -22
  40. data/lib/bio/appl/pts1.rb +263 -0
  41. data/lib/bio/appl/sim4.rb +26 -36
  42. data/lib/bio/appl/sim4/report.rb +2 -18
  43. data/lib/bio/appl/sosui/report.rb +5 -20
  44. data/lib/bio/appl/spidey/report.rb +2 -2
  45. data/lib/bio/appl/targetp/report.rb +4 -20
  46. data/lib/bio/appl/tcoffee.rb +55 -0
  47. data/lib/bio/appl/tmhmm/report.rb +4 -20
  48. data/lib/bio/command.rb +235 -64
  49. data/lib/bio/data/aa.rb +21 -26
  50. data/lib/bio/data/codontable.rb +2 -20
  51. data/lib/bio/data/na.rb +19 -4
  52. data/lib/bio/db.rb +27 -12
  53. data/lib/bio/db/aaindex.rb +2 -20
  54. data/lib/bio/db/embl/common.rb +4 -21
  55. data/lib/bio/db/embl/embl.rb +33 -85
  56. data/lib/bio/db/embl/sptr.rb +612 -302
  57. data/lib/bio/db/embl/swissprot.rb +10 -29
  58. data/lib/bio/db/embl/trembl.rb +10 -29
  59. data/lib/bio/db/embl/uniprot.rb +10 -29
  60. data/lib/bio/db/fantom.rb +15 -20
  61. data/lib/bio/db/fasta.rb +3 -3
  62. data/lib/bio/db/genbank/common.rb +37 -46
  63. data/lib/bio/db/genbank/ddbj.rb +6 -18
  64. data/lib/bio/db/genbank/genbank.rb +47 -186
  65. data/lib/bio/db/genbank/genpept.rb +4 -17
  66. data/lib/bio/db/genbank/refseq.rb +4 -17
  67. data/lib/bio/db/gff.rb +103 -35
  68. data/lib/bio/db/go.rb +4 -20
  69. data/lib/bio/db/kegg/brite.rb +26 -36
  70. data/lib/bio/db/kegg/compound.rb +81 -85
  71. data/lib/bio/db/kegg/drug.rb +98 -0
  72. data/lib/bio/db/kegg/enzyme.rb +133 -110
  73. data/lib/bio/db/kegg/expression.rb +2 -20
  74. data/lib/bio/db/kegg/genes.rb +208 -238
  75. data/lib/bio/db/kegg/genome.rb +164 -285
  76. data/lib/bio/db/kegg/glycan.rb +114 -157
  77. data/lib/bio/db/kegg/keggtab.rb +242 -303
  78. data/lib/bio/db/kegg/kgml.rb +117 -160
  79. data/lib/bio/db/kegg/orthology.rb +112 -0
  80. data/lib/bio/db/kegg/reaction.rb +54 -69
  81. data/lib/bio/db/kegg/taxonomy.rb +331 -0
  82. data/lib/bio/db/lasergene.rb +209 -0
  83. data/lib/bio/db/litdb.rb +3 -27
  84. data/lib/bio/db/medline.rb +228 -249
  85. data/lib/bio/db/nbrf.rb +3 -3
  86. data/lib/bio/db/newick.rb +510 -0
  87. data/lib/bio/db/nexus.rb +1854 -0
  88. data/lib/bio/db/pdb.rb +5 -17
  89. data/lib/bio/db/pdb/atom.rb +2 -18
  90. data/lib/bio/db/pdb/chain.rb +2 -18
  91. data/lib/bio/db/pdb/chemicalcomponent.rb +2 -18
  92. data/lib/bio/db/pdb/model.rb +2 -18
  93. data/lib/bio/db/pdb/pdb.rb +73 -34
  94. data/lib/bio/db/pdb/residue.rb +4 -20
  95. data/lib/bio/db/pdb/utils.rb +2 -18
  96. data/lib/bio/db/prosite.rb +403 -422
  97. data/lib/bio/db/rebase.rb +84 -40
  98. data/lib/bio/db/soft.rb +404 -0
  99. data/lib/bio/db/transfac.rb +5 -17
  100. data/lib/bio/feature.rb +106 -52
  101. data/lib/bio/io/das.rb +32 -42
  102. data/lib/bio/io/dbget.rb +2 -20
  103. data/lib/bio/io/ddbjxml.rb +77 -138
  104. data/lib/bio/io/ebisoap.rb +158 -0
  105. data/lib/bio/io/ensembl.rb +229 -0
  106. data/lib/bio/io/fastacmd.rb +89 -82
  107. data/lib/bio/io/fetch.rb +163 -96
  108. data/lib/bio/io/flatfile.rb +170 -73
  109. data/lib/bio/io/flatfile/bdb.rb +3 -16
  110. data/lib/bio/io/flatfile/index.rb +2 -2
  111. data/lib/bio/io/flatfile/indexer.rb +3 -2
  112. data/lib/bio/io/higet.rb +12 -31
  113. data/lib/bio/io/keggapi.rb +210 -269
  114. data/lib/bio/io/ncbisoap.rb +155 -0
  115. data/lib/bio/io/pubmed.rb +169 -147
  116. data/lib/bio/io/registry.rb +4 -20
  117. data/lib/bio/io/soapwsdl.rb +43 -38
  118. data/lib/bio/io/sql.rb +242 -305
  119. data/lib/bio/location.rb +407 -285
  120. data/lib/bio/map.rb +410 -0
  121. data/lib/bio/pathway.rb +558 -695
  122. data/lib/bio/reference.rb +272 -75
  123. data/lib/bio/sequence.rb +255 -13
  124. data/lib/bio/sequence/aa.rb +71 -10
  125. data/lib/bio/sequence/common.rb +187 -33
  126. data/lib/bio/sequence/compat.rb +59 -4
  127. data/lib/bio/sequence/format.rb +54 -7
  128. data/lib/bio/sequence/generic.rb +3 -3
  129. data/lib/bio/sequence/na.rb +328 -26
  130. data/lib/bio/shell.rb +11 -4
  131. data/lib/bio/shell/core.rb +221 -160
  132. data/lib/bio/shell/demo.rb +18 -15
  133. data/lib/bio/shell/interface.rb +14 -12
  134. data/lib/bio/shell/irb.rb +95 -0
  135. data/lib/bio/shell/object.rb +45 -26
  136. data/lib/bio/shell/plugin/blast.rb +42 -0
  137. data/lib/bio/shell/plugin/codon.rb +22 -14
  138. data/lib/bio/shell/plugin/das.rb +58 -0
  139. data/lib/bio/shell/plugin/emboss.rb +2 -2
  140. data/lib/bio/shell/plugin/entry.rb +22 -11
  141. data/lib/bio/shell/plugin/flatfile.rb +2 -2
  142. data/lib/bio/shell/plugin/keggapi.rb +13 -6
  143. data/lib/bio/shell/plugin/midi.rb +4 -4
  144. data/lib/bio/shell/plugin/obda.rb +2 -2
  145. data/lib/bio/shell/plugin/psort.rb +56 -0
  146. data/lib/bio/shell/plugin/seq.rb +35 -8
  147. data/lib/bio/shell/plugin/soap.rb +87 -0
  148. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/bioruby_generator.rb +29 -0
  149. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/_classes.rhtml +4 -0
  150. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/_log.rhtml +27 -0
  151. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/_methods.rhtml +11 -0
  152. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/_modules.rhtml +4 -0
  153. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/_variables.rhtml +7 -0
  154. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/bioruby-bg.gif +0 -0
  155. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/bioruby-console.png +0 -0
  156. data/lib/bio/shell/rails/{public/images/icon.png → vendor/plugins/generators/bioruby/templates/bioruby-gem.png} +0 -0
  157. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/bioruby-link.gif +0 -0
  158. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/bioruby.css +369 -0
  159. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/bioruby.rhtml +47 -0
  160. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/bioruby_controller.rb +144 -0
  161. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/bioruby_helper.rb +47 -0
  162. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/commands.rhtml +8 -0
  163. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/history.rhtml +10 -0
  164. data/lib/bio/shell/rails/vendor/plugins/generators/bioruby/templates/index.rhtml +22 -0
  165. data/lib/bio/shell/script.rb +25 -0
  166. data/lib/bio/shell/setup.rb +109 -0
  167. data/lib/bio/shell/web.rb +70 -58
  168. data/lib/bio/tree.rb +850 -0
  169. data/lib/bio/util/color_scheme.rb +84 -107
  170. data/lib/bio/util/color_scheme/buried.rb +5 -24
  171. data/lib/bio/util/color_scheme/helix.rb +5 -24
  172. data/lib/bio/util/color_scheme/hydropathy.rb +5 -24
  173. data/lib/bio/util/color_scheme/nucleotide.rb +5 -24
  174. data/lib/bio/util/color_scheme/strand.rb +5 -24
  175. data/lib/bio/util/color_scheme/taylor.rb +5 -24
  176. data/lib/bio/util/color_scheme/turn.rb +5 -24
  177. data/lib/bio/util/color_scheme/zappo.rb +5 -24
  178. data/lib/bio/util/contingency_table.rb +70 -43
  179. data/lib/bio/util/restriction_enzyme.rb +228 -0
  180. data/lib/bio/util/restriction_enzyme/analysis.rb +249 -0
  181. data/lib/bio/util/restriction_enzyme/analysis_basic.rb +217 -0
  182. data/lib/bio/util/restriction_enzyme/cut_symbol.rb +107 -0
  183. data/lib/bio/util/restriction_enzyme/double_stranded.rb +321 -0
  184. data/lib/bio/util/restriction_enzyme/double_stranded/aligned_strands.rb +130 -0
  185. data/lib/bio/util/restriction_enzyme/double_stranded/cut_location_pair.rb +103 -0
  186. data/lib/bio/util/restriction_enzyme/double_stranded/cut_location_pair_in_enzyme_notation.rb +38 -0
  187. data/lib/bio/util/restriction_enzyme/double_stranded/cut_locations.rb +76 -0
  188. data/lib/bio/util/restriction_enzyme/double_stranded/cut_locations_in_enzyme_notation.rb +107 -0
  189. data/lib/bio/util/restriction_enzyme/enzymes.yaml +7061 -0
  190. data/lib/bio/util/restriction_enzyme/range/cut_range.rb +24 -0
  191. data/lib/bio/util/restriction_enzyme/range/cut_ranges.rb +47 -0
  192. data/lib/bio/util/restriction_enzyme/range/horizontal_cut_range.rb +67 -0
  193. data/lib/bio/util/restriction_enzyme/range/sequence_range.rb +257 -0
  194. data/lib/bio/util/restriction_enzyme/range/sequence_range/calculated_cuts.rb +242 -0
  195. data/lib/bio/util/restriction_enzyme/range/sequence_range/fragment.rb +51 -0
  196. data/lib/bio/util/restriction_enzyme/range/sequence_range/fragments.rb +41 -0
  197. data/lib/bio/util/restriction_enzyme/range/vertical_cut_range.rb +77 -0
  198. data/lib/bio/util/restriction_enzyme/single_strand.rb +199 -0
  199. data/lib/bio/util/restriction_enzyme/single_strand/cut_locations_in_enzyme_notation.rb +135 -0
  200. data/lib/bio/util/restriction_enzyme/single_strand_complement.rb +23 -0
  201. data/lib/bio/util/restriction_enzyme/string_formatting.rb +111 -0
  202. data/lib/bio/util/sirna.rb +4 -22
  203. data/sample/color_scheme_na.rb +4 -12
  204. data/sample/enzymes.rb +78 -0
  205. data/sample/goslim.rb +5 -13
  206. data/sample/psortplot_html.rb +4 -12
  207. data/test/data/blast/2.2.15.blastp.m7 +876 -0
  208. data/test/data/embl/AB090716.embl.rel89 +63 -0
  209. data/test/data/fasta/example1.txt +75 -0
  210. data/test/data/fasta/example2.txt +21 -0
  211. data/test/data/iprscan/merged.raw +32 -0
  212. data/test/data/iprscan/merged.txt +74 -0
  213. data/test/data/soft/GDS100_partial.soft +92 -0
  214. data/test/data/soft/GSE3457_family_partial.soft +874 -0
  215. data/test/functional/bio/io/test_ensembl.rb +103 -0
  216. data/test/functional/bio/io/test_soapwsdl.rb +5 -17
  217. data/test/unit/bio/appl/bl2seq/test_report.rb +2 -2
  218. data/test/unit/bio/appl/blast/test_report.rb +3 -16
  219. data/test/unit/bio/appl/blast/test_xmlparser.rb +4 -16
  220. data/test/unit/bio/appl/genscan/test_report.rb +3 -16
  221. data/test/unit/bio/appl/hmmer/test_report.rb +3 -16
  222. data/test/unit/bio/appl/iprscan/test_report.rb +338 -0
  223. data/test/unit/bio/appl/mafft/test_report.rb +63 -0
  224. data/test/unit/bio/appl/sosui/test_report.rb +3 -16
  225. data/test/unit/bio/appl/targetp/test_report.rb +3 -16
  226. data/test/unit/bio/appl/test_blast.rb +3 -16
  227. data/test/unit/bio/appl/test_fasta.rb +4 -16
  228. data/test/unit/bio/appl/test_pts1.rb +140 -0
  229. data/test/unit/bio/appl/tmhmm/test_report.rb +3 -16
  230. data/test/unit/bio/data/test_aa.rb +4 -17
  231. data/test/unit/bio/data/test_codontable.rb +3 -16
  232. data/test/unit/bio/data/test_na.rb +3 -3
  233. data/test/unit/bio/db/embl/test_common.rb +3 -16
  234. data/test/unit/bio/db/embl/test_embl.rb +3 -16
  235. data/test/unit/bio/db/embl/test_embl_rel89.rb +219 -0
  236. data/test/unit/bio/db/embl/test_sptr.rb +1548 -41
  237. data/test/unit/bio/db/embl/test_uniprot.rb +3 -16
  238. data/test/unit/bio/db/kegg/test_genes.rb +3 -16
  239. data/test/unit/bio/db/pdb/test_pdb.rb +7 -24
  240. data/test/unit/bio/db/test_aaindex.rb +2 -2
  241. data/test/unit/bio/db/test_fasta.rb +3 -16
  242. data/test/unit/bio/db/test_gff.rb +3 -16
  243. data/test/unit/bio/db/test_lasergene.rb +95 -0
  244. data/test/unit/bio/db/test_newick.rb +56 -0
  245. data/test/unit/bio/db/test_nexus.rb +360 -0
  246. data/test/unit/bio/db/test_prosite.rb +5 -18
  247. data/test/unit/bio/db/test_rebase.rb +11 -25
  248. data/test/unit/bio/db/test_soft.rb +138 -0
  249. data/test/unit/bio/io/test_ddbjxml.rb +5 -17
  250. data/test/unit/bio/io/test_ensembl.rb +109 -0
  251. data/test/unit/bio/io/test_fastacmd.rb +3 -16
  252. data/test/unit/bio/io/test_flatfile.rb +237 -0
  253. data/test/unit/bio/io/test_soapwsdl.rb +4 -17
  254. data/test/unit/bio/sequence/test_aa.rb +3 -3
  255. data/test/unit/bio/sequence/test_common.rb +3 -16
  256. data/test/unit/bio/sequence/test_compat.rb +3 -16
  257. data/test/unit/bio/sequence/test_na.rb +29 -3
  258. data/test/unit/bio/shell/plugin/test_seq.rb +8 -8
  259. data/test/unit/bio/test_alignment.rb +16 -27
  260. data/test/unit/bio/test_command.rb +242 -25
  261. data/test/unit/bio/test_db.rb +3 -16
  262. data/test/unit/bio/test_feature.rb +4 -16
  263. data/test/unit/bio/test_location.rb +4 -16
  264. data/test/unit/bio/test_map.rb +230 -0
  265. data/test/unit/bio/test_pathway.rb +4 -16
  266. data/test/unit/bio/test_reference.rb +2 -2
  267. data/test/unit/bio/test_sequence.rb +7 -19
  268. data/test/unit/bio/test_shell.rb +3 -16
  269. data/test/unit/bio/test_tree.rb +593 -0
  270. data/test/unit/bio/util/restriction_enzyme/analysis/test_calculated_cuts.rb +299 -0
  271. data/test/unit/bio/util/restriction_enzyme/analysis/test_cut_ranges.rb +103 -0
  272. data/test/unit/bio/util/restriction_enzyme/analysis/test_sequence_range.rb +240 -0
  273. data/test/unit/bio/util/restriction_enzyme/double_stranded/test_aligned_strands.rb +100 -0
  274. data/test/unit/bio/util/restriction_enzyme/double_stranded/test_cut_location_pair.rb +75 -0
  275. data/test/unit/bio/util/restriction_enzyme/double_stranded/test_cut_location_pair_in_enzyme_notation.rb +73 -0
  276. data/test/unit/bio/util/restriction_enzyme/double_stranded/test_cut_locations.rb +53 -0
  277. data/test/unit/bio/util/restriction_enzyme/double_stranded/test_cut_locations_in_enzyme_notation.rb +104 -0
  278. data/test/unit/bio/util/restriction_enzyme/single_strand/test_cut_locations_in_enzyme_notation.rb +83 -0
  279. data/test/unit/bio/util/restriction_enzyme/test_analysis.rb +246 -0
  280. data/test/unit/bio/util/restriction_enzyme/test_cut_symbol.rb +44 -0
  281. data/test/unit/bio/util/restriction_enzyme/test_double_stranded.rb +115 -0
  282. data/test/unit/bio/util/restriction_enzyme/test_single_strand.rb +147 -0
  283. data/test/unit/bio/util/restriction_enzyme/test_single_strand_complement.rb +147 -0
  284. data/test/unit/bio/util/restriction_enzyme/test_string_formatting.rb +60 -0
  285. data/test/unit/bio/util/test_color_scheme.rb +6 -18
  286. data/test/unit/bio/util/test_contingency_table.rb +6 -18
  287. data/test/unit/bio/util/test_restriction_enzyme.rb +42 -0
  288. data/test/unit/bio/util/test_sirna.rb +3 -16
  289. metadata +228 -169
  290. data/doc/BioRuby.rd.ja +0 -225
  291. data/doc/Design.rd.ja +0 -341
  292. data/doc/TODO.rd.ja +0 -138
  293. data/lib/bio/appl/fasta/format6.rb +0 -37
  294. data/lib/bio/db/kegg/cell.rb +0 -88
  295. data/lib/bio/db/kegg/ko.rb +0 -178
  296. data/lib/bio/shell/rails/Rakefile +0 -10
  297. data/lib/bio/shell/rails/app/controllers/application.rb +0 -4
  298. data/lib/bio/shell/rails/app/controllers/shell_controller.rb +0 -94
  299. data/lib/bio/shell/rails/app/helpers/application_helper.rb +0 -3
  300. data/lib/bio/shell/rails/app/models/shell_connection.rb +0 -30
  301. data/lib/bio/shell/rails/app/views/layouts/shell.rhtml +0 -37
  302. data/lib/bio/shell/rails/app/views/shell/history.rhtml +0 -5
  303. data/lib/bio/shell/rails/app/views/shell/index.rhtml +0 -2
  304. data/lib/bio/shell/rails/app/views/shell/show.rhtml +0 -13
  305. data/lib/bio/shell/rails/config/boot.rb +0 -19
  306. data/lib/bio/shell/rails/config/database.yml +0 -85
  307. data/lib/bio/shell/rails/config/environment.rb +0 -53
  308. data/lib/bio/shell/rails/config/environments/development.rb +0 -19
  309. data/lib/bio/shell/rails/config/environments/production.rb +0 -19
  310. data/lib/bio/shell/rails/config/environments/test.rb +0 -19
  311. data/lib/bio/shell/rails/config/routes.rb +0 -19
  312. data/lib/bio/shell/rails/doc/README_FOR_APP +0 -2
  313. data/lib/bio/shell/rails/public/404.html +0 -8
  314. data/lib/bio/shell/rails/public/500.html +0 -8
  315. data/lib/bio/shell/rails/public/dispatch.cgi +0 -10
  316. data/lib/bio/shell/rails/public/dispatch.fcgi +0 -24
  317. data/lib/bio/shell/rails/public/dispatch.rb +0 -10
  318. data/lib/bio/shell/rails/public/favicon.ico +0 -0
  319. data/lib/bio/shell/rails/public/images/rails.png +0 -0
  320. data/lib/bio/shell/rails/public/index.html +0 -277
  321. data/lib/bio/shell/rails/public/javascripts/controls.js +0 -750
  322. data/lib/bio/shell/rails/public/javascripts/dragdrop.js +0 -584
  323. data/lib/bio/shell/rails/public/javascripts/effects.js +0 -854
  324. data/lib/bio/shell/rails/public/javascripts/prototype.js +0 -1785
  325. data/lib/bio/shell/rails/public/robots.txt +0 -1
  326. data/lib/bio/shell/rails/public/stylesheets/main.css +0 -187
  327. data/lib/bio/shell/rails/script/about +0 -3
  328. data/lib/bio/shell/rails/script/breakpointer +0 -3
  329. data/lib/bio/shell/rails/script/console +0 -3
  330. data/lib/bio/shell/rails/script/destroy +0 -3
  331. data/lib/bio/shell/rails/script/generate +0 -3
  332. data/lib/bio/shell/rails/script/performance/benchmarker +0 -3
  333. data/lib/bio/shell/rails/script/performance/profiler +0 -3
  334. data/lib/bio/shell/rails/script/plugin +0 -3
  335. data/lib/bio/shell/rails/script/process/reaper +0 -3
  336. data/lib/bio/shell/rails/script/process/spawner +0 -3
  337. data/lib/bio/shell/rails/script/process/spinner +0 -3
  338. data/lib/bio/shell/rails/script/runner +0 -3
  339. data/lib/bio/shell/rails/script/server +0 -42
  340. data/lib/bio/shell/rails/test/test_helper.rb +0 -28
@@ -0,0 +1,850 @@
1
+ #
2
+ # = bio/tree.rb - phylogenetic tree data structure class
3
+ #
4
+ # Copyright:: Copyright (C) 2006
5
+ # Naohisa Goto <ng@bioruby.org>
6
+ # License:: The Ruby License
7
+ #
8
+ # $Id: tree.rb,v 1.8 2007/04/05 23:35:39 trevor Exp $
9
+ #
10
+
11
+ require 'matrix'
12
+ require 'bio/pathway'
13
+
14
+ module Bio
15
+
16
+ # This is the class for phylogenetic tree.
17
+ # It stores a phylogenetic tree.
18
+ #
19
+ # Internally, it is based on Bio::Pathway class.
20
+ # However, users cannot handle Bio::Pathway object directly.
21
+ #
22
+ # This is alpha version. Incompatible changes may be made frequently.
23
+ class Tree
24
+
25
+ # Error when there are no path between specified nodes
26
+ class NoPathError < RuntimeError; end
27
+
28
+ # Edge object of each node.
29
+ # By default, the object doesn't contain any node information.
30
+ class Edge
31
+
32
+ # creates a new edge.
33
+ def initialize(distance = nil)
34
+ if distance.kind_of?(Numeric)
35
+ self.distance = distance
36
+ elsif distance
37
+ self.distance_string = distance
38
+ end
39
+ end
40
+
41
+ # evolutionary distance
42
+ attr_reader :distance
43
+
44
+ # evolutionary distance represented as a string
45
+ attr_reader :distance_string
46
+
47
+ # set evolutionary distance value
48
+ def distance=(num)
49
+ @distance = num
50
+ @distance_string = (num ? num.to_s : num)
51
+ end
52
+
53
+ # set evolutionary distance value from a string
54
+ def distance_string=(str)
55
+ if str.to_s.strip.empty?
56
+ @distance = nil
57
+ @distance_string = str
58
+ else
59
+ @distance = str.to_f
60
+ @distance_string = str
61
+ end
62
+ end
63
+
64
+ # visualization of this object
65
+ def inspect
66
+ "<Edge distance=#{@distance.inspect}>"
67
+ end
68
+
69
+ # string representation of this object
70
+ def to_s
71
+ @distance_string.to_s
72
+ end
73
+
74
+ #---
75
+ # methods for NHX (New Hampshire eXtended) and/or PhyloXML
76
+ #+++
77
+
78
+ # log likelihood value (:L in NHX)
79
+ attr_accessor :log_likelihood
80
+
81
+ # width of the edge
82
+ # (<branch width="w"> of PhyloXML, or :W="w" in NHX)
83
+ attr_accessor :width
84
+
85
+ # Other NHX parameters. Returns a Hash.
86
+ # Note that :L and :W
87
+ # are not stored here but stored in the proper attributes in this class.
88
+ # However, if you force to set these parameters in this hash,
89
+ # the parameters in this hash are preferred when generating NHX.
90
+ # In addition, If the same parameters are defined at Node object,
91
+ # the parameters in the node are preferred.
92
+ def nhx_parameters
93
+ @nhx_parameters ||= {}
94
+ @nhx_parameters
95
+ end
96
+
97
+ end #class Edge
98
+
99
+ # Gets distance value from the given edge.
100
+ # Returns float or any other numeric value or nil.
101
+ def get_edge_distance(edge)
102
+ begin
103
+ dist = edge.distance
104
+ rescue NoMethodError
105
+ dist = edge
106
+ end
107
+ dist
108
+ end
109
+
110
+ # Gets distance string from the given edge.
111
+ # Returns a string or nil.
112
+ def get_edge_distance_string(edge)
113
+ begin
114
+ dist = edge.distance_string
115
+ rescue NoMethodError
116
+ dist = (edge ? edge.to_s : nil)
117
+ end
118
+ dist
119
+ end
120
+
121
+ # Returns edge1 + edge2
122
+ def get_edge_merged(edge1, edge2)
123
+ dist1 = get_edge_distance(edge1)
124
+ dist2 = get_edge_distance(edge2)
125
+ if dist1 and dist2 then
126
+ Edge.new(dist1 + dist2)
127
+ elsif dist1 then
128
+ Edge.new(dist1)
129
+ elsif dist2 then
130
+ Edge.new(dist2)
131
+ else
132
+ Edge.new
133
+ end
134
+ end
135
+
136
+ # Node object.
137
+ class Node
138
+
139
+ # Creates a new node.
140
+ def initialize(name = nil)
141
+ @name = name if name
142
+ end
143
+
144
+ # name of the node
145
+ attr_accessor :name
146
+
147
+ # bootstrap value
148
+ attr_reader :bootstrap
149
+
150
+ # bootstrap value as a string
151
+ attr_reader :bootstrap_string
152
+
153
+ # sets a bootstrap value
154
+ def bootstrap=(num)
155
+ @bootstrap_string = (num ? num.to_s : num)
156
+ @bootstrap = num
157
+ end
158
+
159
+ # sets a bootstrap value from a string
160
+ def bootstrap_string=(str)
161
+ if str.to_s.strip.empty?
162
+ @bootstrap = nil
163
+ @bootstrap_string = str
164
+ else
165
+ i = str.to_i
166
+ f = str.to_f
167
+ @bootstrap = (i == f ? i : f)
168
+ @bootstrap_string = str
169
+ end
170
+ end
171
+
172
+ # visualization of this object
173
+ def inspect
174
+ if @name and !@name.empty? then
175
+ str = "(Node:#{@name.inspect}"
176
+ else
177
+ str = sprintf('(Node:%x', (self.__id__ << 1) & 0xffffffff)
178
+ end
179
+ str += " bootstrap=#{@bootstrap.inspect}" if @bootstrap
180
+ str += ")"
181
+ str
182
+ end
183
+
184
+ # string representation of this object
185
+ def to_s
186
+ @name.to_s
187
+ end
188
+
189
+ # the order of the node
190
+ # (lower value, high priority)
191
+ attr_accessor :order_number
192
+
193
+ #---
194
+ # methods for NHX (New Hampshire eXtended) and/or PhyloXML
195
+ #+++
196
+
197
+ # Phylogenetic events.
198
+ # Returns an Array of one (or more?) of the following symbols
199
+ # :gene_duplication
200
+ # :speciation
201
+ def events
202
+ @events ||= []
203
+ @events
204
+ end
205
+
206
+ # EC number (EC_number in PhyloXML, or :E in NHX)
207
+ attr_accessor :ec_number
208
+
209
+ # scientific name (scientific_name in PhyloXML, or :S in NHX)
210
+ attr_accessor :scientific_name
211
+
212
+ # taxonomy identifier (taxonomy_identifier in PhyloXML, or :T in NHX)
213
+ attr_accessor :taxonomy_id
214
+
215
+ # Other NHX parameters. Returns a Hash.
216
+ # Note that :D, :E, :S, and :T
217
+ # are not stored here but stored in the proper attributes in this class.
218
+ # However, if you force to set these parameters in this hash,
219
+ # the parameters in this hash are preferred when generating NHX.
220
+ def nhx_parameters
221
+ @nhx_parameters ||= {}
222
+ @nhx_parameters
223
+ end
224
+
225
+ end #class Node
226
+
227
+ # Gets node name
228
+ def get_node_name(node)
229
+ begin
230
+ node.name
231
+ rescue NoMethodError
232
+ node.to_s
233
+ end
234
+ end
235
+
236
+ def get_node_bootstrap(node)
237
+ begin
238
+ node.bootstrap
239
+ rescue NoMethodError
240
+ nil
241
+ end
242
+ end
243
+
244
+ def get_node_bootstrap_string(node)
245
+ begin
246
+ node.bootstrap_string
247
+ rescue NoMethodError
248
+ nil
249
+ end
250
+ end
251
+
252
+ # Creates a new phylogenetic tree.
253
+ # When no arguments are given, it creates a new empty tree.
254
+ # When a Tree object is given, it copies the tree.
255
+ # Note that the new tree shares Node and Edge objects
256
+ # with the given tree.
257
+ def initialize(tree = nil)
258
+ # creates an undirected adjacency list graph
259
+ @pathway = Bio::Pathway.new([], true)
260
+ @root = nil
261
+ @options = {}
262
+ self.concat(tree) if tree
263
+ end
264
+
265
+ # root node of this tree
266
+ # (even if unrooted tree, it is used by some methods)
267
+ attr_accessor :root
268
+
269
+ # tree options; mainly used for tree output
270
+ attr_accessor :options
271
+
272
+ # Clears all nodes and edges.
273
+ # Returns self.
274
+ # Note that options and root are also cleared.
275
+ def clear
276
+ initialize
277
+ self
278
+ end
279
+
280
+ # Returns all nodes as an array.
281
+ def nodes
282
+ @pathway.graph.keys
283
+ end
284
+
285
+ # Number of nodes.
286
+ def number_of_nodes
287
+ @pathway.nodes
288
+ end
289
+
290
+ # Iterates over each node of this tree.
291
+ def each_node(&x) #:yields: node
292
+ @pathway.graph.each_key(&x)
293
+ self
294
+ end
295
+
296
+ # Iterates over each edges of this tree.
297
+ def each_edge #:yields: source, target, edge
298
+ @pathway.relations.each do |rel|
299
+ yield rel.node[0], rel.node[1], rel.relation
300
+ end
301
+ self
302
+ end
303
+
304
+ # Returns all edges an array of [ node0, node1, edge ]
305
+ def edges
306
+ @pathway.relations.collect do |rel|
307
+ [ rel.node[0], rel.node[1], rel.relation ]
308
+ end
309
+ end
310
+
311
+ # Returns number of edges in the tree.
312
+ def number_of_edges
313
+ @pathway.relations.size
314
+ end
315
+
316
+ # Returns an array of adjacent nodes of the given node.
317
+ def adjacent_nodes(node)
318
+ h = @pathway.graph[node]
319
+ h ? h.keys : []
320
+ end
321
+
322
+ # Returns all connected edges with adjacent nodes.
323
+ # Returns an array of the array [ source, target, edge ].
324
+ #
325
+ # The reason why the method name is "out_edges" is that
326
+ # it comes from the Boost Graph Library.
327
+ def out_edges(source)
328
+ h = @pathway.graph[source]
329
+ if h
330
+ h.collect { |key, val| [ source, key, val ] }
331
+ else
332
+ []
333
+ end
334
+ end
335
+
336
+ # Iterates over each connected edges of the given node.
337
+ # Returns self.
338
+ #
339
+ # The reason why the method name is "each_out_edge" is that
340
+ # it comes from the Boost Graph Library.
341
+ def each_out_edge(source) #:yields: source, target, edge
342
+ h = @pathway.graph[source]
343
+ h.each { |key, val| yield source, key, val } if h
344
+ self
345
+ end
346
+
347
+ # Returns number of edges in the given node.
348
+ #
349
+ # The reason why the method name is "out_degree" is that
350
+ # it comes from the Boost Graph Library.
351
+ def out_degree(source)
352
+ h = @pathway.graph[source]
353
+ h ? h.size : 0
354
+ end
355
+
356
+ # Returns an edge from source to target.
357
+ # If source and target are not adjacent nodes, returns nil.
358
+ def get_edge(source, target)
359
+ h = @pathway.graph[source]
360
+ h ? h[target] : nil
361
+ end
362
+
363
+ # Adds a new edge to the tree.
364
+ # Returns the newly added edge.
365
+ # If the edge already exists, it is overwritten with new one.
366
+ def add_edge(source, target, edge = Edge.new)
367
+ @pathway.append(Bio::Relation.new(source, target, edge))
368
+ edge
369
+ end
370
+
371
+ # Finds a node in the tree by given name and returns the node.
372
+ # If the node does not found, returns nil.
373
+ # If multiple nodes with the same name exist,
374
+ # the result would be one of those (unspecified).
375
+ def get_node_by_name(str)
376
+ self.each_node do |node|
377
+ if get_node_name(node) == str
378
+ return node
379
+ end
380
+ end
381
+ nil
382
+ end
383
+
384
+ # Adds a node to the tree.
385
+ # Returns self.
386
+ # If the node already exists, it does nothing.
387
+ def add_node(node)
388
+ @pathway.graph[node] ||= {}
389
+ self
390
+ end
391
+
392
+ # If the node exists, returns true.
393
+ # Otherwise, returns false.
394
+ def include?(node)
395
+ @pathway.graph[node] ? true : false
396
+ end
397
+
398
+ # Removes all edges connected with the node.
399
+ # Returns self.
400
+ # If the node does not exist, raises IndexError.
401
+ def clear_node(node)
402
+ unless self.include?(node)
403
+ raise IndexError, 'the node does not exist'
404
+ end
405
+ @pathway.relations.delete_if do |rel|
406
+ rel.node.include?(node)
407
+ end
408
+ @pathway.graph[node].each_key do |k|
409
+ @pathway.graph[k].delete(node)
410
+ end
411
+ @pathway.graph[node].clear
412
+ self
413
+ end
414
+
415
+ # Removes the given node from the tree.
416
+ # All edges connected with the node are also removed.
417
+ # Returns self.
418
+ # If the node does not exist, raises IndexError.
419
+ def remove_node(node)
420
+ self.clear_node(node)
421
+ @pathway.graph.delete(node)
422
+ self
423
+ end
424
+
425
+ # Removes each node if the block returns not nil.
426
+ # All edges connected with the removed nodes are also removed.
427
+ # Returns self.
428
+ def remove_node_if
429
+ all = self.nodes
430
+ all.each do |node|
431
+ if yield node then
432
+ self.clear_node(node)
433
+ @pathway.graph.delete(node)
434
+ end
435
+ end
436
+ self
437
+ end
438
+
439
+ # Removes an edge between source and target.
440
+ # Returns self.
441
+ # If the edge does not exist, raises IndexError.
442
+ #---
443
+ # If two or more edges exists between source and target,
444
+ # all of them are removed.
445
+ #+++
446
+ def remove_edge(source, target)
447
+ unless self.get_edge(source, target) then
448
+ raise IndexError, 'edge not found'
449
+ end
450
+ fwd = [ source, target ]
451
+ rev = [ target, source ]
452
+ @pathway.relations.delete_if do |rel|
453
+ rel.node == fwd or rel.node == rev
454
+ end
455
+ h = @pathway.graph[source]
456
+ h.delete(target) if h
457
+ h = @pathway.graph[target]
458
+ h.delete(source) if h
459
+ self
460
+ end
461
+
462
+ # Removes each edge if the block returns not nil.
463
+ # Returns self.
464
+ def remove_edge_if #:yields: source, target, edge
465
+ removed_rel = []
466
+ @pathway.relations.delete_if do |rel|
467
+ if yield rel.node[0], rel.node[1], edge then
468
+ removed_rel << rel
469
+ true
470
+ end
471
+ end
472
+ removed_rel.each do |rel|
473
+ source = rel[0]
474
+ target = rel[1]
475
+ h = @pathway.graph[source]
476
+ h.delete(target) if h
477
+ h = @pathway.graph[target]
478
+ h.delete(source) if h
479
+ end
480
+ self
481
+ end
482
+
483
+ # Replaces each node by each block's return value.
484
+ # Returns self.
485
+ def collect_node! #:yields: node
486
+ tr = {}
487
+ self.each_node do |node|
488
+ tr[node] = yield node
489
+ end
490
+ # replaces nodes in @pathway.relations
491
+ @pathway.relations.each do |rel|
492
+ rel.node.collect! { |node| tr[node] }
493
+ end
494
+ # re-generates @pathway from relations
495
+ @pathway.to_list
496
+ # adds orphan nodes
497
+ tr.each_value do |newnode|
498
+ @pathway.graph[newnode] ||= {}
499
+ end
500
+ self
501
+ end
502
+
503
+ # Replaces each edge by each block's return value.
504
+ # Returns self.
505
+ def collect_edge! #:yields: source, target, edge
506
+ @pathway.relations.each do |rel|
507
+ newedge = yield rel.node[0], rel.node[1], rel.relation
508
+ rel.relation = newedge
509
+ @pathway.append(rel, false)
510
+ end
511
+ self
512
+ end
513
+
514
+ # Gets the sub-tree consisted of given nodes.
515
+ # _nodes_ must be an array of nodes.
516
+ # Nodes that do not exist in the original tree are ignored.
517
+ # Returns a Tree object.
518
+ # Note that the sub-tree shares Node and Edge objects
519
+ # with the original tree.
520
+ def subtree(nodes)
521
+ nodes = nodes.find_all do |x|
522
+ @pathway.graph[x]
523
+ end
524
+ return self.class.new if nodes.empty?
525
+ # creates subtree
526
+ new_tree = self.class.new
527
+ nodes.each do |x|
528
+ new_tree.add_node(x)
529
+ end
530
+ self.each_edge do |node1, node2, edge|
531
+ if new_tree.include?(node1) and new_tree.include?(node2) then
532
+ new_tree.add_edge(node1, node2, edge)
533
+ end
534
+ end
535
+ return new_tree
536
+ end
537
+
538
+ # Gets the sub-tree consisted of given nodes and
539
+ # all internal nodes connected between given nodes.
540
+ # _nodes_ must be an array of nodes.
541
+ # Nodes that do not exist in the original tree are ignored.
542
+ # Returns a Tree object.
543
+ # The result is unspecified for cyclic trees.
544
+ # Note that the sub-tree shares Node and Edge objects
545
+ # with the original tree.
546
+ def subtree_with_all_paths(nodes)
547
+ hash = {}
548
+ nodes.each { |x| hash[x] = true }
549
+ nodes.each_index do |i|
550
+ node1 = nodes[i]
551
+ (0...i).each do |j|
552
+ node2 = nodes[j]
553
+ unless node1 == node2 then
554
+ begin
555
+ path = self.path(node1, node2)
556
+ rescue IndexError, NoPathError
557
+ path = []
558
+ end
559
+ path.each { |x| hash[x] = true }
560
+ end
561
+ end
562
+ end
563
+ self.subtree(hash.keys)
564
+ end
565
+
566
+ # Concatenates the other tree.
567
+ # If the same edge exists, the edge in _other_ is used.
568
+ # Returns self.
569
+ # The result is unspecified if _other_ isn't a Tree object.
570
+ # Note that the Node and Edge objects in the _other_ tree are
571
+ # shared in the concatinated tree.
572
+ def concat(other)
573
+ #raise TypeError unless other.kind_of?(self.class)
574
+ other.each_node do |node|
575
+ self.add_node(node)
576
+ end
577
+ other.each_edge do |node1, node2, edge|
578
+ self.add_edge(node1, node2, edge)
579
+ end
580
+ self
581
+ end
582
+
583
+ # Gets path from node1 to node2.
584
+ # Retruns an array of nodes, including node1 and node2.
585
+ # If node1 and/or node2 do not exist, IndexError is raised.
586
+ # If node1 and node2 are not connected, NoPathError is raised.
587
+ # The result is unspecified for cyclic trees.
588
+ def path(node1, node2)
589
+ raise IndexError, 'node1 not found' unless @pathway.graph[node1]
590
+ raise IndexError, 'node2 not found' unless @pathway.graph[node2]
591
+ return [ node1 ] if node1 == node2
592
+ step, path = @pathway.bfs_shortest_path(node1, node2)
593
+ unless path[0] == node1 and path[-1] == node2 then
594
+ raise NoPathError, 'node1 and node2 are not connected'
595
+ end
596
+ path
597
+ end
598
+
599
+ # Iterates over each edge from node1 to node2.
600
+ # The result is unspecified for cyclic trees.
601
+ def each_edge_in_path(node1, node2)
602
+ path = self.path(node1, node2)
603
+ source = path.shift
604
+ path.each do |target|
605
+ edge = self.get_edge(source, target)
606
+ yield source, target, edge
607
+ source = target
608
+ end
609
+ self
610
+ end
611
+
612
+ # Returns distance between node1 and node2.
613
+ # It would raise error if the edges didn't contain distance values.
614
+ # The result is unspecified for cyclic trees.
615
+ def distance(node1, node2)
616
+ distance = 0
617
+ self.each_edge_in_path(node1, node2) do |source, target, edge|
618
+ distance += get_edge_distance(edge)
619
+ end
620
+ distance
621
+ end
622
+
623
+ # Gets the parent node of the _node_.
624
+ # If _root_ isn't specified or _root_ is <code>nil</code>, @root is used.
625
+ # Returns an <code>Node</code> object or nil.
626
+ # The result is unspecified for cyclic trees.
627
+ def parent(node, root = nil)
628
+ root ||= @root
629
+ self.path(root, node)[-2]
630
+ end
631
+
632
+ # Gets the adjacent children nodes of the _node_.
633
+ # If _root_ isn't specified or _root_ is <code>nil</code>, @root is used.
634
+ # Returns an array of <code>Node</code>s.
635
+ # The result is unspecified for cyclic trees.
636
+ def children(node, root = nil)
637
+ root ||= @root
638
+ path = self.path(root, node)
639
+ result = self.adjacent_nodes(node)
640
+ result -= path
641
+ result
642
+ end
643
+
644
+ # Gets all descendent nodes of the _node_.
645
+ # If _root_ isn't specified or _root_ is <code>nil</code>, @root is used.
646
+ # Returns an array of <code>Node</code>s.
647
+ # The result is unspecified for cyclic trees.
648
+ def descendents(node, root = nil)
649
+ root ||= @root
650
+ distance, route = @pathway.breadth_first_search(root)
651
+ d = distance[node]
652
+ result = []
653
+ distance.each do |key, val|
654
+ if val > d then
655
+ x = key
656
+ while x = route[x]
657
+ if x == node then
658
+ result << key
659
+ break
660
+ end
661
+ break if distance[x] <= d
662
+ end
663
+ end
664
+ end
665
+ result
666
+ end
667
+
668
+ # If _node_ is nil, returns an array of
669
+ # all leaves (nodes connected with one edge).
670
+ # Otherwise, gets all descendent leaf nodes of the _node_.
671
+ # If _root_ isn't specified or _root_ is <code>nil</code>, @root is used.
672
+ # Returns an array of <code>Node</code>s.
673
+ # The result is unspecified for cyclic trees.
674
+ def leaves(node = nil, root = nil)
675
+ unless node then
676
+ nodes = []
677
+ self.each_node do |x|
678
+ nodes << x if self.out_degree(x) == 1
679
+ end
680
+ return nodes
681
+ else
682
+ root ||= @root
683
+ self.descendents(node, root).find_all do |x|
684
+ self.adjacent_nodes(x).size == 1
685
+ end
686
+ end
687
+ end
688
+
689
+ # Gets all ancestral nodes of the _node_.
690
+ # If _root_ isn't specified or _root_ is <code>nil</code>, @root is used.
691
+ # Returns an array of <code>Node</code>s.
692
+ # The result is unspecified for cyclic trees.
693
+ def ancestors(node, root = nil)
694
+ root ||= @root
695
+ (self.path(root, node) - [ node ]).reverse
696
+ end
697
+
698
+ # Gets the lowest common ancestor of the two nodes.
699
+ # If _root_ isn't specified or _root_ is <code>nil</code>, @root is used.
700
+ # Returns a <code>Node</code> object or nil.
701
+ # The result is unspecified for cyclic trees.
702
+ def lowest_common_ancestor(node1, node2, root = nil)
703
+ root ||= @root
704
+ distance, route = @pathway.breadth_first_search(root)
705
+ x = node1; r1 = []
706
+ begin; r1 << x; end while x = route[x]
707
+ x = node2; r2 = []
708
+ begin; r2 << x; end while x = route[x]
709
+ return (r1 & r2).first
710
+ end
711
+
712
+ # Returns total distance of all edges.
713
+ # It would raise error if some edges didn't contain distance values.
714
+ def total_distance
715
+ distance = 0
716
+ self.each_edge do |source, target, edge|
717
+ distance += get_edge_distance(edge)
718
+ end
719
+ distance
720
+ end
721
+
722
+ # Calculates distance matrix of given nodes.
723
+ # If _nodes_ is nil, or is ommited, it acts the same as
724
+ # tree.distance_matrix(tree.leaves).
725
+ # Returns a matrix object.
726
+ # The result is unspecified for cyclic trees.
727
+ # Note 1: The diagonal values of the matrix are 0.
728
+ # Note 2: If the distance cannot be calculated, nil will be set.
729
+ def distance_matrix(nodes = nil)
730
+ nodes ||= self.leaves
731
+ matrix = []
732
+ nodes.each_index do |i|
733
+ row = []
734
+ nodes.each_index do |j|
735
+ if i == j then
736
+ distance = 0
737
+ elsif r = matrix[j] and val = r[i] then
738
+ distance = val
739
+ else
740
+ distance = (self.distance(nodes[i], nodes[j]) rescue nil)
741
+ end
742
+ row << distance
743
+ end
744
+ matrix << row
745
+ end
746
+ Matrix.rows(matrix, false)
747
+ end
748
+
749
+ # Shows the adjacency matrix representation of the tree.
750
+ # It shows matrix only for given nodes.
751
+ # If _nodes_ is nil or is ommitted,
752
+ # it acts the same as tree.adjacency_matrix(tree.nodes).
753
+ # If a block is given, for each edge,
754
+ # it yields _source_, _target_, and _edge_, and
755
+ # uses the returned value of the block.
756
+ # Without blocks, it uses edge.
757
+ # Returns a matrix object.
758
+ def adjacency_matrix(nodes = nil,
759
+ default_value = nil,
760
+ diagonal_value = nil) #:yields: source, target, edge
761
+ nodes ||= self.nodes
762
+ size = nodes.size
763
+ hash = {}
764
+ nodes.each_with_index { |x, i| hash[x] = i }
765
+ # prepares an matrix
766
+ matrix = Array.new(size, nil)
767
+ matrix.collect! { |x| Array.new(size, default_value) }
768
+ (0...size).each { |i| matrix[i][i] = diagonal_value }
769
+ # fills the matrix from each edge
770
+ self.each_edge do |source, target, edge|
771
+ i_source = hash[source]
772
+ i_target = hash[target]
773
+ if i_source and i_target then
774
+ val = block_given? ? (yield source, target, edge) : edge
775
+ matrix[i_source][i_target] = val
776
+ matrix[i_target][i_source] = val
777
+ end
778
+ end
779
+ Matrix.rows(matrix, false)
780
+ end
781
+
782
+ # Removes all nodes that are not branches nor leaves.
783
+ # That is, removes nodes connected with exactly two edges.
784
+ # For each removed node, two adjacent edges are merged and
785
+ # a new edge are created.
786
+ # Returns removed nodes.
787
+ # Note that orphan nodes are still kept unchanged.
788
+ def remove_nonsense_nodes
789
+ hash = {}
790
+ self.each_node do |node|
791
+ hash[node] = true if @pathway.graph[node].size == 2
792
+ end
793
+ hash.each_key do |node|
794
+ adjs = @pathway.graph[node].keys
795
+ edges = @pathway.graph[node].values
796
+ new_edge = get_edge_merged(edges[0], edges[1])
797
+ @pathway.graph[adjs[0]].delete(node)
798
+ @pathway.graph[adjs[1]].delete(node)
799
+ @pathway.graph.delete(node)
800
+ @pathway.append(Bio::Relation.new(adjs[0], adjs[1], new_edge))
801
+ end
802
+ #@pathway.to_relations
803
+ @pathway.relations.reject! do |rel|
804
+ hash[rel.node[0]] or hash[rel.node[1]]
805
+ end
806
+ return hash.keys
807
+ end
808
+
809
+ # Insert a new node between adjacent nodes node1 and node2.
810
+ # The old edge between node1 and node2 are changed to the edge
811
+ # between new_node and node2.
812
+ # The edge between node1 and new_node is newly created.
813
+ #
814
+ # If new_distance is specified, the distance between
815
+ # node1 and new_node is set to new_distance, and
816
+ # distance between new_node and node2 is set to
817
+ # <code>tree.get_edge(node1, node2).distance - new_distance</code>.
818
+ #
819
+ # Returns self.
820
+ # If node1 and node2 are not adjacent, raises IndexError.
821
+ #
822
+ # If new_node already exists in the tree, the tree would become
823
+ # circular. In addition, if the edge between new_node and
824
+ # node1 (or node2) already exists, it will be erased.
825
+ def insert_node(node1, node2, new_node, new_distance = nil)
826
+ unless edge = self.get_edge(node1, node2) then
827
+ raise IndexError, 'nodes not found or two nodes are not adjacent'
828
+ end
829
+ new_edge = Edge.new(new_distance)
830
+ self.remove_edge(node1, node2)
831
+ self.add_edge(node1, new_node, new_edge)
832
+ if new_distance and old_distance = get_edge_distance(edge) then
833
+ old_distance -= new_distance
834
+ begin
835
+ edge.distance = old_distance
836
+ rescue NoMethodError
837
+ edge = old_distance
838
+ end
839
+ end
840
+ self.add_edge(new_node, node2, edge)
841
+ self
842
+ end
843
+ end #class Tree
844
+ end #module Bio
845
+
846
+ #---
847
+ # temporary added
848
+ #+++
849
+ require 'bio/db/newick'
850
+