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,410 @@
1
+ #
2
+ # = bio/map.rb - biological mapping class
3
+ #
4
+ # Copyright:: Copyright (C) 2006 Jan Aerts <jan.aerts@bbsrc.ac.uk>
5
+ # License:: The Ruby License
6
+ #
7
+ # $Id: map.rb,v 1.11 2007/04/12 12:19:16 aerts Exp $
8
+
9
+ require 'bio/location'
10
+
11
+ module Bio
12
+
13
+ # == Description
14
+ #
15
+ # The Bio::Map contains classes that describe mapping information
16
+ # and can be used to contain linkage maps, radiation-hybrid maps,
17
+ # etc. As the same marker can be mapped to more than one map, and a
18
+ # single map typically contains more than one marker, the link
19
+ # between the markers and maps is handled by Bio::Map::Mapping
20
+ # objects. Therefore, to link a map to a marker, a Bio::Map::Mapping
21
+ # object is added to that Bio::Map. See usage below.
22
+ #
23
+ # Not only maps in the strict sense have map-like features (and
24
+ # similarly not only markers in the strict sense have marker-like
25
+ # features). For example, a microsatellite is something that can be
26
+ # mapped on a linkage map (and hence becomes a 'marker'), but a
27
+ # clone can also be mapped to a cytogenetic map. In that case, the
28
+ # clone acts as a marker and has marker-like properties. That same
29
+ # clone can also be considered a 'map' when BAC-end sequences are
30
+ # mapped to it. To reflect this flexibility, the modules
31
+ # Bio::Map::ActsLikeMap and Bio::Map::ActsLikeMarker define methods
32
+ # that are typical for maps and markers.
33
+ #
34
+ #--
35
+ # In a certain sense, a biological sequence also has map- and
36
+ # marker-like properties: things can be mapped to it at certain
37
+ # locations, and the sequence itself can be mapped to something else
38
+ # (e.g. the BAC-end sequence example above, or a BLAST-result).
39
+ #++
40
+ #
41
+ # == Usage
42
+ #
43
+ # my_marker1 = Bio::Map::Marker.new('marker1')
44
+ # my_marker2 = Bio::Map::Marker.new('marker2')
45
+ # my_marker3 = Bio::Map::Marker.new('marker3')
46
+ #
47
+ # my_map1 = Bio::Map::SimpleMap.new('RH_map_ABC (2006)', 'RH', 'cR')
48
+ # my_map2 = Bio::Map::SimpleMap.new('consensus', 'linkage', 'cM')
49
+ #
50
+ # my_map1.add_mapping_as_map(my_marker1, '17')
51
+ # my_map1.add_mapping_as_map(Bio::Map::Marker.new('marker2'), '5')
52
+ # my_marker3.add_mapping_as_marker(my_map1, '9')
53
+ #
54
+ # print "Does my_map1 contain marker3? => "
55
+ # puts my_map1.contains_marker?(my_marker3).to_s
56
+ # print "Does my_map2 contain marker3? => "
57
+ # puts my_map2.contains_marker?(my_marker3).to_s
58
+ #
59
+ # my_map1.mappings_as_map.sort.each do |mapping|
60
+ # puts [ mapping.map.name,
61
+ # mapping.marker.name,
62
+ # mapping.location.from.to_s,
63
+ # mapping.location.to.to_s ].join("\t")
64
+ # end
65
+ # puts my_map1.mappings_as_map.min.marker.name
66
+ #
67
+ # my_map2.mappings_as_map.each do |mapping|
68
+ # puts [ mapping.map.name,
69
+ # mapping.marker.name,
70
+ # mapping.location.from.to_s,
71
+ # mapping.location.to.to_s ].join("\t")
72
+ # end
73
+ #
74
+ module Map
75
+
76
+ # == Description
77
+ #
78
+ # The Bio::Map::ActsLikeMap module contains methods that are typical for
79
+ # map-like things:
80
+ #
81
+ # * add markers with their locations (through Bio::Map::Mappings)
82
+ # * check if a given marker is mapped to it,
83
+ # and can be mixed into other classes (e.g. Bio::Map::SimpleMap)
84
+ #
85
+ # Classes that include this mixin should provide an array property
86
+ # called mappings_as_map.
87
+ #
88
+ # For example:
89
+ #
90
+ # class MyMapThing
91
+ # include Bio::Map::ActsLikeMap
92
+ #
93
+ # def initialize (name)
94
+ # @name = name
95
+ # @mappings_as_maps = Array.new
96
+ # end
97
+ # attr_accessor :name, :mappings_as_map
98
+ # end
99
+ #
100
+ module ActsLikeMap
101
+
102
+ # == Description
103
+ #
104
+ # Adds a Bio::Map::Mappings object to its array of mappings.
105
+ #
106
+ # == Usage
107
+ #
108
+ # # suppose we have a Bio::Map::SimpleMap object called my_map
109
+ # my_map.add_mapping_as_map(Bio::Map::Marker.new('marker_a'), '5')
110
+ #
111
+ # ---
112
+ # *Arguments*:
113
+ # * _marker_ (required): Bio::Map::Marker object
114
+ # * _location_: location of mapping. Should be a _string_, not a _number_.
115
+ # *Returns*:: itself
116
+ def add_mapping_as_map(marker, location = nil)
117
+ unless marker.class.include?(Bio::Map::ActsLikeMarker)
118
+ raise "[Error] marker is not object that implements Bio::Map::ActsLikeMarker"
119
+ end
120
+ my_mapping = ( location.nil? ) ? Bio::Map::Mapping.new(self, marker, nil) : Bio::Map::Mapping.new(self, marker, Bio::Locations.new(location))
121
+ if ! marker.mapped_to?(self)
122
+ self.mappings_as_map.push(my_mapping)
123
+ marker.mappings_as_marker.push(my_mapping)
124
+ else
125
+ already_mapped = false
126
+ marker.positions_on(self).each do |loc|
127
+ if loc.equals?(Bio::Locations.new(location))
128
+ already_mapped = true
129
+ end
130
+ end
131
+ if ! already_mapped
132
+ self.mappings_as_map.push(my_mapping)
133
+ marker.mappings_as_marker.push(my_mapping)
134
+ end
135
+ end
136
+
137
+ return self
138
+ end
139
+
140
+ # Checks whether a Bio::Map::Marker is mapped to this
141
+ # Bio::Map::SimpleMap.
142
+ #
143
+ # ---
144
+ # *Arguments*:
145
+ # * _marker_: a Bio::Map::Marker object
146
+ # *Returns*:: true or false
147
+ def contains_marker?(marker)
148
+ unless marker.class.include?(Bio::Map::ActsLikeMarker)
149
+ raise "[Error] marker is not object that implements Bio::Map::ActsLikeMarker"
150
+ end
151
+ contains = false
152
+ self.mappings_as_map.each do |mapping|
153
+ if mapping.marker == marker
154
+ contains = true
155
+ return contains
156
+ end
157
+ end
158
+ return contains
159
+ end
160
+
161
+ end # ActsLikeMap
162
+
163
+ # == Description
164
+ #
165
+ # The Bio::Map::ActsLikeMarker module contains methods that are
166
+ # typical for marker-like things:
167
+ #
168
+ # * map it to one or more maps
169
+ # * check if it's mapped to a given map
170
+ # and can be mixed into other classes (e.g. Bio::Map::Marker)
171
+ #
172
+ # Classes that include this mixin should provide an array property
173
+ # called mappings_as_marker.
174
+ #
175
+ # For example:
176
+ #
177
+ # class MyMarkerThing
178
+ # include Bio::Map::ActsLikeMarker
179
+ #
180
+ # def initialize (name)
181
+ # @name = name
182
+ # @mappings_as_marker = Array.new
183
+ # end
184
+ # attr_accessor :name, :mappings_as_marker
185
+ # end
186
+ #
187
+ module ActsLikeMarker
188
+
189
+ # == Description
190
+ #
191
+ # Adds a Bio::Map::Mappings object to its array of mappings.
192
+ #
193
+ # == Usage
194
+ #
195
+ # # suppose we have a Bio::Map::Marker object called marker_a
196
+ # marker_a.add_mapping_as_marker(Bio::Map::SimpleMap.new('my_map'), '5')
197
+ #
198
+ # ---
199
+ # *Arguments*:
200
+ # * _map_ (required): Bio::Map::SimpleMap object
201
+ # * _location_: location of mapping. Should be a _string_, not a _number_.
202
+ # *Returns*:: itself
203
+ def add_mapping_as_marker(map, location = nil)
204
+ unless map.class.include?(Bio::Map::ActsLikeMap)
205
+ raise "[Error] map is not object that implements Bio::Map::ActsLikeMap"
206
+ end
207
+ my_mapping = (location.nil?) ? Bio::Map::Mappings.new(map, self, nil) : Bio::Map::Mapping.new(map, self, Bio::Locations.new(location))
208
+ if ! self.mapped_to?(map)
209
+ self.mappings_as_marker.push(my_mapping)
210
+ map.mappings_as_map.push(my_mapping)
211
+ else
212
+ already_mapped = false
213
+ self.positions_on(map).each do |loc|
214
+ if loc.equals?(Bio::Locations.new(location))
215
+ already_mapped = true
216
+ end
217
+ end
218
+ if ! already_mapped
219
+ self.mappings_as_marker.push(my_mapping)
220
+ map.mappings_as_map.push(my_mapping)
221
+ end
222
+ end
223
+ end
224
+
225
+ # Check whether this marker is mapped to a given Bio::Map::SimpleMap.
226
+ # ---
227
+ # *Arguments*:
228
+ # * _map_: a Bio::Map::SimpleMap object
229
+ # *Returns*:: true or false
230
+ def mapped_to?(map)
231
+ unless map.class.include?(Bio::Map::ActsLikeMap)
232
+ raise "[Error] map is not object that implements Bio::Map::ActsLikeMap"
233
+ end
234
+
235
+ mapped = false
236
+ self.mappings_as_marker.each do |mapping|
237
+ if mapping.map == map
238
+ mapped = true
239
+ return mapped
240
+ end
241
+ end
242
+
243
+ return mapped
244
+ end
245
+
246
+ # Return all positions of this marker on a given map.
247
+ # ---
248
+ # *Arguments*:
249
+ # * _map_: an object that mixes in Bio::Map::ActsLikeMap
250
+ # *Returns*:: array of Bio::Location objects
251
+ def positions_on(map)
252
+ unless map.class.include?(Bio::Map::ActsLikeMap)
253
+ raise "[Error] map is not object that implements Bio::Map::ActsLikeMap"
254
+ end
255
+
256
+ positions = Array.new
257
+ self.mappings_as_marker.each do |mapping|
258
+ if mapping.map == map
259
+ positions.push(mapping.location)
260
+ end
261
+ end
262
+
263
+ return positions
264
+ end
265
+
266
+ # Return all mappings of this marker on a given map.
267
+ # ---
268
+ # *Arguments*:
269
+ # * _map_: an object that mixes in Bio::Map::ActsLikeMap
270
+ # *Returns*:: array of Bio::Map::Mapping objects
271
+ def mappings_on(map)
272
+ unless map.class.include?(Bio::Map::ActsLikeMap)
273
+ raise "[Error] map is not object that implements Bio::Map::ActsLikeMap"
274
+ end
275
+
276
+ m = Array.new
277
+ self.mappings_as_marker.each do |mapping|
278
+ if mapping.map == map
279
+ m.push(mapping)
280
+ end
281
+ end
282
+
283
+ return m
284
+ end
285
+
286
+
287
+ end # ActsLikeMarker
288
+
289
+ # == Description
290
+ #
291
+ # Creates a new Bio::Map::Mapping object, which links Bio::Map::ActsAsMap-
292
+ # and Bio::Map::ActsAsMarker-like objects. This class is typically not
293
+ # accessed directly, but through map- or marker-like objects.
294
+ class Mapping
295
+
296
+ include Comparable
297
+
298
+ # Creates a new Bio::Map::Mapping object
299
+ # ---
300
+ # *Arguments*:
301
+ # * _map_: a Bio::Map::SimpleMap object
302
+ # * _marker_: a Bio::Map::Marker object
303
+ # * _location_: a Bio::Locations object
304
+ def initialize (map, marker, location = nil)
305
+ @map, @marker, @location = map, marker, location
306
+ end
307
+ attr_accessor :map, :marker, :location
308
+
309
+ # Compares the location of this mapping to another mapping.
310
+ # ---
311
+ # *Arguments*:
312
+ # * other_mapping: Bio::Map::Mapping object
313
+ # *Returns*::
314
+ # * 1 if self < other location
315
+ # * -1 if self > other location
316
+ # * 0 if both location are the same
317
+ # * nil if the argument is not a Bio::Location object
318
+ def <=>(other)
319
+ unless other.kind_of?(Bio::Map::Mapping)
320
+ raise "[Error] markers are not comparable"
321
+ end
322
+ unless @map.equal?(other.map)
323
+ raise "[Error] maps have to be the same"
324
+ end
325
+
326
+ return self.location[0].<=>(other.location[0])
327
+ end
328
+ end # Mapping
329
+
330
+ # == Description
331
+ #
332
+ # This class handles the essential storage of name, type and units
333
+ # of a map. It includes Bio::Map::ActsLikeMap, and therefore
334
+ # supports the methods of that module.
335
+ #
336
+ # == Usage
337
+ #
338
+ # my_map1 = Bio::Map::SimpleMap.new('RH_map_ABC (2006)', 'RH', 'cR')
339
+ # my_map1.add_marker(Bio::Map::Marker.new('marker_a', '17')
340
+ # my_map1.add_marker(Bio::Map::Marker.new('marker_b', '5')
341
+ #
342
+ class SimpleMap
343
+
344
+ include Bio::Map::ActsLikeMap
345
+
346
+ # Builds a new Bio::Map::SimpleMap object
347
+ # ---
348
+ # *Arguments*:
349
+ # * name: name of the map
350
+ # * type: type of the map (e.g. linkage, radiation_hybrid, cytogenetic, ...)
351
+ # * units: unit of the map (e.g. cM, cR, ...)
352
+ # *Returns*:: new Bio::Map::SimpleMap object
353
+ def initialize (name = nil, type = nil, length = nil, units = nil)
354
+ @name, @type, @length, @units = name, type, length, units
355
+ @mappings_as_map = Array.new
356
+ end
357
+
358
+ # Name of the map
359
+ attr_accessor :name
360
+
361
+ # Type of the map
362
+ attr_accessor :type
363
+
364
+ # Length of the map
365
+ attr_accessor :length
366
+
367
+ # Units of the map
368
+ attr_accessor :units
369
+
370
+ # Mappings
371
+ attr_accessor :mappings_as_map
372
+
373
+ end # SimpleMap
374
+
375
+ # == Description
376
+ #
377
+ # This class handles markers that are anchored to a Bio::Map::SimpleMap.
378
+ # It includes Bio::Map::ActsLikeMarker, and therefore supports the
379
+ # methods of that module.
380
+ #
381
+ # == Usage
382
+ #
383
+ # marker_a = Bio::Map::Marker.new('marker_a')
384
+ # marker_b = Bio::Map::Marker.new('marker_b')
385
+ #
386
+ class Marker
387
+
388
+ include Bio::Map::ActsLikeMarker
389
+
390
+ # Builds a new Bio::Map::Marker object
391
+ # ---
392
+ # *Arguments*:
393
+ # * name: name of the marker
394
+ # *Returns*:: new Bio::Map::Marker object
395
+ def initialize(name)
396
+ @name = name
397
+ @mappings_as_marker = Array.new
398
+ end
399
+
400
+ # Name of the marker
401
+ attr_accessor :name
402
+
403
+ # Mappings
404
+ attr_accessor :mappings_as_marker
405
+
406
+ end # Marker
407
+
408
+ end # Map
409
+
410
+ end # Bio
@@ -1,549 +1,685 @@
1
1
  #
