diff --git a/.gitignore b/.gitignore
index d54177f..ec4f674 100644
--- a/.gitignore
+++ b/.gitignore
@@ -18,7 +18,7 @@ Cargo.lock
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
-#.idea/*~
+.idea/*~
.DS_Store
env/
venv/
diff --git a/README.md b/README.md
index f1be943..2050e57 100644
--- a/README.md
+++ b/README.md
@@ -1,264 +1,41 @@
-# microBioRust
+
+
+[](https://lcrossman.github.io/microBioRust/)
+
+
+
+
+
## A Rust bioinformatics crate aimed at Microbial genomics
The aim of this crate is to provide Microbiology friendly Rust functions for bioinformatics.
-Very much under construction!
+> Very much under construction!
Some concepts with many thanks to Rust-bio
-Please see the Roadmap for futher details [here](https://github.com/LCrossman/microBioRust/issues/18)
+Please see the Roadmap for futher details [here](ROADMAP.md)
To install Rust - please see here [Rust install](https://www.rust-lang.org/tools/install) or with Conda
If you would like to contribute please follow the [Rust code of conduct](https://www.rust-lang.org/policies/code-of-conduct)
Questions and comments - please join the Discord server :) [here](https://discord.gg/xP2ngwTttz)
-Currently there is functionality for:
-
-# 1. A Genbank to GFF parser
-
-# 2. An Embl to GFF and GBK parser
-
-# 3. Calculate sequence metrics e.g. hydrophobicity, distance measures
-
-# 4. A Heatmap plot with wasm and d3.js
-
-To use a specific workspace (at the moment microSeqIO or heatmap) clone the project, cd into the specific directory required and build the project from there
-for more background please see
-
-In microBioRust:
-
-You can parse genbank files and save as a GFF (gff3) format as well as extracting DNA sequences, gene DNA sequences (ffn) and protein fasta sequences (faa)
-Super simple way:
-
-```rust
-pub fn genbank_to_faa() -> Result<(), anyhow::Error> {
- let args = Arguments::parse();
- let records = genbank!(&args.filename);
- for record in records.iter() {
- for (k, v) in &record.cds.attributes {
- if let Some(seq) = record.seq_features.get_sequence_faa(k) {
- println!(">{}|{}\n{}", &record.id, &k, seq);
- }
- }
- }
- return Ok(());
-}
-
-```
-
-Better for Debugging:
-
-```rust
-pub fn genbank_to_faa() -> Result<(), anyhow::Error> {
- let args: Vec = env::args().collect();
- let config = Config::new(&args).unwrap_or_else(|err| {
- println!("Problem with parsing file arguments: {}", err);
- process::exit(1);
- });
- let file_gbk = fs::File::open(config.filename)?;
- let mut reader = Reader::new(file_gbk);
- let mut records = reader.records();
- let mut cds_counter: u32 = 0;
- loop {
- //collect from each record advancing on a next record basis, count cds records
- match records.next() {
- Some(Ok(mut record)) => {
- for (k, v) in &record.cds.attributes {
- match record.seq_features.get_sequence_faa(&k) {
- Some(value) => {
- let seq_faa = value.to_string();
- println!(">{}|{}\n{}", &record.id, &k, seq_faa);
- }
- _ => (),
- };
- }
- cds_counter += 1;
- }
- Some(Err(e)) => {
- println!("Error encountered - an err {:?}", e);
- }
- None => {
- println!("finished iteration");
- break;
- }
- }
- }
- println!("Total records processed: {}", read_counter);
- return Ok(());
-}
-```
-
-Example to save a provided multi- or single genbank file as a GFF file (by joining any multi-genbank)
-
-```rust
-pub fn genbank_to_gff() -> io::Result<()> {
- let args: Vec = env::args().collect();
- let config = Config::new(&args).unwrap_or_else(|err| {
- println!("Problem with parsing file arguments: {}", err);
- process::exit(1);
- });
- let file_gbk = fs::File::open(&config.filename)?;
- let prev_start: u32 = 0;
- let mut prev_end: u32 = 0;
- let mut reader = Reader::new(file_gbk);
- let mut records = reader.records();
- let mut read_counter: u32 = 0;
- let mut seq_region: BTreeMap = BTreeMap::new();
- let mut record_vec: Vec = Vec::new();
- loop {
- match records.next() {
- Some(Ok(mut record)) => {
- //println!("next record");
- //println!("Record id: {:?}", record.id);
- let source = record.source_map.source_name.clone().expect("issue collecting source name");
- let beginning = match record.source_map.get_start(&source) {
- Some(value) => value.get_value(),
- _ => 0,
- };
- let ending = match record.source_map.get_stop(&source) {
- Some(value) => value.get_value(),
- _ => 0,
- };
- if ending + prev_end < beginning + prev_end {
- }
- seq_region.insert(source, (beginning + prev_end, ending + prev_end));
- record_vec.push(record);
- // Add additional fields to print if needed
- read_counter+=1;
- prev_end+=ending; // create the joined record if there are multiple
- },
- Some(Err(e)) => { println!("theres an err {:?}", e); },
- None => {
- println!("finished iteration");
- break; },
- }
- }
- let output_file = format!("{}.gff", &config.filename);
- gff_write(seq_region.clone(), record_vec, &output_file, true);
- println!("Total records processed: {}", read_counter);
- return Ok(());
-}
-```
-
-Example to create a completely new record, use of setters or set_ functionality
+Currently there is functionality for:
+````
+ 1. A Genbank to GFF parser
-To write into GFF format requires gff_write(seq_region, record_vec, filename, true or false)
+ 2. An Embl to GFF and GBK parser
-The seq_region is the region of interest to save with name and DNA coordinates such as `seqregion.entry("source_1".to_string(), (1,897))`
+ 3. Calculate sequence metrics e.g. hydrophobicity, distance measures
-This makes it possible to save the whole file or to subset it
+ 4. A Heatmap plot with wasm and d3.js
-record_vec is a list of the records. If there is only one record, include this as a vec using `vec![record]`
+````
-The boolean true/false describes whether the DNA sequence should be included in the GFF3 file
+To see more on how to use have a look at usage [here](docs/usage.md)
-To write into genbank format requires gbk_write(seq_region, record_vec, filename), no true or false since genbank format will include the DNA sequence
+To use a specific workspace (at the moment microSeqIO or heatmap) clone the project, cd into the specific directory required and build the project from there
- ```rust
-pub fn create_new_record() -> Result<(), anyhow::Error> {
- let filename = format!("new_record.gff");
- let mut record = Record::new();
- let mut seq_region: BTreeMap = BTreeMap::new();
- //example from E.coli K12
- seq_region.insert("source_1".to_string(), (1, 897));
- //Add the source into SourceAttributes
- record
- .source_map
- .set_counter("source_1".to_string())
- .set_start(RangeValue::Exact(1))
- .set_stop(RangeValue::Exact(897))
- .set_organism("Escherichia coli".to_string())
- .set_mol_type("DNA".to_string())
- .set_strain("K-12 substr. MG1655".to_string())
- .set_type_material("type strain of Escherichia coli K12".to_string())
- .set_db_xref("PRJNA57779".to_string());
- //Add the features into FeatureAttributes, here we are setting two features, i.e. coding sequences or genes
- record
- .cds
- .set_counter("b3304".to_string())
- .set_start(RangeValue::Exact(1))
- .set_stop(RangeValue::Exact(354))
- .set_gene("rplR".to_string())
- .set_product("50S ribosomal subunit protein L18".to_string())
- .set_codon_start(1)
- .set_strand(-1);
- record
- .cds
- .set_counter("b3305".to_string())
- .set_start(RangeValue::Exact(364))
- .set_stop(RangeValue::Exact(897))
- .set_gene("rplF".to_string())
- .set_product("50S ribosomal subunit protein L6".to_string())
- .set_codon_start(1)
- .set_strand(-1);
- //Add the sequences for the coding sequence (CDS) into SequenceAttributes
- record
- .seq_features
- .set_counter("b3304".to_string())
- .set_start(RangeValue::Exact(1))
- .set_stop(RangeValue::Exact(354))
- .set_sequence_ffn(
- "ATGGATAAGAAATCTGCTCGTATCCGTCGTGCGACCCGCGCACGCCGCAAGCTCCAGGAG
-CTGGGCGCAACTCGCCTGGTGGTACATCGTACCCCGCGTCACATTTACGCACAGGTAATT
-GCACCGAACGGTTCTGAAGTTCTGGTAGCTGCTTCTACTGTAGAAAAAGCTATCGCTGAA
-CAACTGAAGTACACCGGTAACAAAGACGCGGCTGCAGCTGTGGGTAAAGCTGTCGCTGAA
-CGCGCTCTGGAAAAAGGCATCAAAGATGTATCCTTTGACCGTTCCGGGTTCCAATATCAT
-GGTCGTGTCCAGGCACTGGCAGATGCTGCCCGTGAAGCTGGCCTTCAGTTCTAA"
- .to_string(),
- )
- .set_sequence_faa(
- "MDKKSARIRRATRARRKLQELGATRLVVHRTPRHIYAQVIAPNGSEVLVAASTVEKAIAE
-QLKYTGNKDAAAAVGKAVAERALEKGIKDVSFDRSGFQYHGRVQALADAAREAGLQF"
- .to_string(),
- )
- .set_codon_start(1)
- .set_strand(-1);
- record
- .seq_features
- .set_counter("bb3305".to_string())
- .set_start(RangeValue::Exact(364))
- .set_stop(RangeValue::Exact(897))
- .set_sequence_ffn(
- "ATGTCTCGTGTTGCTAAAGCACCGGTCGTTGTTCCTGCCGGCGTTGACGTAAAAATCAAC
-GGTCAGGTTATTACGATCAAAGGTAAAAACGGCGAGCTGACTCGTACTCTCAACGATGCT
-GTTGAAGTTAAACATGCAGATAATACCCTGACCTTCGGTCCGCGTGATGGTTACGCAGAC
-GGTTGGGCACAGGCTGGTACCGCGCGTGCCCTGCTGAACTCAATGGTTATCGGTGTTACC
-GAAGGCTTCACTAAGAAGCTGCAGCTGGTTGGTGTAGGTTACCGTGCAGCGGTTAAAGGC
-AATGTGATTAACCTGTCTCTGGGTTTCTCTCATCCTGTTGACCATCAGCTGCCTGCGGGT
-ATCACTGCTGAATGTCCGACTCAGACTGAAATCGTGCTGAAAGGCGCTGATAAGCAGGTG
-ATCGGCCAGGTTGCAGCGGATCTGCGCGCCTACCGTCGTCCTGAGCCTTATAAAGGCAAG
-GGTGTTCGTTACGCCGACGAAGTCGTGCGTACCAAAGAGGCTAAGAAGAAGTAA"
- .to_string(),
- )
- .set_sequence_faa(
- "MSRVAKAPVVVPAGVDVKINGQVITIKGKNGELTRTLNDAVEVKHADNTLTFGPRDGYAD
-GWAQAGTARALLNSMVIGVTEGFTKKLQLVGVGYRAAVKGNVINLSLGFSHPVDHQLPAG
-ITAECPTQTEIVLKGADKQVIGQVAADLRAYRRPEPYKGKGVRYADEVVRTKEAKKK"
- .to_string(),
- )
- .set_codon_start(1)
- .set_strand(-1);
- //Add the full sequence of the entire record into the record.sequence
- record.sequence = "TTAGAACTGAAGGCCAGCTTCACGGGCAGCATCTGCCAGTGCCTGGACACGACCATGATA
-TTGGAACCCGGAACGGTCAAAGGATACATCTTTGATGCCTTTTTCCAGAGCGCGTTCAGC
-GACAGCTTTACCCACAGCTGCAGCCGCGTCTTTGTTACCGGTGTACTTCAGTTGTTCAGC
-GATAGCTTTTTCTACAGTAGAAGCAGCTACCAGAACTTCAGAACCGTTCGGTGCAATTAC
-CTGTGCGTAAATGTGACGCGGGGTACGATGTACCACCAGGCGAGTTGCGCCCAGCTCCTG
-GAGCTTGCGGCGTGCGCGGGTCGCACGACGGATACGAGCAGATTTCTTATCCATAGTGTT
-ACCTTACTTCTTCTTAGCCTCTTTGGTACGCACGACTTCGTCGGCGTAACGAACACCCTT
-GCCTTTATAAGGCTCAGGACGACGGTAGGCGCGCAGATCCGCTGCAACCTGGCCGATCAC
-CTGCTTATCAGCGCCTTTCAGCACGATTTCAGTCTGAGTCGGACATTCAGCAGTGATACC
-CGCAGGCAGCTGATGGTCAACAGGATGAGAGAAACCCAGAGACAGGTTAATCACATTGCC
-TTTAACCGCTGCACGGTAACCTACACCAACCAGCTGCAGCTTCTTAGTGAAGCCTTCGGT
-AACACCGATAACCATTGAGTTCAGCAGGGCACGCGCGGTACCAGCCTGTGCCCAACCGTC
-TGCGTAACCATCACGCGGACCGAAGGTCAGGGTATTATCTGCATGTTTAACTTCAACAGC
-ATCGTTGAGAGTACGAGTCAGCTCGCCGTTTTTACCTTTGATCGTAATAACCTGACCGTT
-GATTTTTACGTCAACGCCGGCAGGAACAACGACCGGTGCTTTAGCAACACGAGACAT"
- .to_string();
- gff_write(seq_region, vec![record], &filename, true);
- return Ok(());
-}
-```
+For more background please see
diff --git a/docs/assets/MICROBIO B.svg b/docs/assets/MICROBIO B.svg
new file mode 100644
index 0000000..891c5bd
--- /dev/null
+++ b/docs/assets/MICROBIO B.svg
@@ -0,0 +1,190 @@
+
+
+
+
diff --git a/docs/usage.md b/docs/usage.md
index e69de29..955f35f 100644
--- a/docs/usage.md
+++ b/docs/usage.md
@@ -0,0 +1,234 @@
+In microBioRust:
+
+You can parse genbank files and save as a GFF (gff3) format as well as extracting DNA sequences, gene DNA sequences (ffn) and protein fasta sequences (faa)
+Super simple way:
+
+```rust
+pub fn genbank_to_faa() -> Result<(), anyhow::Error> {
+ let args = Arguments::parse();
+ let records = genbank!(&args.filename);
+ for record in records.iter() {
+ for (k, v) in &record.cds.attributes {
+ if let Some(seq) = record.seq_features.get_sequence_faa(k) {
+ println!(">{}|{}\n{}", &record.id, &k, seq);
+ }
+ }
+ }
+ return Ok(());
+}
+
+```
+
+Better for Debugging:
+
+```rust
+pub fn genbank_to_faa() -> Result<(), anyhow::Error> {
+ let args: Vec = env::args().collect();
+ let config = Config::new(&args).unwrap_or_else(|err| {
+ println!("Problem with parsing file arguments: {}", err);
+ process::exit(1);
+ });
+ let file_gbk = fs::File::open(config.filename)?;
+ let mut reader = Reader::new(file_gbk);
+ let mut records = reader.records();
+ let mut cds_counter: u32 = 0;
+ loop {
+ //collect from each record advancing on a next record basis, count cds records
+ match records.next() {
+ Some(Ok(mut record)) => {
+ for (k, v) in &record.cds.attributes {
+ match record.seq_features.get_sequence_faa(&k) {
+ Some(value) => {
+ let seq_faa = value.to_string();
+ println!(">{}|{}\n{}", &record.id, &k, seq_faa);
+ }
+ _ => (),
+ };
+ }
+ cds_counter += 1;
+ }
+ Some(Err(e)) => {
+ println!("Error encountered - an err {:?}", e);
+ }
+ None => {
+ println!("finished iteration");
+ break;
+ }
+ }
+ }
+ println!("Total records processed: {}", read_counter);
+ return Ok(());
+}
+```
+
+Example to save a provided multi- or single genbank file as a GFF file (by joining any multi-genbank)
+
+```rust
+pub fn genbank_to_gff() -> io::Result<()> {
+ let args: Vec = env::args().collect();
+ let config = Config::new(&args).unwrap_or_else(|err| {
+ println!("Problem with parsing file arguments: {}", err);
+ process::exit(1);
+ });
+ let file_gbk = fs::File::open(&config.filename)?;
+ let prev_start: u32 = 0;
+ let mut prev_end: u32 = 0;
+ let mut reader = Reader::new(file_gbk);
+ let mut records = reader.records();
+ let mut read_counter: u32 = 0;
+ let mut seq_region: BTreeMap = BTreeMap::new();
+ let mut record_vec: Vec = Vec::new();
+ loop {
+ match records.next() {
+ Some(Ok(mut record)) => {
+ //println!("next record");
+ //println!("Record id: {:?}", record.id);
+ let source = record.source_map.source_name.clone().expect("issue collecting source name");
+ let beginning = match record.source_map.get_start(&source) {
+ Some(value) => value.get_value(),
+ _ => 0,
+ };
+ let ending = match record.source_map.get_stop(&source) {
+ Some(value) => value.get_value(),
+ _ => 0,
+ };
+ if ending + prev_end < beginning + prev_end {
+ }
+ seq_region.insert(source, (beginning + prev_end, ending + prev_end));
+ record_vec.push(record);
+ // Add additional fields to print if needed
+ read_counter+=1;
+ prev_end+=ending; // create the joined record if there are multiple
+ },
+ Some(Err(e)) => { println!("theres an err {:?}", e); },
+ None => {
+ println!("finished iteration");
+ break; },
+ }
+ }
+ let output_file = format!("{}.gff", &config.filename);
+ gff_write(seq_region.clone(), record_vec, &output_file, true);
+ println!("Total records processed: {}", read_counter);
+ return Ok(());
+}
+```
+
+Example to create a completely new record, use of setters or set_ functionality
+
+To write into GFF format requires gff_write(seq_region, record_vec, filename, true or false)
+
+The seq_region is the region of interest to save with name and DNA coordinates such as `seqregion.entry("source_1".to_string(), (1,897))`
+
+This makes it possible to save the whole file or to subset it
+
+record_vec is a list of the records. If there is only one record, include this as a vec using `vec![record]`
+
+The boolean true/false describes whether the DNA sequence should be included in the GFF3 file
+
+To write into genbank format requires gbk_write(seq_region, record_vec, filename), no true or false since genbank format will include the DNA sequence
+
+ ```rust
+pub fn create_new_record() -> Result<(), anyhow::Error> {
+ let filename = format!("new_record.gff");
+ let mut record = Record::new();
+ let mut seq_region: BTreeMap = BTreeMap::new();
+ //example from E.coli K12
+ seq_region.insert("source_1".to_string(), (1, 897));
+ //Add the source into SourceAttributes
+ record
+ .source_map
+ .set_counter("source_1".to_string())
+ .set_start(RangeValue::Exact(1))
+ .set_stop(RangeValue::Exact(897))
+ .set_organism("Escherichia coli".to_string())
+ .set_mol_type("DNA".to_string())
+ .set_strain("K-12 substr. MG1655".to_string())
+ .set_type_material("type strain of Escherichia coli K12".to_string())
+ .set_db_xref("PRJNA57779".to_string());
+ //Add the features into FeatureAttributes, here we are setting two features, i.e. coding sequences or genes
+ record
+ .cds
+ .set_counter("b3304".to_string())
+ .set_start(RangeValue::Exact(1))
+ .set_stop(RangeValue::Exact(354))
+ .set_gene("rplR".to_string())
+ .set_product("50S ribosomal subunit protein L18".to_string())
+ .set_codon_start(1)
+ .set_strand(-1);
+ record
+ .cds
+ .set_counter("b3305".to_string())
+ .set_start(RangeValue::Exact(364))
+ .set_stop(RangeValue::Exact(897))
+ .set_gene("rplF".to_string())
+ .set_product("50S ribosomal subunit protein L6".to_string())
+ .set_codon_start(1)
+ .set_strand(-1);
+ //Add the sequences for the coding sequence (CDS) into SequenceAttributes
+ record
+ .seq_features
+ .set_counter("b3304".to_string())
+ .set_start(RangeValue::Exact(1))
+ .set_stop(RangeValue::Exact(354))
+ .set_sequence_ffn(
+ "ATGGATAAGAAATCTGCTCGTATCCGTCGTGCGACCCGCGCACGCCGCAAGCTCCAGGAG
+CTGGGCGCAACTCGCCTGGTGGTACATCGTACCCCGCGTCACATTTACGCACAGGTAATT
+GCACCGAACGGTTCTGAAGTTCTGGTAGCTGCTTCTACTGTAGAAAAAGCTATCGCTGAA
+CAACTGAAGTACACCGGTAACAAAGACGCGGCTGCAGCTGTGGGTAAAGCTGTCGCTGAA
+CGCGCTCTGGAAAAAGGCATCAAAGATGTATCCTTTGACCGTTCCGGGTTCCAATATCAT
+GGTCGTGTCCAGGCACTGGCAGATGCTGCCCGTGAAGCTGGCCTTCAGTTCTAA"
+ .to_string(),
+ )
+ .set_sequence_faa(
+ "MDKKSARIRRATRARRKLQELGATRLVVHRTPRHIYAQVIAPNGSEVLVAASTVEKAIAE
+QLKYTGNKDAAAAVGKAVAERALEKGIKDVSFDRSGFQYHGRVQALADAAREAGLQF"
+ .to_string(),
+ )
+ .set_codon_start(1)
+ .set_strand(-1);
+ record
+ .seq_features
+ .set_counter("bb3305".to_string())
+ .set_start(RangeValue::Exact(364))
+ .set_stop(RangeValue::Exact(897))
+ .set_sequence_ffn(
+ "ATGTCTCGTGTTGCTAAAGCACCGGTCGTTGTTCCTGCCGGCGTTGACGTAAAAATCAAC
+GGTCAGGTTATTACGATCAAAGGTAAAAACGGCGAGCTGACTCGTACTCTCAACGATGCT
+GTTGAAGTTAAACATGCAGATAATACCCTGACCTTCGGTCCGCGTGATGGTTACGCAGAC
+GGTTGGGCACAGGCTGGTACCGCGCGTGCCCTGCTGAACTCAATGGTTATCGGTGTTACC
+GAAGGCTTCACTAAGAAGCTGCAGCTGGTTGGTGTAGGTTACCGTGCAGCGGTTAAAGGC
+AATGTGATTAACCTGTCTCTGGGTTTCTCTCATCCTGTTGACCATCAGCTGCCTGCGGGT
+ATCACTGCTGAATGTCCGACTCAGACTGAAATCGTGCTGAAAGGCGCTGATAAGCAGGTG
+ATCGGCCAGGTTGCAGCGGATCTGCGCGCCTACCGTCGTCCTGAGCCTTATAAAGGCAAG
+GGTGTTCGTTACGCCGACGAAGTCGTGCGTACCAAAGAGGCTAAGAAGAAGTAA"
+ .to_string(),
+ )
+ .set_sequence_faa(
+ "MSRVAKAPVVVPAGVDVKINGQVITIKGKNGELTRTLNDAVEVKHADNTLTFGPRDGYAD
+GWAQAGTARALLNSMVIGVTEGFTKKLQLVGVGYRAAVKGNVINLSLGFSHPVDHQLPAG
+ITAECPTQTEIVLKGADKQVIGQVAADLRAYRRPEPYKGKGVRYADEVVRTKEAKKK"
+ .to_string(),
+ )
+ .set_codon_start(1)
+ .set_strand(-1);
+ //Add the full sequence of the entire record into the record.sequence
+ record.sequence = "TTAGAACTGAAGGCCAGCTTCACGGGCAGCATCTGCCAGTGCCTGGACACGACCATGATA
+TTGGAACCCGGAACGGTCAAAGGATACATCTTTGATGCCTTTTTCCAGAGCGCGTTCAGC
+GACAGCTTTACCCACAGCTGCAGCCGCGTCTTTGTTACCGGTGTACTTCAGTTGTTCAGC
+GATAGCTTTTTCTACAGTAGAAGCAGCTACCAGAACTTCAGAACCGTTCGGTGCAATTAC
+CTGTGCGTAAATGTGACGCGGGGTACGATGTACCACCAGGCGAGTTGCGCCCAGCTCCTG
+GAGCTTGCGGCGTGCGCGGGTCGCACGACGGATACGAGCAGATTTCTTATCCATAGTGTT
+ACCTTACTTCTTCTTAGCCTCTTTGGTACGCACGACTTCGTCGGCGTAACGAACACCCTT
+GCCTTTATAAGGCTCAGGACGACGGTAGGCGCGCAGATCCGCTGCAACCTGGCCGATCAC
+CTGCTTATCAGCGCCTTTCAGCACGATTTCAGTCTGAGTCGGACATTCAGCAGTGATACC
+CGCAGGCAGCTGATGGTCAACAGGATGAGAGAAACCCAGAGACAGGTTAATCACATTGCC
+TTTAACCGCTGCACGGTAACCTACACCAACCAGCTGCAGCTTCTTAGTGAAGCCTTCGGT
+AACACCGATAACCATTGAGTTCAGCAGGGCACGCGCGGTACCAGCCTGTGCCCAACCGTC
+TGCGTAACCATCACGCGGACCGAAGGTCAGGGTATTATCTGCATGTTTAACTTCAACAGC
+ATCGTTGAGAGTACGAGTCAGCTCGCCGTTTTTACCTTTGATCGTAATAACCTGACCGTT
+GATTTTTACGTCAACGCCGGCAGGAACAACGACCGGTGCTTTAGCAACACGAGACAT"
+ .to_string();
+ gff_write(seq_region, vec![record], &filename, true);
+ return Ok(());
+}
+```