func BuildGff(sequence Sequence) []byte {
	var gffBuffer bytes.Buffer

	var versionString string
	if sequence.Meta.GffVersion != "" {
		versionString = "##gff-version " + sequence.Meta.GffVersion + "\n"
	} else {
		versionString = "##gff-version 3 \n"
	}
	gffBuffer.WriteString(versionString)

	var regionString string
	var name string
	var start string
	var end string

	if sequence.Meta.Name != "" {
		name = sequence.Meta.Name
	} else if sequence.Meta.Locus.Name != "" {
		name = sequence.Meta.Locus.Name
	} else if sequence.Meta.Accession != "" {
		name = sequence.Meta.Accession
	} else {
		name = "unknown"
	}

	if sequence.Meta.RegionStart != 0 {
		start = strconv.Itoa(sequence.Meta.RegionStart)
	} else {
		start = "1"
	}

	if sequence.Meta.RegionEnd != 0 {
		end = strconv.Itoa(sequence.Meta.RegionEnd)
	} else if sequence.Meta.Locus.SequenceLength != "" {
		reg, err := regexp.Compile("[^0-9]+")
		if err != nil {
			log.Fatal(err)
		}
		end = reg.ReplaceAllString(sequence.Meta.Locus.SequenceLength, "")
	} else {
		end = "1"
	}

	regionString = "##sequence-region " + name + " " + start + " " + end + "\n"
	gffBuffer.WriteString(regionString)

	for _, feature := range sequence.Features {
		var featureString string

		var featureName string
		if feature.Name != "" {
			featureName = feature.Name
		} else {
			featureName = sequence.Meta.Locus.Name
		}

		var featureSource string
		if feature.Source != "" {
			featureSource = feature.Source
		} else {
			featureSource = "feature"
		}

		var featureType string
		if feature.Type != "" {
			featureType = feature.Type
		} else {
			featureType = "unknown"
		}

		// Indexing starts at 1 for gff so we need to shift up from Sequence 0 index.
		featureStart := strconv.Itoa(feature.SequenceLocation.Start + 1)
		featureEnd := strconv.Itoa(feature.SequenceLocation.End)

		featureScore := feature.Score
		featureStrand := string(feature.Strand)
		featurePhase := feature.Phase
		var featureAttributes string

		keys := make([]string, 0, len(feature.Attributes))
		for key := range feature.Attributes {
			keys = append(keys, key)
		}
		sort.Strings(keys)

		for _, key := range keys {
			attributeString := key + "=" + feature.Attributes[key] + ";"
			featureAttributes += attributeString
		}

		if len(featureAttributes) > 0 {
			featureAttributes = featureAttributes[0 : len(featureAttributes)-1]
		}
		TAB := "\t"
		featureString = featureName + TAB + featureSource + TAB + featureType + TAB + featureStart + TAB + featureEnd + TAB + featureScore + TAB + featureStrand + TAB + featurePhase + TAB + featureAttributes + "\n"
		gffBuffer.WriteString(featureString)
	}

	gffBuffer.WriteString("###\n")
	gffBuffer.WriteString("##FASTA\n")
	gffBuffer.WriteString(">" + sequence.Meta.Name + "\n")

	for letterIndex, letter := range sequence.Sequence {
		letterIndex++
		if letterIndex%70 == 0 && letterIndex != 0 && letterIndex != sequence.Meta.RegionEnd {
			gffBuffer.WriteRune(letter)
			gffBuffer.WriteString("\n")
		} else {
			gffBuffer.WriteRune(letter)
		}
	}
	gffBuffer.WriteString("\n")
	return gffBuffer.Bytes()
}
// BuildGff takes an Annotated sequence and returns a byte array representing a gff to be written out.
BuildGff takes an Annotated sequence and returns a byte array representing a gff to be written out.
// BuildGff takes an Annotated sequence and returns a byte array representing a gff to be written out .
func BuildGff(sequence Sequence) []byte {
	var gffBuffer bytes.Buffer
	var versionString string
	if sequence.Meta.GffVersion != "" {
		versionString = "##gff-version " + sequence.Meta.GffVersion + "\n"
	} else {
		versionString = "##gff-version 3 \n"
	}
	gffBuffer.WriteString(versionString)
	var regionString string
	var name string
	var start string
	var end string
	if sequence.Meta.Name != "" {
		name = sequence.Meta.Name
	} else if sequence.Meta.Locus.Name != "" {
		name = sequence.Meta.Locus.Name
	} else if sequence.Meta.Accession != "" {
		name = sequence.Meta.Accession
	} else {
		name = "unknown"
	}
	if sequence.Meta.RegionStart != 0 {
		start = strconv.Itoa(sequence.Meta.RegionStart)
	} else {
		start = "1"
	}
	if sequence.Meta.RegionEnd != 0 {
		end = strconv.Itoa(sequence.Meta.RegionEnd)
	} else if sequence.Meta.Locus.SequenceLength != "" {
		reg, err := regexp.Compile("[^0-9]+")
		if err != nil {
			log.Fatal(err)
		}
		end = reg.ReplaceAllString(sequence.Meta.Locus.SequenceLength, "")
	} else {
		end = "1"
	}
	regionString = "##sequence-region " + name + " " + start + " " + end + "\n"
	gffBuffer.WriteString(regionString)
	for _, feature := range sequence.Features {
		var featureString string
		var featureName string
		if feature.Name != "" {
			featureName = feature.Name
		} else {
			featureName = sequence.Meta.Locus.Name
		}
		var featureSource string
		if feature.Source != "" {
			featureSource = feature.Source
		} else {
			featureSource = "feature"
		}
		var featureType string
		if feature.Type != "" {
			featureType = feature.Type
		} else {
			featureType = "unknown"
		}
		featureStart := strconv.Itoa(feature.SequenceLocation.Start + 1)
		featureEnd := strconv.Itoa(feature.SequenceLocation.End)
		featureScore := feature.Score
		featureStrand := string(feature.Strand)
		featurePhase := feature.Phase
		var featureAttributes string
		keys := make([]string, 0, len(feature.Attributes))
		for key := range feature.Attributes {
			keys = append(keys, key)
		}
		sort.Strings(keys)
		for _, key := range keys {
			attributeString := key + "=" + feature.Attributes[key] + ";"
			featureAttributes += attributeString
		}
		if len(featureAttributes) > 0 {
			featureAttributes = featureAttributes[0 : len(featureAttributes)-1]
		}
		TAB := "\t"
		featureString = featureName + TAB + featureSource + TAB + featureType + TAB + featureStart + TAB + featureEnd + TAB + featureScore + TAB + featureStrand + TAB + featurePhase + TAB + featureAttributes + "\n"
		gffBuffer.WriteString(featureString)
	}
	gffBuffer.WriteString("###\n")
	gffBuffer.WriteString("##FASTA\n")
	gffBuffer.WriteString(">" + sequence.Meta.Name + "\n")
	for letterIndex, letter := range sequence.Sequence {
		letterIndex++
		if letterIndex%70 == 0 && letterIndex != 0 && letterIndex != sequence.Meta.RegionEnd {
			gffBuffer.WriteRune(letter)
			gffBuffer.WriteString("\n")
		} else {
			gffBuffer.WriteRune(letter)
		}
	}
	gffBuffer.WriteString("\n")
	return gffBuffer.Bytes()
}
func BuildGff ( sequence Sequence ) [ ] byte { var gffBuffer bytes . Buffer var versionString string if sequence . Meta . GffVersion != " " { versionString = " " + sequence . Meta . GffVersion + " \n " } else { versionString = " \n " } gffBuffer . WriteString ( versionString ) var regionString string var name string var start string var end string if sequence . Meta . Name != " " { name = sequence . Meta . Name } else if sequence . Meta . Locus . Name != " " { name = sequence . Meta . Locus . Name } else if sequence . Meta . Accession != " " { name = sequence . Meta . Accession } else { name = " " } if sequence . Meta . RegionStart != 0 { start = strconv . Itoa ( sequence . Meta . RegionStart ) } else { start = " " } if sequence . Meta . RegionEnd != 0 { end = strconv . Itoa ( sequence . Meta . RegionEnd ) } else if sequence . Meta . Locus . SequenceLength != " " { reg , err := regexp . Compile ( " " ) if err != nil { log . Fatal ( err ) } end = reg . ReplaceAllString ( sequence . Meta . Locus . SequenceLength , " " ) } else { end = " " } regionString = " " + name + " " + start + " " + end + " \n " gffBuffer . WriteString ( regionString ) for _ , feature := range sequence . Features { var featureString string var featureName string if feature . Name != " " { featureName = feature . Name } else { featureName = sequence . Meta . Locus . Name } var featureSource string if feature . Source != " " { featureSource = feature . Source } else { featureSource = " " } var featureType string if feature . Type != " " { featureType = feature . Type } else { featureType = " " } featureStart := strconv . Itoa ( feature . SequenceLocation . Start + 1 ) featureEnd := strconv . Itoa ( feature . SequenceLocation . End ) featureScore := feature . Score featureStrand := string ( feature . Strand ) featurePhase := feature . Phase var featureAttributes string keys := make ( [ ] string , 0 , len ( feature . Attributes ) ) for key := range feature . Attributes { keys = append ( keys , key ) } sort . Strings ( keys ) for _ , key := range keys { attributeString := key + " " + feature . Attributes [ key ] + " " featureAttributes += attributeString } if len ( featureAttributes ) > 0 { featureAttributes = featureAttributes [ 0 : len ( featureAttributes ) - 1 ] } TAB := " \t " featureString = featureName + TAB + featureSource + TAB + featureType + TAB + featureStart + TAB + featureEnd + TAB + featureScore + TAB + featureStrand + TAB + featurePhase + TAB + featureAttributes + " \n " gffBuffer . WriteString ( featureString ) } gffBuffer . WriteString ( " \n " ) gffBuffer . WriteString ( " \n " ) gffBuffer . WriteString ( " " + sequence . Meta . Name + " \n " ) for letterIndex , letter := range sequence . Sequence { letterIndex ++ if letterIndex % 70 == 0 && letterIndex != 0 && letterIndex != sequence . Meta . RegionEnd { gffBuffer . WriteRune ( letter ) gffBuffer . WriteString ( " \n " ) } else { gffBuffer . WriteRune ( letter ) } } gffBuffer . WriteString ( " \n " ) return gffBuffer . Bytes ( ) }
BuildGff takes an Annotated sequence and returns a byte array representing a gff to be written out.
BuildGff takes an Annotated sequence and returns a byte array representing a gff to be written out .
// Indexing starts at 1 for gff so we need to shift up from Sequence 0 index.