2
- # bio/pathway.rb - Binary relations and Graph algorithms
2
+ # = bio/pathway.rb - Binary relations and Graph algorithms
3
3
  #
4
- # Copyright (C) 2001 KATAYAMA Toshiaki <k@bioruby.org>
5
- # KAWASHIMA Shuichi <s@bioruby.org>
4
+ # Copyright: Copyright (C) 2001
5
+ # Toshiaki Katayama <k@bioruby.org>,
6
+ # Shuichi Kawashima <shuichi@hgc.jp>
7
+ # License:: The Ruby License
6
8
  #
7
- # This library is free software; you can redistribute it and/or
8
- # modify it under the terms of the GNU Lesser General Public
9
- # License as published by the Free Software Foundation; either
10
- # version 2 of the License, or (at your option) any later version.
11
- #
12
- # This library is distributed in the hope that it will be useful,
13
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
14
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
- # Lesser General Public License for more details.
16
- #
17
- # You should have received a copy of the GNU Lesser General Public
18
- # License along with this library; if not, write to the Free Software
19
- # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20
- #
21
- # $Id: pathway.rb,v 1.34 2005/12/18 16:50:56 k Exp $
9
+ # $Id: pathway.rb,v 1.36 2007/04/05 23:35:39 trevor Exp $
22
10
  #
