func ParseGff(file []byte) Sequence {

	gff := string(file)
	sequence := Sequence{}

	lines := strings.Split(gff, "\n")
	metaString := lines[0:2]
	versionString := metaString[0]
	regionStringArray := strings.Split(metaString[1], " ")

	meta := Meta{}
	meta.GffVersion = strings.Split(versionString, " ")[1]
	meta.Name = regionStringArray[1] // Formally region name, but changed to name here for generality/interoperability.
	meta.RegionStart, _ = strconv.Atoi(regionStringArray[2])
	meta.RegionEnd, _ = strconv.Atoi(regionStringArray[3])
	meta.Size = meta.RegionEnd - meta.RegionStart

	var sequenceBuffer bytes.Buffer
	fastaFlag := false
	for _, line := range lines {
		if line == "##FASTA" {
			fastaFlag = true
		} else if len(line) == 0 {
			continue
		} else if line[0:2] == "##" {
			continue
		} else if fastaFlag && line[0:1] != ">" {
			// sequence.Sequence = sequence.Sequence + line
			sequenceBuffer.WriteString(line)
		} else if fastaFlag && line[0:1] == ">" {
			sequence.Description = line
		} else {
			record := Feature{}
			fields := strings.Split(line, "\t")
			record.Name = fields[0]
			record.Source = fields[1]
			record.Type = fields[2]

			// Indexing starts at 1 for gff so we need to shift down for Sequence 0 index.
			record.SequenceLocation.Start, _ = strconv.Atoi(fields[3])
			record.SequenceLocation.Start--
			record.SequenceLocation.End, _ = strconv.Atoi(fields[4])

			record.Score = fields[5]
			record.Strand = fields[6]
			record.Phase = fields[7]
			record.Attributes = make(map[string]string)
			attributes := fields[8]
			// var eqIndex int
			attributeSlice := strings.Split(attributes, ";")

			for _, attribute := range attributeSlice {
				attributeSplit := strings.Split(attribute, "=")
				key := attributeSplit[0]
				value := attributeSplit[1]
				record.Attributes[key] = value
			}
			sequence.AddFeature(record)
		}
	}
	sequence.Sequence = sequenceBuffer.String()
	sequence.Meta = meta

	return sequence
}
// ParseGff Takes in a string representing a gffv3 file and parses it into an Sequence object.
ParseGff Takes in a string representing a gffv3 file and parses it into an Sequence object.
// ParseGff Takes in a string representing a gffv3 file and parses it into an Sequence object .
func ParseGff(file []byte) Sequence {
	gff := string(file)
	sequence := Sequence{}
	lines := strings.Split(gff, "\n")
	metaString := lines[0:2]
	versionString := metaString[0]
	regionStringArray := strings.Split(metaString[1], " ")
	meta := Meta{}
	meta.GffVersion = strings.Split(versionString, " ")[1]
	meta.Name = regionStringArray[1] 
	meta.RegionStart, _ = strconv.Atoi(regionStringArray[2])
	meta.RegionEnd, _ = strconv.Atoi(regionStringArray[3])
	meta.Size = meta.RegionEnd - meta.RegionStart
	var sequenceBuffer bytes.Buffer
	fastaFlag := false
	for _, line := range lines {
		if line == "##FASTA" {
			fastaFlag = true
		} else if len(line) == 0 {
			continue
		} else if line[0:2] == "##" {
			continue
		} else if fastaFlag && line[0:1] != ">" {
			sequenceBuffer.WriteString(line)
		} else if fastaFlag && line[0:1] == ">" {
			sequence.Description = line
		} else {
			record := Feature{}
			fields := strings.Split(line, "\t")
			record.Name = fields[0]
			record.Source = fields[1]
			record.Type = fields[2]
			record.SequenceLocation.Start, _ = strconv.Atoi(fields[3])
			record.SequenceLocation.Start--
			record.SequenceLocation.End, _ = strconv.Atoi(fields[4])
			record.Score = fields[5]
			record.Strand = fields[6]
			record.Phase = fields[7]
			record.Attributes = make(map[string]string)
			attributes := fields[8]
			attributeSlice := strings.Split(attributes, ";")
			for _, attribute := range attributeSlice {
				attributeSplit := strings.Split(attribute, "=")
				key := attributeSplit[0]
				value := attributeSplit[1]
				record.Attributes[key] = value
			}
			sequence.AddFeature(record)
		}
	}
	sequence.Sequence = sequenceBuffer.String()
	sequence.Meta = meta
	return sequence
}
func ParseGff ( file [ ] byte ) Sequence { gff := string ( file ) sequence := Sequence { } lines := strings . Split ( gff , " \n " ) metaString := lines [ 0 : 2 ] versionString := metaString [ 0 ] regionStringArray := strings . Split ( metaString [ 1 ] , " " ) meta := Meta { } meta . GffVersion = strings . Split ( versionString , " " ) [ 1 ] meta . Name = regionStringArray [ 1 ] meta . RegionStart , _ = strconv . Atoi ( regionStringArray [ 2 ] ) meta . RegionEnd , _ = strconv . Atoi ( regionStringArray [ 3 ] ) meta . Size = meta . RegionEnd - meta . RegionStart var sequenceBuffer bytes . Buffer fastaFlag := false for _ , line := range lines { if line == " " { fastaFlag = true } else if len ( line ) == 0 { continue } else if line [ 0 : 2 ] == " " { continue } else if fastaFlag && line [ 0 : 1 ] != " " { sequenceBuffer . WriteString ( line ) } else if fastaFlag && line [ 0 : 1 ] == " " { sequence . Description = line } else { record := Feature { } fields := strings . Split ( line , " \t " ) record . Name = fields [ 0 ] record . Source = fields [ 1 ] record . Type = fields [ 2 ] record . SequenceLocation . Start , _ = strconv . Atoi ( fields [ 3 ] ) record . SequenceLocation . Start -- record . SequenceLocation . End , _ = strconv . Atoi ( fields [ 4 ] ) record . Score = fields [ 5 ] record . Strand = fields [ 6 ] record . Phase = fields [ 7 ] record . Attributes = make ( map [ string ] string ) attributes := fields [ 8 ] attributeSlice := strings . Split ( attributes , " " ) for _ , attribute := range attributeSlice { attributeSplit := strings . Split ( attribute , " " ) key := attributeSplit [ 0 ] value := attributeSplit [ 1 ] record . Attributes [ key ] = value } sequence . AddFeature ( record ) } } sequence . Sequence = sequenceBuffer . String ( ) sequence . Meta = meta return sequence }
ParseGff Takes in a string representing a gffv3 file and parses it into an Sequence object.
ParseGff Takes in a string representing a gffv3 file and parses it into an Sequence object .
// Formally region name, but changed to name here for generality/interoperability. // sequence.Sequence = sequence.Sequence + line // Indexing starts at 1 for gff so we need to shift down for Sequence 0 index. // var eqIndex int