module Bio::Ucsc::TableClassDetector

Constants

COMMON_CLASS_METHODS
PARAMETERS
RESERVED_METHODS
UPPERCASED_TABLE_PREFIX

Public Instance Methods

bed(sym, opts={:bin => true}) click to toggle source

BED: Browser Extensible Description format interval search using chrom/chromStart/chromEnd

# File lib/bio-ucsc/table_class_detector.rb, line 153
def bed(sym, opts={:bin => true})
  if opts[:bin]
    chrom_bin = "chrom = :chrom AND bin in (:bins) "
  else
    chrom_bin = "chrom = :chrom "
  end

  %!
    class #{uphead(sym)} < DBConnection
      self.table_name = "#{downhead(sym)}"
      #{delete_reserved_methods}
      #{COMMON_CLASS_METHODS}
 
      def self.with_interval(interval)
        interval = Bio::Ucsc::Gi.wrap(interval)
        where(
          "#{chrom_bin}" +
          "AND ( " +
            "(chromStart BETWEEN :zstart AND :zend)" +
            "OR (chromEnd BETWEEN :zstart AND :zend)" +
            "OR (chromStart <= :zstart AND chromEnd >= :zend) )",
          #{PARAMETERS})
      end

      def self.with_interval_excl(interval)
          interval = Bio::Ucsc::Gi.wrap(interval)
          where(
            "#{chrom_bin}" +
            "AND ( " +
              "(chromStart BETWEEN :zstart AND :zend) " +
              "AND (chromEnd BETWEEN :zstart AND :zend) )",
            #{PARAMETERS})
      end

      def self.find_first_or_all_by_interval(interval, first_all, opt)
        interval = Bio::Ucsc::Gi.wrap(interval)
        zstart = interval.zero_start
        zend   = interval.zero_end

        if opt[:partial] == true
          where =
            "#{chrom_bin}" +
            "AND ( " +
              "(chromStart BETWEEN :zstart AND :zend) " +
              "OR (chromEnd BETWEEN :zstart AND :zend) " +
              "OR (chromStart <= :zstart AND chromEnd >= :zend) )"
        else
          where =
           "#{chrom_bin}" +
           "AND ( " +
             "(chromStart BETWEEN :zstart AND :zend)" +
             "AND (chromEnd BETWEEN :zstart AND :zend))"
        end
        cond = {
          :chrom => interval.chrom,
          :bins  => Ucsc::UcscBin.bin_all(zstart, zend),
          :zstart => zstart,
          :zend => zend, }          
        self.find(first_all,
                  { :select => "*",
                    :conditions => [where, cond], })
      end
    end
  !
end
const_missing(sym) click to toggle source
# File lib/bio-ucsc/table_class_detector.rb, line 43
def const_missing(sym)
  module_eval generic(sym)
  col_names = const_get(sym).columns.map{|x|x.name}

  case
  when (["bin", "tName", "tStart", "tEnd"] - col_names).empty?
    module_eval psl(sym, :bin => true)
  when (["bin", "tName", "tStart", "tEnd"] - col_names) == ["bin"]
    module_eval psl(sym, :bin => false)

  when (["bin", "chrom", "chromStart", "chromEnd"] - col_names).empty?
    module_eval bed(sym, :bin => true)
  when (["bin", "chrom", "chromStart", "chromEnd"] - col_names) == ["bin"]
    module_eval bed(sym, :bin => false)

  when (["bin", "chrom", "txStart", "txEnd"] - col_names).empty?
    module_eval genepred(sym, :bin => true)
  when (["bin", "chrom", "txStart", "txEnd"] - col_names) == ["bin"]
    module_eval genepred(sym, :bin => false)

  when (["bin", "genoName", "genoStart", "genoEnd"] - col_names).empty?
    module_eval rmsk(sym, :bin => true)
  when (["bin", "genoName", "genoStart", "genoEnd"] - col_names) == ["bin"]
    module_eval rmsk(sym, :bin => false)
  end
  
  const_get(sym)
end
genepred(sym, opts={:bin => true}) click to toggle source

genePred: Gene and gene-prediction features interval search using chrom/txStart/txEnd

# File lib/bio-ucsc/table_class_detector.rb, line 221
def genepred(sym, opts={:bin => true})
  if opts[:bin]
    chrom_bin = "chrom = :chrom AND bin in (:bins) "
  else
    chrom_bin = "chrom = :chrom "
  end

  %!
    class #{uphead(sym)} < DBConnection
      self.table_name = "#{downhead(sym)}"
      #{delete_reserved_methods}
      #{COMMON_CLASS_METHODS} 

      def self.with_interval(interval)
       interval = Bio::Ucsc::Gi.wrap(interval)
       where(
         "#{chrom_bin}" +
         "AND ( " +
           "(txStart BETWEEN :zstart AND :zend) " +
           "OR (txEnd BETWEEN :zstart AND :zend) " +
           "OR (txStart <= :zstart AND txEnd >= :zend) )",
         #{PARAMETERS})
      end

      def self.with_interval_excl(interval)
        interval = Bio::Ucsc::Gi.wrap(interval)
        where(
          "#{chrom_bin}" +
          "AND ( " +
            "(txStart BETWEEN :zstart AND :zend) " +
            "AND  (txEnd BETWEEN :zstart AND :zend) )",
          #{PARAMETERS})
      end

      def self.find_first_or_all_by_interval(interval, first_all, opt) 
        interval = Bio::Ucsc::Gi.wrap(interval)
        zstart = interval.zero_start
        zend   = interval.zero_end
        if opt[:partial] == true
          where = 
            "#{chrom_bin}" +
            "AND ( " +
            "(txStart BETWEEN :zstart AND :zend)" +
            "OR (txEnd BETWEEN :zstart AND :zend)" +
            "OR (txStart <= :zstart AND txEnd >= :zend))"
        else
          where =
            "#{chrom_bin}" +
            "AND ( " +
            "(txStart BETWEEN :zstart AND :zend)" +
            "AND (txEnd BETWEEN :zstart AND :zend) )"
        end
        cond = {
          :chrom  => interval.chrom,
          :bins   => Bio::Ucsc::UcscBin.bin_all(zstart, zend),
          :zstart => zstart,
          :zend   => zend,
        }
        self.find(first_all,
                  { :select => "*",
                    :conditions => [where, cond], })
      end

      def exons_raw
        starts = exonStarts.split(",").map{|x|Integer(x)}
        ends = exonEnds.split(",").map{|x|Integer(x)}
        starts.zip(ends).map do |x|
          Bio::GenomicInterval.zero_based(chrom, x[0], x[1])
        end
      end

      def exons
        return @exons if @exons
        if strand == "+"
          @exons = exons_raw
        else
          @exons = exons_raw.reverse
        end
        @exons
      end

      def introns
        return @introns if @introns
        if exonCount == 1
          @introns = []
          return @introns
        end
        @introns = Array.new
        exons_raw.each_cons(2) do |ex1, ex2|
          @introns <<
            Bio::GenomicInterval.zero_based(chrom, ex1.zero_end, ex2.zero_start)
        end
        @introns = @introns.reverse if strand == "-"
        @introns
      end

      def cdses
        return @cdses if @cdses
        if cdsStart == cdsEnd # gene without CDSes
          @cdses = []
          return @cdses
        end

        cdses_exons_plus = exons_raw.reject do |x|
          x.zero_end < cdsStart || cdsEnd < x.zero_start
        end
        cdses_plus = cdses_exons_plus.map do |x|
          zstart = x.zero_start
          zstart = cdsStart if x.zero_start < cdsStart
          zend   = x.zero_end
          zend   = cdsEnd if cdsEnd < x.zero_end
          Bio::GenomicInterval.zero_based(chrom, zstart, zend)
        end
        if strand == "+"
          @cdses = cdses_plus
        else
          @cdses = cdses_plus.reverse
        end
        @cdses
      end # def cdses
      
      alias :cdss :cdses

    end # class
  ! 
end
generic(sym) click to toggle source

generic: tables without interval serarch supported also used to prefetch table column names

# File lib/bio-ucsc/table_class_detector.rb, line 74
def generic(sym)
  %!
    class #{uphead(sym)} < DBConnection
      self.table_name = "#{downhead(sym)}"
      #{delete_reserved_methods}
    end
  !
end
psl(sym, opts={:bin => true}) click to toggle source

PSL: Pattern Space Layout interval search using tName/tStart/tEnd

# File lib/bio-ucsc/table_class_detector.rb, line 85
def psl(sym, opts={:bin => true})
  if opts[:bin]
    chrom_bin = "tName = :chrom AND bin in (:bins) "
  else
    chrom_bin = "tName = :chrom "
  end

  %!
    class #{uphead(sym)} < DBConnection
      self.table_name = "#{downhead(sym)}"
      #{delete_reserved_methods}
      #{COMMON_CLASS_METHODS}

      def self.with_interval(interval)
        interval = Bio::Ucsc::Gi.wrap(interval)
        where(
          "#{chrom_bin}" +
          "AND ( " +
            "(tStart BETWEEN :zstart AND :zend) " +
            "OR (tEnd BETWEEN :zstart AND :zend) " +
            "OR (tStart <= :zstart AND tEnd >= :zend) )",
          #{PARAMETERS})
      end

      def self.with_interval_excl(interval)
        interval = Bio::Ucsc::Gi.wrap(interval)
        where(
          "#{chrom_bin}" +
          "AND ( " +
            "(tStart BETWEEN :zstart AND :zend)" +
            "AND (tEnd BETWEEN :zstart AND :zend) )",
          #{PARAMETERS})
      end

      def self.find_first_or_all_by_interval(interval, first_all, opt)
        interval = Bio::Ucsc::Gi.wrap(interval)
        zstart = interval.zero_start
        zend   = interval.zero_end

        if opt[:partial] == true
          where =
            "#{chrom_bin}" +
            "AND ( " +
              "(tStart BETWEEN :zstart AND :zend) " +
              "OR (tEnd BETWEEN :zstart AND :zend) " +
              "OR (tStart <= :zstart AND tEnd >= :zend) )"
        else
          where =
            "#{chrom_bin}" +
            "AND ( " +
              "(tStart BETWEEN :zstart AND :zend) " +
              "AND (tEnd BETWEEN :zstart AND :zend) )"
        end
        cond = {
          :chrom => interval.chrom,
          :bins  => Ucsc::UcscBin.bin_all(zstart, zend),
          :zstart => zstart,
          :zend => zend,}
        self.find(first_all,
                  { :select => "*",
                    :conditions => [where, cond], })
      end
    end
  !
end
rmsk(sym, opts={:bin => true}) click to toggle source

rmsk: Repeatmasker .out file interval search using genoName/genoStart/genoEnd

# File lib/bio-ucsc/table_class_detector.rb, line 350
def rmsk(sym, opts={:bin => true})
  if opts[:bin]
    chrom_bin = "genoName = :chrom AND bin in (:bins) "
  else
    chrom_bin = "genoName = :chrom "
  end

  %!
    class #{uphead(sym)} < DBConnection
      self.table_name = "#{downhead(sym)}"
      #{delete_reserved_methods}
      #{COMMON_CLASS_METHODS}
 
      def self.with_interval(interval)
        interval = Bio::Ucsc::Gi.wrap(interval)
        where(
          "#{chrom_bin}" +
          "AND ( " +
          "(genoStart BETWEEN :zstart AND :zend)" +
          "OR (genoEnd BETWEEN :zstart AND :zend)" +
          "OR (genoStart <= :zstart AND genoEnd >= :zend) )",
          #{PARAMETERS})
      end

      def self.with_interval_excl(interval)
        interval = Bio::Ucsc::Gi.wrap(interval)
        where(
          "#{chrom_bin}" +
          "AND ( " +
          "(genoStart BETWEEN :zstart AND :zend)" +
          "AND (genoEnd BETWEEN :zstart AND :zend) )",
          #{PARAMETERS})
      end

      def self.find_first_or_all_by_interval(interval, first_all, opt)
        interval = Bio::Ucsc::Gi.wrap(interval)
        zstart = interval.zero_start
        zend   = interval.zero_end
        if opt[:partial] == true
          where =
            "#{chrom_bin}" +
            "AND ( " +
            "(genoStart BETWEEN :zstart AND :zend) " +
            "OR (genoEnd BETWEEN :zstart AND :zend) " +
            "OR (genoStart <= :zstart AND genoEnd >= :zend) )"
        else
          where =
            "#{chrom_bin}" +
            "AND ( " +
            "(genoStart BETWEEN :zstart AND :zend) " +
            "AND (genoEnd BETWEEN :zstart AND :zend) )"
        end
        cond = {
          :chrom  => interval.chrom,
          :bins   => Bio::Ucsc::UcscBin.bin_all(zstart, zend),
          :zstart => zstart,
          :zend   => zend,
        }
        self.find(first_all,
                  { :select => "*",
                    :conditions => [where, cond], })
      end
    end
  !
end

Private Instance Methods

delete_reserved_methods() click to toggle source

This hack works only for ActiveRecord version <=3.0

# File lib/bio-ucsc/table_class_detector.rb, line 421
def delete_reserved_methods
  codes = Array.new
  unless ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR > 0
    codes << "include SafeAttributes"
    RESERVED_METHODS.each do |reserved|
      codes << "bad_attribute_names :#{reserved}"
    end
  end
  codes.join("\n")
end
downhead(sym) click to toggle source
# File lib/bio-ucsc/table_class_detector.rb, line 436
def downhead(sym)
  if UPPERCASED_TABLE_PREFIX.any?{|x|sym.to_s.start_with? x}
    sym.to_s
  else
    (sym.to_s[0..0].downcase + sym.to_s[1..-1])
  end
end
uphead(sym) click to toggle source
# File lib/bio-ucsc/table_class_detector.rb, line 432
def uphead(sym)
  (sym.to_s[0..0].upcase + sym.to_s[1..-1])
end