23
11
 
24
12
  require 'matrix'
25
13
 
26
14
  module Bio
27
15
 
28
- class Pathway
16
+ # Bio::Pathway is a general graph object initially constructed by the
17
+ # list of the ((<Bio::Relation>)) objects. The basic concept of the
18
+ # Bio::Pathway object is to store a graph as an adjacency list (in the
19
+ # instance variable @graph), and converting the list into an adjacency
20
+ # matrix by calling to_matrix method on demand. However, in some
21
+ # cases, it is convenient to have the original list of the
22
+ # ((<Bio::Relation>))s, Bio::Pathway object also stores the list (as
23
+ # the instance variable @relations) redundantly.
24
+ #
25
+ # Note: you can clear the @relations list by calling clear_relations!
26
+ # method to reduce the memory usage, and the content of the @relations
27
+ # can be re-generated from the @graph by to_relations method.
28
+ class Pathway
29
+
30
+ # Initial graph (adjacency list) generation from the list of Relation.
31
+ #
32
+ # Generate Bio::Pathway object from the list of Bio::Relation objects.
33
+ # If the second argument is true, undirected graph is generated.
34
+ #
35
+ # r1 = Bio::Relation.new('a', 'b', 1)
36
+ # r2 = Bio::Relation.new('a', 'c', 5)
37
+ # r3 = Bio::Relation.new('b', 'c', 3)
38
+ # list = [ r1, r2, r3 ]
39
+ # g = Bio::Pathway.new(list, 'undirected')
40
+ #
41
+ def initialize(relations, undirected = false)
42
+ @undirected = undirected
43
+ @relations = relations
44
+ @graph = {} # adjacency list expression of the graph
45
+ @index = {} # numbering each node in matrix
46
+ @label = {} # additional information on each node
47
+ self.to_list # generate adjacency list
48
+ end
29
49
 
30
- # Initial graph (adjacency list) generation from the list of Relation
31
- def initialize(relations, undirected = false)
32
- @undirected = undirected
33
- @relations = relations
34
- @graph = {} # adjacency list expression of the graph
35
- @index = {} # numbering each node in matrix
36
- @label = {} # additional information on each node
37
- self.to_list # generate adjacency list
38
- end
39
- attr_reader :relations, :graph, :index
40
- attr_accessor :label
50
+ # Read-only accessor for the internal list of the Bio::Relation objects
51
+ attr_reader :relations
41
52
 
42
- def directed?
43
- @undirected ? false : true
44
- end
53
+ # Read-only accessor for the adjacency list of the graph.
54
+ attr_reader :graph
45
55
 
46
- def undirected?
47
- @undirected ? true : false
48
- end
56
+ # Read-only accessor for the row/column index (@index) of the
57
+ # adjacency matrix. Contents of the hash @index is created by
58
+ # calling to_matrix method.
59
+ attr_reader :index
49
60
 
50
- def directed
51
- if undirected?
52
- @undirected = false
53
- self.to_list
54
- end
55
- end
61
+ # Accessor for the hash of the label assigned to the each node. You can
62
+ # label some of the nodes in the graph by passing a hash to the label
63
+ # and select subgraphs which contain labeled nodes only by subgraph method.
64
+ #
65
+ # hash = { 1 => 'red', 2 => 'green', 5 => 'black' }
66
+ # g.label = hash
67
+ # g.label
68
+ # g.subgraph # => new graph consists of the node 1, 2, 5 only
69
+ #
70
+ attr_accessor :label
56
71
 
57
- def undirected
58
- if directed?
59
- @undirected = true
60
- self.to_list
61
- end
62
- end
63
72
 
64
- # clear @relations to reduce the memory usage
65
- def clear_relations!
66
- @relations.clear
73
+ # Returns true or false respond to the internal state of the graph.
74
+ def directed?
75
+ @undirected ? false : true
76
+ end
77
+
78
+ # Returns true or false respond to the internal state of the graph.
79
+ def undirected?
80
+ @undirected ? true : false
81
+ end
82
+
83
+ # Changes the internal state of the graph from 'undirected' to
84
+ # 'directed' and re-generate adjacency list. The undirected graph
85
+ # can be converted to directed graph, however, the edge between two
86
+ # nodes will be simply doubled to both ends.
87
+ #
88
+ # Note: this method can not be used without the list of the
89
+ # Bio::Relation objects (internally stored in @relations variable).
90
+ # Thus if you already called clear_relations! method, call
91
+ # to_relations first.
92
+ def directed
93
+ if undirected?
94
+ @undirected = false
95
+ self.to_list
67
96
  end
97
+ end
68
98
 
69
- # reconstruct @relations from the adjacency list @graph
70
- def to_relations
71
- @relations.clear
72
- @graph.each_key do |from|
73
- @graph[from].each do |to, w|
74
- @relations << Relation.new(from, to, w)
75
- end
76
- end
77
- return @relations
99
+ # Changes the internal state of the graph from 'directed' to
100
+ # 'undirected' and re-generate adjacency list.
101
+ #
102
+ # Note: this method can not be used without the list of the
103
+ # Bio::Relation objects (internally stored in @relations variable).
104
+ # Thus if you already called clear_relations! method, call
105
+ # to_relations first.
106
+ def undirected
107
+ if directed?
108
+ @undirected = true
109
+ self.to_list
78
110
  end
111
+ end
79
112
 
113
+ # Clear @relations array to reduce the memory usage.
114
+ def clear_relations!
115
+ @relations.clear
116
+ end
80
117
 
81
- # Graph (adjacency list) generation from the Relations
82
- def to_list
83
- @graph.clear
84
- @relations.each do |rel|
85
- append(rel, false) # append to @graph without push to @relations
118
+ # Reconstruct @relations from the adjacency list @graph.
119
+ def to_relations
120
+ @relations.clear
121
+ @graph.each_key do |from|
122
+ @graph[from].each do |to, w|
123
+ @relations << Relation.new(from, to, w)
86
124
  end
87
125
  end
126
+ return @relations
127
+ end
88
128
 
89
- def append(rel, add_rel = true)
90
- @relations.push(rel) if add_rel
91
- if @graph[rel.from].nil?
92
- @graph[rel.from] = {}
93
- end
94
- if @graph[rel.to].nil?
95
- @graph[rel.to] = {}
96
- end
97
- @graph[rel.from][rel.to] = rel.relation
98
- @graph[rel.to][rel.from] = rel.relation if @undirected
99
- end
100
129
 
101
- def delete(rel)
102
- @relations.delete_if do |x|
103
- x === rel
104
- end
105
- @graph[rel.from].delete(rel.to)
106
- @graph[rel.to].delete(rel.from) if @undirected
130
+ # Graph (adjacency list) generation from the Relations
131
+ #
132
+ # Generate the adjcancecy list @graph from @relations (called by
133
+ # initialize and in some other cases when @relations has been changed).
134
+ def to_list
135
+ @graph.clear
136
+ @relations.each do |rel|
137
+ append(rel, false) # append to @graph without push to @relations
107
138
  end
