예제 #1
0
파일: gff.go 프로젝트: frogs/biogo
func (self *Reader) commentMetaline(line string) (f *feat.Feature, err error) {
	// Load these into a slice in a MetaField of the Feature
	fields := strings.Split(string(line), " ")
	switch fields[0] {
	case "gff-version":
		self.Version, err = strconv.Atoi(fields[1])
		if err != nil {
			self.Version = DefaultVersion
		}
		return self.Read()
	case "source-version":
		if len(fields) > 1 {
			self.SourceVersion = strings.Join(fields[1:], " ")
			return self.Read()
		} else {
			return nil, bio.NewError("Incomplete source-version metaline", 0, fields)
		}
	case "date":
		if len(fields) > 1 {
			self.Date, err = time.Parse(self.TimeFormat, strings.Join(fields[1:], " "))
			return self.Read()
		} else {
			return nil, bio.NewError("Incomplete date metaline", 0, fields)
		}
	case "Type":
		if len(fields) > 1 {
			self.Type = bio.ParseMoltype(fields[1])
			return self.Read()
		} else {
			return nil, bio.NewError("Incomplete Type metaline", 0, fields)
		}
	case "sequence-region":
		if len(fields) > 3 {
			var start, end int
			start, err = strconv.Atoi(fields[2])
			if err != nil {
				return nil, err
			} else {
				if self.OneBased {
					start = bio.OneToZero(start)
				}
			}
			end, err = strconv.Atoi(fields[3])
			if err != nil {
				return nil, err
			}
			f = &feat.Feature{
				Meta: &feat.Feature{
					ID:    fields[1],
					Start: start,
					End:   end,
				},
			}
		} else {
			return nil, bio.NewError("Incomplete sequence-region metaline", 0, fields)
		}
	case "DNA", "RNA", "Protein":
		if len(fields) > 1 {
			var s *seq.Seq
			s, err = self.metaSequence(fields[0], fields[1])
			if err != nil {
				return
			} else {
				f = &feat.Feature{Meta: s}
			}
		} else {
			return nil, bio.NewError("Incomplete sequence metaline", 0, fields)
		}
	default:
		f = &feat.Feature{Meta: line}
	}

	return
}
예제 #2
0
파일: gff.go 프로젝트: frogs/biogo
// Read a single feature or part and return it or an error.
func (self *Reader) Read() (f *feat.Feature, err error) {
	var (
		line  string
		elems []string
		s     int8
		ok    bool
	)

	for {
		line, err = self.r.ReadString('\n')
		if err != nil {
			return
		}
		if len(line) > 0 && line[len(line)-1] == '\r' {
			line = line[:len(line)-1]
		}
		line = strings.TrimSpace(line)
		if len(line) == 0 { // ignore blank lines
			continue
		} else if strings.HasPrefix(line, "##") {
			f, err = self.commentMetaline(line[2:])
			return
		} else if line[0] != '#' { // ignore comments
			elems = strings.SplitN(line, "\t", 10)
			break
		}
	}

	if s, ok = charToStrand[elems[strandField]]; !ok {
		s = 0
	}

	startPos, se := strconv.Atoi(elems[startField])
	if se != nil {
		startPos = 0
	} else {
		if self.OneBased {
			startPos = bio.OneToZero(startPos)
		}
	}

	endPos, se := strconv.Atoi(elems[endField])
	if se != nil {
		endPos = 0
	}

	fr, se := strconv.Atoi(elems[frameField])
	if se != nil {
		fr = -1
	}

	score, se := strconv.ParseFloat(elems[scoreField], 64)
	var scorePtr *float64
	if se != nil {
		scorePtr = nil
	} else {
		scorePtr = &score
	}

	f = &feat.Feature{
		ID:       elems[nameField] + ":" + strconv.Itoa(startPos) + ".." + strconv.Itoa(endPos),
		Location: elems[nameField],
		Source:   elems[sourceField],
		Start:    startPos,
		End:      endPos,
		Feature:  elems[featureField],
		Score:    scorePtr,
		Frame:    int8(fr),
		Strand:   s,
		Moltype:  self.Type, // currently we default to bio.DNA
	}

	if len(elems) > attributeField {
		f.Attributes = elems[attributeField]
	}
	if len(elems) > commentField {
		f.Comments = elems[commentField]
	}

	return
}