From ktym at hgc.jp Mon Feb 6 09:41:52 2006 From: ktym at hgc.jp (Toshiaki Katayama) Date: Mon, 6 Feb 2006 23:41:52 +0900 Subject: [BioRuby] New Bio::Sequence organization (Re: (no subject) In-Reply-To: References: <20060131073057.GA15105@thebird.nl> Message-ID: Hi, I have changed subseq method to raise exception as Pjotr suggested. lib/bio/sequence.rb is largely refactord after the BioRuby 0.7.1 release and is now split into several pieces under the lib/bio/sequence/ directory. Bio::Sequence is now became a container of rich sequence annotations and stores the sequence itself in @seq instance variable. This will enable users (including Jan Aerts) to write format converter etc. Bio::Sequence::Format module will do the job when our implementation is finished. Several common methods for NA and AA (previously in the Bio::Sequence class) are separated into the module Bio::Sequence::Common, and lib/bio/sequence/na.rb and aa.rb include this module. I think the APIs of Bio::Sequence::NA and AA are not affected by this change. Bio::Sequence::Generic is a new simple object to store an intact string like gapped sequence or case conscious sequence mainly for alignment (Bio::Sequence::NA or AA removes non alphabet chars in contrast). Toshiaki On 2006/02/01, at 2:25, Moses Hohman wrote: > Hi Pjotr, > > I completely agree. We should throw an exception. > > Moses > > On Jan 31, 2006, at 1:30 AM, Pjotr Prins wrote: > >> Dear all, >> >> In the tutorial we write: >> >> So when using String methods, you should subtract 1 from positions >> conventionally used in biology. (subseq method returns nil if you >> specify positions smaller than or equal to 0 for either one of the >> "from" or "to".) >> >> and I added: >> >> (EDITOR'S NOTE: should 'subseq' not throw an exception instead?) >> >> Can someone state what is the preferred design? I personally think an >> exception should be thrown to warn a programmer something is wrong - >> i.e. this is an exceptional situation ;-). Returning a nil may lead to >> nicer looking loops, but it does not help writing good programs. >> >> Regarding the exception vs return code issue, I think Martin Fowler's >> Refactoring says all that need to be said : >> >> - Returning an error code to indicate an error is a code smell because >> you could miss the error checking >> (http://www.refactoring.com/catalog/...hException.html) >> >> - Throwing an exception on a condition the caller could have checked >> first is another code smell because it makes the caller code hard >> to read >> (http://www.refactoring.com/catalog/...onWithTest.html) >> >> Pj. >> _______________________________________________ >> BioRuby mailing list >> BioRuby at lists.open-bio.org >> http://lists.open-bio.org/mailman/listinfo/bioruby >> > From jan.aerts at bbsrc.ac.uk Wed Feb 8 11:46:56 2006 From: jan.aerts at bbsrc.ac.uk (jan aerts (RI)) Date: Wed, 8 Feb 2006 16:46:56 -0000 Subject: [BioRuby] Map objects => comparable Message-ID: <84DA9D8AC9B05F4B889E7C70238CB451030DAB6C@rie2ksrv1.ri.bbsrc.ac.uk> Hi all, I've just looked into creating a simple Map object (could hold data for linkage maps, RH maps and the like). However, being rather new to ruby, I bump into what probably turns out to be a simple problem. I originally thought of creating a SimpleMap and Marker class, each containing a @mappings array. However, this gave problems when implementing a sensible <=> method in the Marker class (to be able to use Comparable mixin). The reason is that a single marker can be mapped to different maps, and I couldn't see a way to traverse only those mappings for a marker that would go to a certain map. Therefore, I included a Mapping class, which would provide the link between maps and markers and in which a sane <=> method could be written. Result: it looks like these three classes work nicely together (see test-code below: I can sort markers on position within a given map, or print the last marker on the map). However, I think that this setting does not make it possible to do a between? or '>' between mappings... Could I ask anyone to take a look at the code below and tell me how to use/alter it to be able to: * Test if a marker is located upstream of another marker (e.g. based on the '<'-method from the Comparable mixin) * Test is a marker is between two other markers (e.g. based on the 'between?'-method from the Comparable mixin; in the code example below: test if my_marker3 lies between my_marker1 and my_marker2 on my_map1) Explanation of setup of maps/markers: # One marker can be mapped to different maps. (<= this is what's giving the problem) # For each marker that is mapped to a map, or map that gets a marker added, basically two things happen: a mapping is added to the Marker object as well as to the SimpleMap object Many thanks, jan. module Bio module Map # This class handles the essential storage of name, species, type and units of a map. class SimpleMap include Enumerable # Builds a new Bio::Map::SimpleMap object def initialize (name = nil, species = nil, units = nil, type = nil) @name, @species, @units, @type = name, species, units, type @mappings = Array.new() end attr_accessor :name, :species, :units, :type, :mappings # Add a MappedMarker object to the map def add_mapping(marker, position) unless marker.kind_of?(Bio::Map::Marker) raise "[Error] marker is not a Bio::Map::Marker object" end my_mapping = Bio::Map::Mapping.new(self, marker, position) @mappings.push(my_mapping) unless marker.mapped_to?(self) marker.mappings.push(my_mapping) end end # Check whether a Bio::Map::Marker is mapped to this Bio::Map::SimpleMap. def contains?(marker) contains = false @mappings.each do |mapping| if mapping.marker == marker contains = true return contains end end return contains end # Go through all Bio::Map::Mapping objects linked to this Bio::Map::SimpleMap. def each @mappings.each do |mapping| yield mapping end end end # SimpleMap # This class represents the link between SimpleMap and Marker class Mapping include Comparable def initialize (map, marker, position) @map, @marker, @position = map, marker, position end attr_accessor :map, :marker, :position # To get comparable working... def <=>(other) unless self.position.kind_of?(Comparable) raise "[Error] markers are not comparable" end if self.position > other.position return 1 elsif self.position < other.position return -1 elsif self.position == other.position return 0 end end end # Mapping # This class handles markers that are anchored to Bio::Map::SimpleMap. class Marker include Enumerable def initialize(name) @name = name @mappings = Array.new() end attr_accessor :name, :mappings # Add a new map and position for this marker def add_mapping (map, position) unless map.kind_of?(Bio::Map::SimpleMap) raise "[Error] map is not a Bio::Map::SimpleMap object" end my_mapping = Bio::Map::Mapping.new(map, self, position) @mappings.push(my_mapping) unless map.contains?(self) map.mappings.push(my_mapping) end end # Check whether this Bio::Map::Marker is mapped to a given Bio::Map::SimpleMap def mapped_to?(map) mapped = false @mappings.each do |mapping| if mapping.map == map mapped = true return mapped end end return mapped end # Go through all Mapping objects linked to this map. def each @mappings.each do |mapping| yield mapping end end end # MappedMarker end # Map end # Bio if __FILE__ == $0 my_marker1 = Bio::Map::Marker.new('marker1') my_marker2 = Bio::Map::Marker.new('marker2') my_marker3 = Bio::Map::Marker.new('marker3') my_map1 = Bio::Map::SimpleMap.new('RH_map_ABC (2006)', 'BTA', 'cR', 'RH') my_map2 = Bio::Map::SimpleMap.new('consensus', 'GGA', 'cM', 'linkage') my_map1.add_mapping(my_marker1, 17) my_map1.add_mapping(my_marker2, 5) my_marker3.add_mapping(my_map1, 9) my_marker3.add_mapping(my_map2, 53) my_map1.sort.each do |mapping| puts mapping.map.name + "\t" + mapping.marker.name + "\t" + mapping.position.to_s end puts my_map1.min.marker.name my_map2.each do |mapping| puts mapping.map.name + "\t" + mapping.marker.name + "\t" + mapping.position.to_s end # p my_map1.between?(my_mappable2,my_mappable3) # p my_map1.between?(my_mappable,my_mappable2) end ---------The obligatory disclaimer-------- The information contained in this e-mail (including any attachments) is confidential and is intended for the use of the addressee only. The opinions expressed within this e-mail (including any attachments) are the opinions of the sender and do not necessarily constitute those of Roslin Institute (Edinburgh) ("the Institute") unless specifically stated by a sender who is duly authorised to do so on behalf of the Institute. From pjotr2006 at thebird.nl Fri Feb 17 05:01:23 2006 From: pjotr2006 at thebird.nl (Pjotr Prins) Date: Fri, 17 Feb 2006 11:01:23 +0100 Subject: [BioRuby] New Bio::Sequence organization In-Reply-To: <20060217093830.GA16638@thebird.nl> References: <20060217093830.GA16638@thebird.nl> Message-ID: <20060217100123.GA16829@thebird.nl> Forget that... Brain dead this morning. On Fri, Feb 17, 2006 at 10:38:30AM +0100, wrk wrote: > Interesting bug - current CVS of BioRuby. First is OK, other one not: > > bioruby> seq = Bio::Sequence::NA.new("atgcatgcaaaa") > bioruby> puts seq.complement > ttttgcatgcat > bioruby> seq = Bio::Sequence::NA.new("at") > bioruby> puts seq.complement > at > From pjotr2006 at thebird.nl Fri Feb 17 04:38:30 2006 From: pjotr2006 at thebird.nl (Pjotr Prins) Date: Fri, 17 Feb 2006 10:38:30 +0100 Subject: [BioRuby] New Bio::Sequence organization Message-ID: <20060217093830.GA16638@thebird.nl> Interesting bug - current CVS of BioRuby. First is OK, other one not: bioruby> seq = Bio::Sequence::NA.new("atgcatgcaaaa") bioruby> puts seq.complement ttttgcatgcat bioruby> seq = Bio::Sequence::NA.new("at") bioruby> puts seq.complement at From ktym at hgc.jp Mon Feb 27 13:25:38 2006 From: ktym at hgc.jp (Toshiaki Katayama) Date: Tue, 28 Feb 2006 03:25:38 +0900 Subject: [BioRuby] BioRuby 1.0.0 released Message-ID: <623469FD-0FEF-465E-9F6C-AFDDF72D068B@hgc.jp> Hi, We have released BioRuby 1.0.0 with ChemRuby 1.0.0 as a result of one year grant funded by IPA. http://bioruby.org/archive/bioruby-1.0.0.tar.gz http://chemruby.org/archive/chemruby-1.0.0.tar.gz One of the major development is the BioRuby shell, a CUI for BioRuby. % bioruby test bioruby> demo will show you some features of the shell. We have done the Japanese tutorial on BioRuby shell but that part is not yet translated in English (sorry). Another large development is a number of unit tests. You can test the BioRuby by % ruby install.rb config % ruby install.rb setup % ruby install.rb test before installing. If you found any errors or problems, please let us know. There were some incompatible changes in the library, so if you are trying to upgrade, please take a look on the "bioruby-1.0.0/doc/Changes-0.7.rd" file. We will continue to develop the library and your contributions are always welcome! Some future plans: * English documentation (please help us!) * Change license from LGPL to Ruby's * HTTP proxy support (by open-uri?) * Better supports on Bio::DAS, Bio::GFF, Bio::SQL * Utilization of Bio::Sequence as the format converter * Improvement of shell with Rails * Cooperation with ChemRuby * Additional tests From ktym at hgc.jp Mon Feb 6 14:41:52 2006 From: ktym at hgc.jp (Toshiaki Katayama) Date: Mon, 6 Feb 2006 23:41:52 +0900 Subject: [BioRuby] New Bio::Sequence organization (Re: (no subject) In-Reply-To: References: <20060131073057.GA15105@thebird.nl> Message-ID: Hi, I have changed subseq method to raise exception as Pjotr suggested. lib/bio/sequence.rb is largely refactord after the BioRuby 0.7.1 release and is now split into several pieces under the lib/bio/sequence/ directory. Bio::Sequence is now became a container of rich sequence annotations and stores the sequence itself in @seq instance variable. This will enable users (including Jan Aerts) to write format converter etc. Bio::Sequence::Format module will do the job when our implementation is finished. Several common methods for NA and AA (previously in the Bio::Sequence class) are separated into the module Bio::Sequence::Common, and lib/bio/sequence/na.rb and aa.rb include this module. I think the APIs of Bio::Sequence::NA and AA are not affected by this change. Bio::Sequence::Generic is a new simple object to store an intact string like gapped sequence or case conscious sequence mainly for alignment (Bio::Sequence::NA or AA removes non alphabet chars in contrast). Toshiaki On 2006/02/01, at 2:25, Moses Hohman wrote: > Hi Pjotr, > > I completely agree. We should throw an exception. > > Moses > > On Jan 31, 2006, at 1:30 AM, Pjotr Prins wrote: > >> Dear all, >> >> In the tutorial we write: >> >> So when using String methods, you should subtract 1 from positions >> conventionally used in biology. (subseq method returns nil if you >> specify positions smaller than or equal to 0 for either one of the >> "from" or "to".) >> >> and I added: >> >> (EDITOR'S NOTE: should 'subseq' not throw an exception instead?) >> >> Can someone state what is the preferred design? I personally think an >> exception should be thrown to warn a programmer something is wrong - >> i.e. this is an exceptional situation ;-). Returning a nil may lead to >> nicer looking loops, but it does not help writing good programs. >> >> Regarding the exception vs return code issue, I think Martin Fowler's >> Refactoring says all that need to be said : >> >> - Returning an error code to indicate an error is a code smell because >> you could miss the error checking >> (http://www.refactoring.com/catalog/...hException.html) >> >> - Throwing an exception on a condition the caller could have checked >> first is another code smell because it makes the caller code hard >> to read >> (http://www.refactoring.com/catalog/...onWithTest.html) >> >> Pj. >> _______________________________________________ >> BioRuby mailing list >> BioRuby at lists.open-bio.org >> http://lists.open-bio.org/mailman/listinfo/bioruby >> > From jan.aerts at bbsrc.ac.uk Wed Feb 8 16:46:56 2006 From: jan.aerts at bbsrc.ac.uk (jan aerts (RI)) Date: Wed, 8 Feb 2006 16:46:56 -0000 Subject: [BioRuby] Map objects => comparable Message-ID: <84DA9D8AC9B05F4B889E7C70238CB451030DAB6C@rie2ksrv1.ri.bbsrc.ac.uk> Hi all, I've just looked into creating a simple Map object (could hold data for linkage maps, RH maps and the like). However, being rather new to ruby, I bump into what probably turns out to be a simple problem. I originally thought of creating a SimpleMap and Marker class, each containing a @mappings array. However, this gave problems when implementing a sensible <=> method in the Marker class (to be able to use Comparable mixin). The reason is that a single marker can be mapped to different maps, and I couldn't see a way to traverse only those mappings for a marker that would go to a certain map. Therefore, I included a Mapping class, which would provide the link between maps and markers and in which a sane <=> method could be written. Result: it looks like these three classes work nicely together (see test-code below: I can sort markers on position within a given map, or print the last marker on the map). However, I think that this setting does not make it possible to do a between? or '>' between mappings... Could I ask anyone to take a look at the code below and tell me how to use/alter it to be able to: * Test if a marker is located upstream of another marker (e.g. based on the '<'-method from the Comparable mixin) * Test is a marker is between two other markers (e.g. based on the 'between?'-method from the Comparable mixin; in the code example below: test if my_marker3 lies between my_marker1 and my_marker2 on my_map1) Explanation of setup of maps/markers: # One marker can be mapped to different maps. (<= this is what's giving the problem) # For each marker that is mapped to a map, or map that gets a marker added, basically two things happen: a mapping is added to the Marker object as well as to the SimpleMap object Many thanks, jan. module Bio module Map # This class handles the essential storage of name, species, type and units of a map. class SimpleMap include Enumerable # Builds a new Bio::Map::SimpleMap object def initialize (name = nil, species = nil, units = nil, type = nil) @name, @species, @units, @type = name, species, units, type @mappings = Array.new() end attr_accessor :name, :species, :units, :type, :mappings # Add a MappedMarker object to the map def add_mapping(marker, position) unless marker.kind_of?(Bio::Map::Marker) raise "[Error] marker is not a Bio::Map::Marker object" end my_mapping = Bio::Map::Mapping.new(self, marker, position) @mappings.push(my_mapping) unless marker.mapped_to?(self) marker.mappings.push(my_mapping) end end # Check whether a Bio::Map::Marker is mapped to this Bio::Map::SimpleMap. def contains?(marker) contains = false @mappings.each do |mapping| if mapping.marker == marker contains = true return contains end end return contains end # Go through all Bio::Map::Mapping objects linked to this Bio::Map::SimpleMap. def each @mappings.each do |mapping| yield mapping end end end # SimpleMap # This class represents the link between SimpleMap and Marker class Mapping include Comparable def initialize (map, marker, position) @map, @marker, @position = map, marker, position end attr_accessor :map, :marker, :position # To get comparable working... def <=>(other) unless self.position.kind_of?(Comparable) raise "[Error] markers are not comparable" end if self.position > other.position return 1 elsif self.position < other.position return -1 elsif self.position == other.position return 0 end end end # Mapping # This class handles markers that are anchored to Bio::Map::SimpleMap. class Marker include Enumerable def initialize(name) @name = name @mappings = Array.new() end attr_accessor :name, :mappings # Add a new map and position for this marker def add_mapping (map, position) unless map.kind_of?(Bio::Map::SimpleMap) raise "[Error] map is not a Bio::Map::SimpleMap object" end my_mapping = Bio::Map::Mapping.new(map, self, position) @mappings.push(my_mapping) unless map.contains?(self) map.mappings.push(my_mapping) end end # Check whether this Bio::Map::Marker is mapped to a given Bio::Map::SimpleMap def mapped_to?(map) mapped = false @mappings.each do |mapping| if mapping.map == map mapped = true return mapped end end return mapped end # Go through all Mapping objects linked to this map. def each @mappings.each do |mapping| yield mapping end end end # MappedMarker end # Map end # Bio if __FILE__ == $0 my_marker1 = Bio::Map::Marker.new('marker1') my_marker2 = Bio::Map::Marker.new('marker2') my_marker3 = Bio::Map::Marker.new('marker3') my_map1 = Bio::Map::SimpleMap.new('RH_map_ABC (2006)', 'BTA', 'cR', 'RH') my_map2 = Bio::Map::SimpleMap.new('consensus', 'GGA', 'cM', 'linkage') my_map1.add_mapping(my_marker1, 17) my_map1.add_mapping(my_marker2, 5) my_marker3.add_mapping(my_map1, 9) my_marker3.add_mapping(my_map2, 53) my_map1.sort.each do |mapping| puts mapping.map.name + "\t" + mapping.marker.name + "\t" + mapping.position.to_s end puts my_map1.min.marker.name my_map2.each do |mapping| puts mapping.map.name + "\t" + mapping.marker.name + "\t" + mapping.position.to_s end # p my_map1.between?(my_mappable2,my_mappable3) # p my_map1.between?(my_mappable,my_mappable2) end ---------The obligatory disclaimer-------- The information contained in this e-mail (including any attachments) is confidential and is intended for the use of the addressee only. The opinions expressed within this e-mail (including any attachments) are the opinions of the sender and do not necessarily constitute those of Roslin Institute (Edinburgh) ("the Institute") unless specifically stated by a sender who is duly authorised to do so on behalf of the Institute. From pjotr2006 at thebird.nl Fri Feb 17 10:01:23 2006 From: pjotr2006 at thebird.nl (Pjotr Prins) Date: Fri, 17 Feb 2006 11:01:23 +0100 Subject: [BioRuby] New Bio::Sequence organization In-Reply-To: <20060217093830.GA16638@thebird.nl> References: <20060217093830.GA16638@thebird.nl> Message-ID: <20060217100123.GA16829@thebird.nl> Forget that... Brain dead this morning. On Fri, Feb 17, 2006 at 10:38:30AM +0100, wrk wrote: > Interesting bug - current CVS of BioRuby. First is OK, other one not: > > bioruby> seq = Bio::Sequence::NA.new("atgcatgcaaaa") > bioruby> puts seq.complement > ttttgcatgcat > bioruby> seq = Bio::Sequence::NA.new("at") > bioruby> puts seq.complement > at > From pjotr2006 at thebird.nl Fri Feb 17 09:38:30 2006 From: pjotr2006 at thebird.nl (Pjotr Prins) Date: Fri, 17 Feb 2006 10:38:30 +0100 Subject: [BioRuby] New Bio::Sequence organization Message-ID: <20060217093830.GA16638@thebird.nl> Interesting bug - current CVS of BioRuby. First is OK, other one not: bioruby> seq = Bio::Sequence::NA.new("atgcatgcaaaa") bioruby> puts seq.complement ttttgcatgcat bioruby> seq = Bio::Sequence::NA.new("at") bioruby> puts seq.complement at From ktym at hgc.jp Mon Feb 27 18:25:38 2006 From: ktym at hgc.jp (Toshiaki Katayama) Date: Tue, 28 Feb 2006 03:25:38 +0900 Subject: [BioRuby] BioRuby 1.0.0 released Message-ID: <623469FD-0FEF-465E-9F6C-AFDDF72D068B@hgc.jp> Hi, We have released BioRuby 1.0.0 with ChemRuby 1.0.0 as a result of one year grant funded by IPA. http://bioruby.org/archive/bioruby-1.0.0.tar.gz http://chemruby.org/archive/chemruby-1.0.0.tar.gz One of the major development is the BioRuby shell, a CUI for BioRuby. % bioruby test bioruby> demo will show you some features of the shell. We have done the Japanese tutorial on BioRuby shell but that part is not yet translated in English (sorry). Another large development is a number of unit tests. You can test the BioRuby by % ruby install.rb config % ruby install.rb setup % ruby install.rb test before installing. If you found any errors or problems, please let us know. There were some incompatible changes in the library, so if you are trying to upgrade, please take a look on the "bioruby-1.0.0/doc/Changes-0.7.rd" file. We will continue to develop the library and your contributions are always welcome! Some future plans: * English documentation (please help us!) * Change license from LGPL to Ruby's * HTTP proxy support (by open-uri?) * Better supports on Bio::DAS, Bio::GFF, Bio::SQL * Utilization of Bio::Sequence as the format converter * Improvement of shell with Rails * Cooperation with ChemRuby * Additional tests