139
+ end
108
140
 
109
- def nodes
110
- @graph.keys.length
141
+ # Add an Bio::Relation object 'rel' to the @graph and @relations.
142
+ # If the second argument is false, @relations is not modified (only
143
+ # useful when genarating @graph from @relations internally).
144
+ def append(rel, add_rel = true)
145
+ @relations.push(rel) if add_rel
146
+ if @graph[rel.from].nil?
147
+ @graph[rel.from] = {}
111
148
  end
149
+ if @graph[rel.to].nil?
150
+ @graph[rel.to] = {}
151
+ end
152
+ @graph[rel.from][rel.to] = rel.relation
153
+ @graph[rel.to][rel.from] = rel.relation if @undirected
154
+ end
112
155
 
113
- def edges
114
- edges = 0
115
- @graph.each_value do |v|
116
- edges += v.size
117
- end
118
- edges
156
+ # Remove an edge indicated by the Bio::Relation object 'rel' from the
157
+ # @graph and the @relations.
158
+ def delete(rel)
159
+ @relations.delete_if do |x|
160
+ x === rel
119
161
  end
162
+ @graph[rel.from].delete(rel.to)
163
+ @graph[rel.to].delete(rel.from) if @undirected
164
+ end
120
165
 
166
+ # Returns the number of the nodes in the graph.
167
+ def nodes
168
+ @graph.keys.length
169
+ end
121
170
 
122
- # Convert adjacency list to adjacency matrix
123
- def to_matrix(default_value = nil, diagonal_value = nil)
171
+ # Returns the number of the edges in the graph.
172
+ def edges
173
+ edges = 0
174
+ @graph.each_value do |v|
175
+ edges += v.size
176
+ end
177
+ edges
178
+ end
124
179
 
125
- # Note: following code only fills the outer Array with the reference
126
- # to the same inner Array object.
127
- #
128
- # matrix = Array.new(nodes, Array.new(nodes))
129
- #
130
- # so create a new Array object for each row as follows:
131
180
 
132
- matrix = Array.new
133
- nodes.times do
134
- matrix.push(Array.new(nodes, default_value))
135
- end
181
+ # Convert adjacency list to adjacency matrix
182
+ #
183
+ # Returns the adjacency matrix expression of the graph as a Matrix
184
+ # object. If the first argument was assigned, the matrix will be
185
+ # filled with the given value. The second argument indicates the
186
+ # value of the diagonal constituents of the matrix besides the above.
187
+ def to_matrix(default_value = nil, diagonal_value = nil)
136
188
 
137
- if diagonal_value
138
- nodes.times do |i|
139
- matrix[i][i] = diagonal_value
140
- end
141
- end
189
+ #--
190
+ # Note: following code only fills the outer Array with the reference
191
+ # to the same inner Array object.
192
+ #
193
+ # matrix = Array.new(nodes, Array.new(nodes))
194
+ #
195
+ # so create a new Array object for each row as follows:
196
+ #++
142
197
 
143
- # assign index number for each node
144
- @graph.keys.each_with_index do |k, i|
145
- @index[k] = i
146
- end
198
+ matrix = Array.new
199
+ nodes.times do
200
+ matrix.push(Array.new(nodes, default_value))
201
+ end
147
202
 
148
- if @relations.empty? # only used after clear_relations!
149
- @graph.each do |from, hash|
150
- hash.each do |to, relation|
151
- x = @index[from]
152
- y = @index[to]
153
- matrix[x][y] = relation
154
- end
155
- end
156
- else
157
- @relations.each do |rel|
158
- x = @index[rel.from]
159
- y = @index[rel.to]
160
- matrix[x][y] = rel.relation
161
- matrix[y][x] = rel.relation if @undirected
162
- end
203
+ if diagonal_value
204
+ nodes.times do |i|
205
+ matrix[i][i] = diagonal_value
163
206
  end
164
- Matrix[*matrix]
165
207
  end
166
208
 
167
-
168
- # pretty printer of the adjacency matrix
169
- def dump_matrix(*arg)
170
- matrix = self.to_matrix(*arg)
171
- sorted = @index.sort {|a,b| a[1] <=> b[1]}
172
- "[# " + sorted.collect{|x| x[0]}.join(", ") + "\n" +
173
- matrix.to_a.collect{|row| ' ' + row.inspect}.join(",\n") + "\n]"
209
+ # assign index number for each node
210
+ @graph.keys.each_with_index do |k, i|
211
+ @index[k] = i
174
212
  end
175
213
 
176
- # pretty printer of the adjacency list
177
- def dump_list
178
- list = ""
214
+ if @relations.empty? # only used after clear_relations!
179
215
  @graph.each do |from, hash|
180
- list << "#{from} => "
181
- a = []
182
- hash.each do |to, relation|
183
- a.push("#{to} (#{relation})")
184
- end
185
- list << a.join(", ") + "\n"
216
+ hash.each do |to, relation|
217
+ x = @index[from]
218
+ y = @index[to]
219
+ matrix[x][y] = relation
220
+ end
221
+ end
222
+ else
223
+ @relations.each do |rel|
224
+ x = @index[rel.from]
225
+ y = @index[rel.to]
226
+ matrix[x][y] = rel.relation
227
+ matrix[y][x] = rel.relation if @undirected
186
228
  end
187
- list
188
229
  end
230
+ Matrix[*matrix]
231
+ end
232
+
189
233
 
234
+ # Pretty printer of the adjacency matrix.
235
+ #
236
+ # The dump_matrix method accepts the same arguments as to_matrix.
237
+ # Useful when you want to check the internal state of the matrix
238
+ # (for debug purpose etc.) easily.
239
+ def dump_matrix(*arg)
240
+ matrix = self.to_matrix(*arg)
241
+ sorted = @index.sort {|a,b| a[1] <=> b[1]}
242
+ "[# " + sorted.collect{|x| x[0]}.join(", ") + "\n" +
243
+ matrix.to_a.collect{|row| ' ' + row.inspect}.join(",\n") + "\n]"
244
+ end
245
+
246
+ # Pretty printer of the adjacency list.
247
+ #
248
+ # The dump_matrix method accepts the same arguments as to_matrix.
249
+ # Useful when you want to check the internal state of the adjacency
250
+ # list (for debug purpose etc.) easily.
251
+ def dump_list
252
+ list = ""
253
+ @graph.each do |from, hash|
254
+ list << "#{from} => "
255
+ a = []
256
+ hash.each do |to, relation|
257
+ a.push("#{to} (#{relation})")
258
+ end
259
+ list << a.join(", ") + "\n"
260
+ end
261
+ list
262
+ end
190
263
 
191
- # Select labeled nodes and generate subgraph
192
- def subgraph(list = nil)
193
- if list
194
- @label.clear
195
- list.each do |node|
196
- @label[node] = true
197
- end
264
+ # Select labeled nodes and generate subgraph
265
+ #
266
+ # This method select some nodes and returns new Bio::Pathway object
267
+ # consists of selected nodes only. If the list of the nodes (as
268
+ # Array) is assigned as the argument, use the list to select the
269
+ # nodes from the graph. If no argument is assigned, internal
270
+ # property of the graph @label is used to select the nodes.
271
+ #
272
+ # hash = { 'a' => 'secret', 'b' => 'important', 'c' => 'important' }
273
+ # g.label = hash
274
+ # g.subgraph
275
+ # list = [ 'a', 'b', 'c' ]
276
+ # g.subgraph(list)
277
+ #
278
+ def subgraph(list = nil)
279
+ if list
280
+ @label.clear
281
+ list.each do |node|
282
+ @label[node] = true
198
283
  end
199
- sub_graph = Pathway.new([], @undirected)
200
- @graph.each do |from, hash|
201
- next unless @label[from]
202
- hash.each do |to, relation|
203
- next unless @label[to]
204
- sub_graph.append(Relation.new(from, to, relation))
205
- end
284
+ end
285
+ sub_graph = Pathway.new([], @undirected)
286
+ @graph.each do |from, hash|
287
+ next unless @label[from]
288
+ hash.each do |to, relation|
289
+ next unless @label[to]
290
+ sub_graph.append(Relation.new(from, to, relation))
206
291
  end
207
- return sub_graph
208
292
  end
293
+ return sub_graph
294
+ end
209
295
 
210
296
 
211
- def common_subgraph(graph)
212
- raise NotImplementedError
213
- end
297
+ # Not implemented yet.
298
+ def common_subgraph(graph)
299
+ raise NotImplementedError
300
+ end
214
301
 
215
302
 
216
- def clique
217
- raise NotImplementedError
218
- end
303
+ # Not implemented yet.
304
+ def clique
305
+ raise NotImplementedError
306
+ end
219
307
 
220
308
 
221
- # Returns completeness of the edge density among the surrounded nodes
222
- def cliquishness(node)
223
- neighbors = @graph[node].keys
224
- sg = subgraph(neighbors)
225
- if sg.graph.size != 0
226
- edges = sg.edges / 2.0
227
- nodes = sg.nodes
228
- complete = (nodes * (nodes - 1)) / 2.0
229
- return edges/complete
230
- else
231
- return 0.0
232
- end
309
+ # Returns completeness of the edge density among the surrounded nodes.
310
+ #
311
+ # Calculates the value of cliquishness around the 'node'. This value
312
+ # indicates completeness of the edge density among the surrounded nodes.
313
+ def cliquishness(node)
314
+ neighbors = @graph[node].keys
315
+ sg = subgraph(neighbors)
316
+ if sg.graph.size != 0
317
+ edges = sg.edges / 2.0
318
+ nodes = sg.nodes
319
+ complete = (nodes * (nodes - 1)) / 2.0
320
+ return edges/complete
321
+ else
322
+ return 0.0
233
323
  end
324
+ end
234
325
 
326
+ # Returns frequency of the nodes having same number of edges as hash
327
+ #
328
+ # Calculates the frequency of the nodes having the same number of edges
329
+ # and returns the value as Hash.
330
+ def small_world
331
+ freq = Hash.new(0)
332
+ @graph.each_value do |v|
333
+ freq[v.size] += 1
334
+ end
335
+ return freq
336
+ end
235
337
 
236
- # Returns frequency of the nodes having same number of edges as hash
237
- def small_world
238
- freq = Hash.new(0)
239
- @graph.each_value do |v|
240
- freq[v.size] += 1
338
+ # Breadth first search solves steps and path to the each node and
339
+ # forms a tree contains all reachable vertices from the root node.
340
+ # This method returns the result in 2 hashes - 1st one shows the
341
+ # steps from root node and 2nd hash shows the structure of the tree.
342
+ #
343
+ # The weight of the edges are not considered in this method.
344
+ def breadth_first_search(root)
345
+ visited = {}
346
+ distance = {}
347
+ predecessor = {}
348
+
349
+ visited[root] = true
350
+ distance[root] = 0
351
+ predecessor[root] = nil
352
+
353
+ queue = [ root ]
354
+
355
+ while from = queue.shift
356
+ next unless @graph[from]
357
+ @graph[from].each_key do |to|
358
+ unless visited[to]
359
+ visited[to] = true
360
+ distance[to] = distance[from] + 1
361
+ predecessor[to] = from
362
+ queue.push(to)
363
+ end
241
364
  end
242
- return freq
243
365
  end
366
+ return distance, predecessor
367
+ end
244
368
 
369
+ # Alias for the breadth_first_search method.
370
+ alias bfs breadth_first_search
245
371
 
246
- # Breadth first search solves steps and path to the each node and forms
247
- # a tree contains all reachable vertices from the root node.
248
- def breadth_first_search(root)
249
- visited = {}
250
- distance = {}
251
- predecessor = {}
252
-
253
- visited[root] = true
254
- distance[root] = 0
255
- predecessor[root] = nil
256
-
257
- queue = [ root ]
258
372
 
259
- while from = queue.shift
260
- next unless @graph[from]
261
- @graph[from].each_key do |to|
262
- unless visited[to]
263
- visited[to] = true
264
- distance[to] = distance[from] + 1
265
- predecessor[to] = from
266
- queue.push(to)
267
- end
268
- end
269
- end
270
- return distance, predecessor
373
+ # Calculates the shortest path between two nodes by using
374
+ # breadth_first_search method and returns steps and the path as Array.
375
+ def bfs_shortest_path(node1, node2)
376
+ distance, route = breadth_first_search(node1)
377
+ step = distance[node2]
378
+ node = node2
379
+ path = [ node2 ]
380
+ while node != node1 and route[node]
381
+ node = route[node]
382
+ path.unshift(node)
271
383
  end
272
- alias bfs breadth_first_search
384
+ return step, path
385
+ end
273
386
 
274
387
 
275
- def bfs_shortest_path(node1, node2)
276
- distance, route = breadth_first_search(node1)
277
- step = distance[node2]
278
- node = node2
279
- path = [ node2 ]
280
- while node != node1 and route[node]
281
- node = route[node]
282
- path.unshift(node)
388
+ # Depth first search yields much information about the structure of
389
+ # the graph especially on the classification of the edges. This
390
+ # method returns 5 hashes - 1st one shows the timestamps of each
391
+ # node containing the first discoverd time and the search finished
392
+ # time in an array. The 2nd, 3rd, 4th, and 5th hashes contain 'tree
393
+ # edges', 'back edges', 'cross edges', 'forward edges' respectively.
394
+ #
395
+ # If $DEBUG is true (e.g. ruby -d), this method prints the progression
396
+ # of the search.
397
+ #
398
+ # The weight of the edges are not considered in this method.
399
+ def depth_first_search
400
+ visited = {}
401
+ timestamp = {}
402
+ tree_edges = {}
403
+ back_edges = {}
404
+ cross_edges = {}
405
+ forward_edges = {}
406
+ count = 0
407
+
408
+ dfs_visit = Proc.new { |from|
409
+ visited[from] = true
410
+ timestamp[from] = [count += 1]
411
+ @graph[from].each_key do |to|
412
+ if visited[to]
413
+ if timestamp[to].size > 1
414
+ if timestamp[from].first < timestamp[to].first
415
+ # forward edge (black)
416
+ p "#{from} -> #{to} : forward edge" if $DEBUG
417
+ forward_edges[from] = to
418
+ else
419
+ # cross edge (black)
420
+ p "#{from} -> #{to} : cross edge" if $DEBUG
421
+ cross_edges[from] = to
422
+ end
423
+ else
424
+ # back edge (gray)
425
+ p "#{from} -> #{to} : back edge" if $DEBUG
426
+ back_edges[from] = to
427
+ end
428
+ else
429
+ # tree edge (white)
430
+ p "#{from} -> #{to} : tree edge" if $DEBUG
431
+ tree_edges[to] = from
432
+ dfs_visit.call(to)
433
+ end
283
434
  end
284
- return step, path
285
- end
286
-
287
-
288
- # Depth first search yields much information about the structure of the
289
- # graph especially on the classification of the edges.
290
- def depth_first_search
291
- visited = {}
292
- timestamp = {}
293
- tree_edges = {}
294
- back_edges = {}
295
- cross_edges = {}
296
- forward_edges = {}
297
- count = 0
298
-
299
- dfs_visit = Proc.new { |from|
300
- visited[from] = true
301
- timestamp[from] = [count += 1]
302
- @graph[from].each_key do |to|
303
- if visited[to]
304
- if timestamp[to].size > 1
305
- if timestamp[from].first < timestamp[to].first
306
- # forward edge (black)
307
- p "#{from} -> #{to} : forward edge" if $DEBUG
308
- forward_edges[from] = to
309
- else
310
- # cross edge (black)
311
- p "#{from} -> #{to} : cross edge" if $DEBUG
312
- cross_edges[from] = to
313
- end
314
- else
315
- # back edge (gray)
316
- p "#{from} -> #{to} : back edge" if $DEBUG
317
- back_edges[from] = to
318
- end
319
- else
320
- # tree edge (white)
321
- p "#{from} -> #{to} : tree edge" if $DEBUG
322
- tree_edges[to] = from
323
- dfs_visit.call(to)
324
- end
325
- end
326
- timestamp[from].push(count += 1)
327
- }
328
-
329
- @graph.each_key do |node|
330
- unless visited[node]
331
- dfs_visit.call(node)
332
- end
435
+ timestamp[from].push(count += 1)
436
+ }
437
+
438
+ @graph.each_key do |node|
439
+ unless visited[node]
440
+ dfs_visit.call(node)
333
441
  end
334
- return timestamp, tree_edges, back_edges, cross_edges, forward_edges
335
442
  end
336
- alias dfs depth_first_search
443
+ return timestamp, tree_edges, back_edges, cross_edges, forward_edges
444
+ end
337
445
 
446
+ # Alias for the depth_first_search method.
447
+ alias dfs depth_first_search
338
448
 
339
- def dfs_topological_sort
340
- # sorted by finished time reversely and collect node names only
341
- timestamp, = self.depth_first_search
342
- timestamp.sort {|a,b| b[1][1] <=> a[1][1]}.collect {|x| x.first }
343
- end
344
449
 
450
+ # Topological sort of the directed acyclic graphs ("dags") by using
451
+ # depth_first_search.
452
+ def dfs_topological_sort
453
+ # sorted by finished time reversely and collect node names only
454
+ timestamp, = self.depth_first_search
455
+ timestamp.sort {|a,b| b[1][1] <=> a[1][1]}.collect {|x| x.first }
456
+ end
345
457
 
346
- # Dijkstra method to solve the shortest path problem in the weighted graph.
347
- def dijkstra(root)
348
- distance, predecessor = initialize_single_source(root)
349
- @graph[root].each do |k, v|
350
- distance[k] = v
351
- predecessor[k] = root
352
- end
353
- queue = distance.dup
354
- queue.delete(root)
355
-
356
- while queue.size != 0
357
- min = queue.min {|a, b| a[1] <=> b[1]}
358
- u = min[0] # extranct a node having minimal distance
359
- @graph[u].each do |k, v|
360
- # relaxing procedure of root -> 'u' -> 'k'
361
- if distance[k] > distance[u] + v
362
- distance[k] = distance[u] + v
363
- predecessor[k] = u
364
- end
458
+
459
+ # Dijkstra method to solve the shortest path problem in the weighted graph.
460
+ def dijkstra(root)
461
+ distance, predecessor = initialize_single_source(root)
462
+ @graph[root].each do |k, v|
463
+ distance[k] = v
464
+ predecessor[k] = root
465
+ end
466
+ queue = distance.dup
467
+ queue.delete(root)
468
+
469
+ while queue.size != 0
470
+ min = queue.min {|a, b| a[1] <=> b[1]}
471
+ u = min[0] # extranct a node having minimal distance
472
+ @graph[u].each do |k, v|
473
+ # relaxing procedure of root -> 'u' -> 'k'
474
+ if distance[k] > distance[u] + v
475
+ distance[k] = distance[u] + v
476
+ predecessor[k] = u
365
477
  end
366
- queue.delete(u)
367
478
  end
368
- return distance, predecessor
479
+ queue.delete(u)
369
480
  end
481
+ return distance, predecessor
482
+ end
370
483
 
371
-
372
- # Bellman-Ford method for solving the single-source shortest-paths
373
- # problem in the graph in which edge weights can be negative.
374
- def bellman_ford(root)
375
- distance, predecessor = initialize_single_source(root)
376
- for i in 1 ..(self.nodes - 1) do
377
- @graph.each_key do |u|
378
- @graph[u].each do |v, w|
379
- # relaxing procedure of root -> 'u' -> 'v'
380
- if distance[v] > distance[u] + w
381
- distance[v] = distance[u] + w
382
- predecessor[v] = u
383
- end
384
- end
385
- end
386
- end
387
- # negative cyclic loop check
484
+ # Bellman-Ford method for solving the single-source shortest-paths
485
+ # problem in the graph in which edge weights can be negative.
486
+ def bellman_ford(root)
487
+ distance, predecessor = initialize_single_source(root)
488
+ for i in 1 ..(self.nodes - 1) do
388
489
  @graph.each_key do |u|
389
490
  @graph[u].each do |v, w|
491
+ # relaxing procedure of root -> 'u' -> 'v'
390
492
  if distance[v] > distance[u] + w
391
- return false
493
+ distance[v] = distance[u] + w
494
+ predecessor[v] = u
392
495
  end
393
496
  end
394
497
  end
395
- return distance, predecessor
396
498
  end
499
+ # negative cyclic loop check
500
+ @graph.each_key do |u|
501
+ @graph[u].each do |v, w|
502
+ if distance[v] > distance[u] + w
503
+ return false
504
+ end
505
+ end
506
+ end
507
+ return distance, predecessor
508
+ end
397
509
 
398
510
 
399
- # Floyd-Wardshall alogrithm for solving the all-pairs shortest-paths
400
- # problem on a directed graph G = (V, E).
401
- def floyd_warshall
402
- inf = 1 / 0.0
511
+ # Floyd-Wardshall alogrithm for solving the all-pairs shortest-paths
512
+ # problem on a directed graph G = (V, E).
513
+ def floyd_warshall
514
+ inf = 1 / 0.0
403
515
 
404
- m = self.to_matrix(inf, 0)
405
- d = m.dup
406
- n = self.nodes
407
- for k in 0 .. n - 1 do
408
- for i in 0 .. n - 1 do
409
- for j in 0 .. n - 1 do
410
- if d[i, j] > d[i, k] + d[k, j]
411
- d[i, j] = d[i, k] + d[k, j]
412
- end
516
+ m = self.to_matrix(inf, 0)
517
+ d = m.dup
518
+ n = self.nodes
519
+ for k in 0 .. n - 1 do
520
+ for i in 0 .. n - 1 do
521
+ for j in 0 .. n - 1 do
522
+ if d[i, j] > d[i, k] + d[k, j]
523
+ d[i, j] = d[i, k] + d[k, j]
413
524
  end
414
525
  end
415
526
  end
416
- return d
417
527
  end
418
- alias floyd floyd_warshall
419
-
528
+ return d
529
+ end
420
530
 
421
- # Kruskal method for finding minimam spaninng trees
422
- def kruskal
423
- # initialize
424
- rel = self.to_relations.sort{|a, b| a <=> b}
425
- index = []
426
- for i in 0 .. (rel.size - 1) do
427
- for j in (i + 1) .. (rel.size - 1) do
428
- if rel[i] == rel[j]
429
- index << j
430
- end
531
+ # Alias for the floyd_warshall method.
532
+ alias floyd floyd_warshall
533
+
534
+ # Kruskal method for finding minimam spaninng trees
535
+ def kruskal
536
+ # initialize
537
+ rel = self.to_relations.sort{|a, b| a <=> b}
538
+ index = []
539
+ for i in 0 .. (rel.size - 1) do
540
+ for j in (i + 1) .. (rel.size - 1) do
541
+ if rel[i] == rel[j]
542
+ index << j
431
543
  end
432
544
  end
433
- index.sort{|x, y| y<=>x}.each do |i|
434
- rel[i, 1] = []
545
+ end
546
+ index.sort{|x, y| y<=>x}.each do |i|
547
+ rel[i, 1] = []
548
+ end
549
+ mst = []
550
+ seen = Hash.new()
551
+ @graph.each_key do |x|
552
+ seen[x] = nil
553
+ end
554
+ i = 1
555
+ # initialize end
556
+
557
+ rel.each do |r|
558
+ if seen[r.node[0]] == nil
559
+ seen[r.node[0]] = 0
435
560
  end
436
- mst = []
437
- seen = Hash.new()
438
- @graph.each_key do |x|
439
- seen[x] = nil
561
+ if seen[r.node[1]] == nil
562
+ seen[r.node[1]] = 0
440
563
  end
441
- i = 1
442
- # initialize end
443
-
444
- rel.each do |r|
445
- if seen[r.node[0]] == nil
446
- seen[r.node[0]] = 0
447
- end
448
- if seen[r.node[1]] == nil
449
- seen[r.node[1]] = 0
450
- end
451
- if seen[r.node[0]] == seen[r.node[1]] && seen[r.node[0]] == 0
452
- mst << r
453
- seen[r.node[0]] = i
454
- seen[r.node[1]] = i
455
- elsif seen[r.node[0]] != seen[r.node[1]]
456
- mst << r
457
- v1 = seen[r.node[0]].dup
458
- v2 = seen[r.node[1]].dup
459
- seen.each do |k, v|
460
- if v == v1 || v == v2
461
- seen[k] = i
462
- end
564
+ if seen[r.node[0]] == seen[r.node[1]] && seen[r.node[0]] == 0
565
+ mst << r
566
+ seen[r.node[0]] = i
567
+ seen[r.node[1]] = i
568
+ elsif seen[r.node[0]] != seen[r.node[1]]
569
+ mst << r
570
+ v1 = seen[r.node[0]].dup
571
+ v2 = seen[r.node[1]].dup
572
+ seen.each do |k, v|
573
+ if v == v1 || v == v2
574
+ seen[k] = i
463
575
  end
464
576
  end
465
- i += 1
466
577
  end
467
- return Pathway.new(mst)
578
+ i += 1
468
579
  end
580
+ return Pathway.new(mst)
581
+ end
469
582
 
470
583
 
471
- private
584
+ private
472
585
 
473
586
 
474
- def initialize_single_source(root)
475
- inf = 1 / 0.0 # inf.infinite? -> true
587
+ def initialize_single_source(root)
588
+ inf = 1 / 0.0 # inf.infinite? -> true
476
589
 
477
- distance = {}
478
- predecessor = {}
590
+ distance = {}
591
+ predecessor = {}
479
592
 
480
- @graph.each_key do |k|
481
- distance[k] = inf
482
- predecessor[k] = nil
483
- end
484
- distance[root] = 0
485
- return distance, predecessor
593
+ @graph.each_key do |k|
594
+ distance[k] = inf
595
+ predecessor[k] = nil
486
596
  end
487
-
597
+ distance[root] = 0
598
+ return distance, predecessor
488
599
  end
489
600
 
601
+ end # Pathway
490
602
 
491
603
 
492
- class Relation
493
604
 
494
- def initialize(node1, node2, edge)
495
- @node = [node1, node2]
496
- @edge = edge
497
- end
498
- attr_accessor :node, :edge
605
+ # Bio::Relation is a simple object storing two nodes and the relation of them.
606
+ # The nodes and the edge (relation) can be any Ruby object. You can also
607
+ # compare Bio::Relation objects if the edges have Comparable property.
608
+ class Relation
499
609
 
500
- def from
501
- @node[0]
502
- end
610
+ # Create new binary relation object consists of the two object 'node1'
611
+ # and 'node2' with the 'edge' object as the relation of them.
612
+ def initialize(node1, node2, edge)
613
+ @node = [node1, node2]
614
+ @edge = edge
615
+ end
616
+ attr_accessor :node, :edge
503
617
 
504
- def to
505
- @node[1]
506
- end
618
+ # Returns one node.
619
+ def from
620
+ @node[0]
621
+ end
507
622
 
508
- def relation
509
- @edge
510
- end
623
+ # Returns another node.
624
+ def to
625
+ @node[1]
626
+ end
511
627
 
512
- def hash
513
- @node.sort.push(@edge).hash
514
- end
628
+ def relation
629
+ @edge
630
+ end
515
631
 
516
- def ===(rel)
517
- if self.edge == rel.edge
518
- if self.node[0] == rel.node[0] and self.node[1] == rel.node[1]
519
- return true
520
- elsif self.node[0] == rel.node[1] and self.node[1] == rel.node[0]
521
- return true
522
- else
523
- return false
524
- end
632
+ # Used by eql? method
633
+ def hash
634
+ @node.sort.push(@edge).hash
635
+ end
636
+
637
+ # Compare with another Bio::Relation object whether havind same edges
638
+ # and same nodes. The == method compares Bio::Relation object's id,
639
+ # however this case equality === method compares the internal property
640
+ # of the Bio::Relation object.
641
+ def ===(rel)
642
+ if self.edge == rel.edge
643
+ if self.node[0] == rel.node[0] and self.node[1] == rel.node[1]
644
+ return true
645
+ elsif self.node[0] == rel.node[1] and self.node[1] == rel.node[0]
646
+ return true
525
647
  else
526
- return false
648
+ return false
527
649
  end
650
+ else
651
+ return false
528
652
  end
529
- alias eql? ===
653
+ end
530
654
 
531
- def <=>(rel)
532
- unless self.edge.kind_of? Comparable
533
- raise "[Error] edges are not comparable"
534
- end
535
- if self.edge > rel.edge
536
- return 1
537
- elsif self.edge < rel.edge
538
- return -1
539
- elsif self.edge == rel.edge
540
- return 0
541
- end
655
+ # Method eql? is an alias of the === method and is used with hash method
656
+ # to make uniq arry of the Bio::Relation objects.
657
+ #
658
+ # a1 = Bio::Relation.new('a', 'b', 1)
659
+ # a2 = Bio::Relation.new('b', 'a', 1)
660
+ # a3 = Bio::Relation.new('b', 'c', 1)
661
+ # p [ a1, a2, a3 ].uniq
662
+ alias eql? ===
663
+
664
+ # Used by the each method to compare with another Bio::Relation object.
665
+ # This method is only usable when the edge objects have the property of
666
+ # the module Comparable.
667
+ def <=>(rel)
668
+ unless self.edge.kind_of? Comparable
669
+ raise "[Error] edges are not comparable"
670
+ end
671
+ if self.edge > rel.edge
672
+ return 1
673
+ elsif self.edge < rel.edge
674
+ return -1
675
+ elsif self.edge == rel.edge
676
+ return 0
542
677
  end
543
-
544
678
  end
545
679
 
546
- end
680
+ end # Relation
681
+
682
+ end # Bio
547
683
 
548
684
 
549
685
 
@@ -716,276 +852,3 @@ if __FILE__ == $0
716
852
 
717
853
  end
718
854
 
719
-
720
- =begin
721
-
722
- = Bio::Pathway
723
-
724
- Bio::Pathway is a general graph object initially constructed by the list of
725
- the ((<Bio::Relation>)) objects. The basic concept of the Bio::Pathway object
726
- is to store a graph as an adjacency list (in the instance variable @graph),
727
- and converting the list into an adjacency matrix by calling to_matrix method
728
- on demand. However, in some cases, it is convenient to have the original list
729
- of the ((<Bio::Relation>))s, Bio::Pathway object also stores the list (as the
730
- instance variable @relations) redundantly.
731
-
732
- Note: you can clear the @relations list by calling clear_relations! method to
733
- reduce the memory usage, and the content of the @relations can be re-generated
734
- from the @graph by to_relations method.
735
-
736
- --- Bio::Pathway.new(list, undirected = false)
737
-
738
- Generate Bio::Pathway object from the list of Bio::Relation objects.
739
- If the second argument is true, undirected graph is generated.
740
-
741
- r1 = Bio::Relation.new('a', 'b', 1)
742
- r2 = Bio::Relation.new('a', 'c', 5)
743
- r3 = Bio::Relation.new('b', 'c', 3)
744
- list = [ r1, r2, r3 ]
745
- g = Bio::Pathway.new(list, 'undirected')
746
-
747
- --- Bio::Pathway#relations
748
-
749
- Read-only accessor for the internal list of the Bio::Relation objects
750
- '@relations'.
751
-
752
- --- Bio::Pathway#graph
753
-
754
- Read-only accessor for the adjacency list of the graph.
755
-
756
- --- Bio::Pathway#index
757
-
758
- Read-only accessor for the row/column index (@index) of the adjacency
759
- matrix. Contents of the hash @index is created by calling to_matrix
760
- method.
761
-
762
- --- Bio::Pathway#label
763
-
764
- Accessor for the hash of the label assigned to the each node. You can
765
- label some of the nodes in the graph by passing a hash to the label
766
- and select subgraphs which contain labeled nodes only by subgraph method.
767
-
768
- hash = { 1 => 'red', 2 => 'green', 5 => 'black' }
769
- g.label = hash
770
- g.label
771
- g.subgraph # => new graph consists of the node 1, 2, 5 only
772
-
773
- --- Bio::Pathway#directed?
774
- --- Bio::Pathway#undirected?
775
-
776
- Returns true or false respond to the internal state of the graph.
777
-
778
- --- Bio::Pathway#directed
779
- --- Bio::Pathway#undirected
780
-
781
- Changes the internal state of the graph between 'directed' and
782
- 'undirected' and re-generate adjacency list. The undirected graph
783
- can be converted to directed graph, however, the edge between two
784
- nodes will be simply doubled to both ends.
785
- Note that these method can not be used without the list of the
786
- Bio::Relation objects (internally stored in @relations variable).
787
- Thus if you already called clear_relations! method, call
788
- to_relations first.
789
-
790
- --- Bio::Pathway#clear_relations!
791
- --- Bio::Pathway#to_relations
792
-
793
- Clear @relations array and re-generate @relations from @graph.
794
- Useful when you want to reduce the memory usage of the object.
795
-
796
- --- Bio::Pathway#to_list
797
-
798
- Generate the adjcancecy list @graph from @relations (called by
799
- initialize and in some other cases when @relations has been changed).
800
-
801
- --- Bio::Pathway#append(rel, add_rel = true)
802
-
803
- Add an Bio::Relation object 'rel' to the @graph and @relations.
804
- If the second argument is false, @relations is not modified (only
805
- useful when genarating @graph from @relations internally).
806
-
807
- --- Bio::Pathway#delete(rel)
808
-
809
- Remove an edge indicated by the Bio::Relation object 'rel' from the
810
- @graph and the @relations.
811
-
812
- --- Bio::Pathway#nodes
813
- --- Bio::Pathway#edges
814
-
815
- Returns the number of the nodes or edges in the graph.
816
-
817
- --- Bio::Pathway#to_matrix(default_value = nil, diagonal_value = nil)
818
-
819
- Returns the adjacency matrix expression of the graph as a Matrix object.
820
- If the first argument was assigned, the matrix will be filled with
821
- the given value. The second argument indicates the value of the
822
- diagonal constituents of the matrix besides the above.
823
-
824
- --- Bio::Pathway#dump_matrix(default_value = nil, diagonal_value = nil)
825
- --- Bio::Pathway#dump_list
826
-
827
- These are pretty printer of the graph. The dump_matrix method
828
- accepts the same arguments as to_matrix. Useful when you want to
829
- check the internal state of the adjacency list or the matrix (for
830
- the debug etc.) easily.
831
-
832
- --- Bio::Pathway#subgraph(list = nil)
833
-
834
- This method select some nodes and returns new Bio::Pathway object
835
- consists of selected nodes only.
836
- If the list of the nodes (as Array) is assigned as the argument,
837
- use the list to select the nodes from the graph. If no argument
838
- is assigned, internal property of the graph @label is used to select
839
- the nodes.
840
-
841
- hash = { 'a' => 'secret', 'b' => 'important', 'c' => 'important' }
842
- g.label = hash
843
- g.subgraph
844
-
845
- list = [ 'a', 'b', 'c' ]
846
- g.subgraph(list)
847
-
848
- --- Bio::Pathway#common_subgraph(graph)
849
-
850
- Not implemented yet.
851
-
852
- --- Bio::Pathway#clique
853
-
854
- Not implemented yet.
855
-
856
- --- Bio::Pathway#cliquishness(node)
857
-
858
- Calculates the value of cliquishness around the 'node'. This value
859
- indicates completeness of the edge density among the surrounded nodes.
860
-
861
- --- Bio::Pathway#small_world
862
-
863
- Calculates the frequency of the nodes having the same number of edges
864
- and returns the value as Hash.
865
-
866
- --- Bio::Pathway#breadth_first_search(root)
867
-
868
- Breadth first search solves steps and path to the each node and forms
869
- a tree contains all reachable vertices from the root node. This method
870
- returns the result in 2 hashes - 1st one shows the steps from root node
871
- and 2nd hash shows the structure of the tree.
872
-
873
- The weight of the edges are not considered in this method.
874
-
875
- --- Bio::Pathway#bfs(root)
876
-
877
- Alias for the breadth_first_search method.
878
-
879
- --- Bio::Pathway#bfs_shortest_path(node1, node2)
880
-
881
- Calculates the shortest path between two nodes by using
882
- breadth_first_search method and returns steps and the path as Array.
883
-
884
- --- Bio::Pathway#depth_first_search
885
-
886
- Depth first search yields much information about the structure of the
887
- graph especially on the classification of the edges. This method returns
888
- 5 hashes - 1st one shows the timestamps of each node containing the first
889
- discoverd time and the search finished time in an array. The 2nd, 3rd,
890
- 4th, and 5th hashes contain 'tree edges', 'back edges', 'cross edges',
891
- 'forward edges' respectively.
892
-
893
- If $DEBUG is true (e.g. ruby -d), this method prints the progression
894
- of the search.
895
-
896
- The weight of the edges are not considered in this method.
897
-
898
- --- Bio::Pathway#dfs
899
-
900
- Alias for the depth_first_search method.
901
-
902
- --- Bio::Pathway#dfs_topological_sort
903
-
904
- Topological sort of the directed acyclic graphs ("dags") by using
905
- depth_first_search.
906
-
907
- --- Bio::Pathway#dijkstra(root)
908
-
909
- Dijkstra method solves the sortest path problem in the weighted graph.
910
-
911
- --- Bio::Pathway#bellman_ford(root)
912
-
913
- Bellman-Ford method solves the single-source shortest-paths problem
914
- in the graph in which the edge weights can be negative.
915
-
916
- --- Bio::Pathway#floyd_warshall
917
-
918
- Floyd-Wardshall alogrithm solves the all-pairs shortest-paths problem
919
- on a directed graph G = (V, E).
920
-
921
- --- Bio::Pathway#floyd
922
-
923
- Alias for the floyd_warshall method.
924
-
925
- --- Bio::Pathway#kruskal
926
-
927
- Kruskal method calculates the minimam spaninng trees.
928
-
929
- --- Bio::Pathway#initialize_single_source(root)
930
-
931
- Private method used to initialize the distance by 'Infinity' and the
932
- path to the parent node by 'nil'.
933
-
934
-
935
- = Bio::Relation
936
-
937
- Bio::Relation is a simple object storing two nodes and the relation of them.
938
- The nodes and the edge (relation) can be any Ruby object. You can also
939
- compare Bio::Relation objects if the edges have Comparable property.
940
-
941
- --- Bio::Relation.new(node1, node2, edge)
942
-
943
- Create new binary relation object consists of the two object 'node1'
944
- and 'node2' with the 'edge' object as the relation of them.
945
-
946
- --- Bio::Relation#node
947
-
948
- Accessor for the @node.
949
-
950
- --- Bio::Relation#edge
951
-
952
- Accessor for the @edge.
953
-
954
- --- Bio::Relation#from
955
-
956
- Returns one node.
957
-
958
- --- Bio::Relation#to
959
-
960
- Returns another node.
961
-
962
- --- Bio::Relation#relation
963
-
964
- Returns the edge.
965
-
966
- --- Bio::Relation#===(rel)
967
-
968
- Compare with another Bio::Relation object whether havind same edges
969
- and same nodes. The == method compares Bio::Relation object's id,
970
- however this case equality === method compares the internal property
971
- of the Bio::Relation object.
972
-
973
- --- Bio::Relation#eql?(rel)
974
- --- Bio::Relation#hash
975
-
976
- Method eql? is an alias of the === method and is used with hash method
977
- to make uniq arry of the Bio::Relation objects.
978
-
979
- a1 = Bio::Relation.new('a', 'b', 1)
980
- a2 = Bio::Relation.new('b', 'a', 1)
981
- a3 = Bio::Relation.new('b', 'c', 1)
982
- p [ a1, a2, a3 ].uniq
983
-
984
- --- Bio::Relation#<=>(rel)
985
-
986
- Used by the each method to compare with another Bio::Relation object.
987
- This method is only usable when the edge objects have the property of
988
- the module Comparable.
989
-
990
- =end
991
-