<p>I'm assuming the FASTA header contains all the information you want. You can easily generate a proper bed file with Biopython:</p>

<pre><code>from Bio import SeqIO

for record in SeqIO.parse('test.fa', 'fasta'):
    lst = record.id.split(':')
    chr_, (start, end) = lst[0], lst[1].split('-')
    print('\t'.join((chr_, start, end)))
</code></pre>

<p>Note that native Python code is only marginally longer:</p>

<pre><code>with open('test.fa') as f:
    for line in f:
        if line.startswith('&gt;'):
            lst = line.rstrip().split(':')
            chr_ = lst[0].lstrip('&gt;')
            start, end = lst[1].split('-')
            print('\t'.join((chr_, start, end)))
</code></pre>

<p>Both code snippets output bed format:</p>

<pre><code>chr1    0   1000
chr1    1000    2000
chr1    2000    3000
chr1    3000    4000
</code></pre>

CC BY-SA 4.0
2018-11-14T10:04:44.823Z
2018-11-14T13:40:11.650Z
2018-11-14T13:40:11.650Z
Chris_Rands
<p>If your headers are <strong>always</strong> of the form <code>&gt;chrZ:a-b</code>, where <code>chrZ</code> is a chromosome name, <code>a</code> is a zero-indexed, half-open start position, and <code>b</code> is a zero-indexed, half-open stop position:</p>

<pre><code><span class="math-container">$ awk '($</span>0 ~ /^&gt;/){ print substr($0,2) }' in.fa | sed 's/[:|-]/\t/g' &gt; out.bed
</code></pre>

<p>If your headers contain coordinates using a different index, then you can make adjustments to <code><span class="math-container">$1</code> and <code>$</span>2</code> in the <code>awk</code> statement to create zero-indexed, half-open coordinates to export to BED, depending on the initial index.</p>

CC BY-SA 4.0
2018-11-14T01:16:34.817Z
How do I do it with biopython?
0x90
CC BY-SA 4.0
2018-11-14T01:18:44.817Z
I would not use Biopython for this. I recommend using standard Unix tools that are fast and flexible. I would not use a hammer to open a jar.
Alex Reynolds
CC BY-SA 4.0
2018-11-14T01:15:41.003Z
2018-11-14T01:18:18.107Z
2018-11-14T01:18:18.107Z
Alex Reynolds
<p>The UCSC format you linked to isn't a BED file, your method should never produce it. What you posted as your desired output is also not a BED file. Below is a BED file:</p>
<pre><code>chr1    0       1000
chr1    1000    2000
chr1    2000    3000
chr1    3000    4000
</code></pre>
<p>awk and biopython were producing the appropriate thing already. You just need to zoom in on a region in IGV. Since it's not a bigBed file, IGV won't show everything at all zoom levels.</p>
<p>As a demonstration, below is the BED file from above in IGV:</p>
<p><a href="https://i.sstatic.net/8ttlm.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/8ttlm.png" alt="enter image description here" /></a></p>

CC BY-SA 4.0
2018-11-14T00:57:28.693Z
2021-09-02T15:58:53.233Z
2021-09-02T15:58:53.233Z
Devon Ryan
<p>Assuming that you have a reference genome sequence file (e.g., <code>reference.fasta</code>) available. Getting this kind of file is straightforward.</p>

<p>1) Index the reference genome and map your reads or FASTA sequences to it (for example with bowtie2)</p>

<pre><code># index reference genome (should be precomputed)
bowtie2-build reference.fasta reference
# map reads
bowtie2 -x  reference -U file.fasta -S file.sam
# compress SAM to a BAM (binary) file
samtools view -bS file.sam &gt; file.bam
</code></pre>

<p>2) Create a BED files from the BAM file using <code>bedtools</code></p>

<pre><code># extract BED file
bedtools bamtobed -i file.bam &gt; file.bed
</code></pre>

<p>Alternatively, for sliding windows you can generate these from a reference sequence provided that you know the length of each chromosome (perhaps there is a way to extract these directly from <code>reference.fasta</code>):</p>

<pre><code># length per chromosome
samtools view -H file.bam | grep "SQ" | cut -d":" -f2-3 | sed 's/LN://' &gt; file.chr.txt
</code></pre>

<p>Create sliding windows (using only the lengths per chromosome)</p>

<pre><code># create sliding windows
bedtools makewindows -g file.chr.txt -w 1000 &gt; windows.bed
</code></pre>

CC BY-SA 4.0
2018-11-14T05:57:50.240Z
2018-11-14T05:57:50.240Z
Tom Kelly ケリー・トム
<p>Here is a fun little python script I cooked up for the occasion. It will take a standard fasta file as a command-line argument and turn it into the proper bed format. Using your example fasta:</p>

<pre><code>import pandas as pd
import sys

inFasta = sys.argv[1] # take fasta as command argument

def fastaParser(fasta):
    headers = []
    with open(fasta) as f:
        header = None
        for line in f:
            if line.startswith('&gt;'): # identifies fasta header line
                headers.append(line[1:-1]) # append all of the line that isnt &gt;
                header = line[1:] # in reset header
    newHeader = (header.replace(':',',') for header in headers) # format to be accepted later
    newnewHeader = (header.replace('-',',') for header in newHeader) # format to accept later
    bedHead = (header.split(',') for header in newnewHeader) # separate by comma from format above
    return bedHead

fastaParsed = fastaParser(inFasta) # run the function

headers = list(fastaParsed) # go from generator to list
bedfile = pd.DataFrame(headers) # create dataframe which will output bedfile

bedfile.to_csv('fastabedfile.bed', sep='\t', index=False, header=None) # output bedfile format
</code></pre>

<p>to run:</p>

<pre><code>[dkennetz@nodecn202  fasta_parser]$python fastaParser.py fakeFasta.fa

[dkennetz@nodecn202  fasta_parser]$more fastabedfile.bed
chr1    0       1000
chr1    1000    2000
chr1    2000    3000
chr1    3000    4000
</code></pre>

CC BY-SA 4.0
2018-11-14T04:33:58.760Z
2018-11-14T04:33:58.760Z
d_kennetz
<p>I have some problems in creating a .bed file for hg19, so I will be able to visualize the .bed file in IGV.</p>
<p>The .fasta file contains rows of this form:</p>
<pre><code>&gt;chr1:0-1000
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
&gt;chr1:1000-2000
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
&gt;chr1:2000-3000
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
&gt;chr1:3000-4000
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
</code></pre>
<p>I tried both with biopython:</p>
<pre><code>from Bio import SeqIO

with open(f1) as in_f, open(f1+'.seq','w') as out_f:
    for record in SeqIO.parse(in_f, 'fasta'):
        out_f.write('{}\t0\t{}\n'.format(record.id, len(record))
</code></pre>
<p>and awk:</p>
<pre><code>samtools faidx file.fasta
awk 'BEGIN {FS=&quot;\t&quot;}; {print <span class="math-container">$1 FS "0" FS $</span>2}' file.fasta.fai  &gt; file.bed
</code></pre>
<p>Both ways gave me the same output which IGV couldn't work with:</p>
<pre><code>chr1:0-1000 0   1000
chr1:1000-2000  0   1000
chr1:2000-3000  0   1000
chr1:3000-4000  0   1000
chr1:4000-5000  0   1000
chr1:5000-6000  0   1000
chr1:6000-7000  0   1000
chr1:7000-8000  0   1000
</code></pre>
<p>Now I tried to see what would be a valid .bed file format from <a href="http://genome.ucsc.edu/cgi-bin/hgTables" rel="nofollow noreferrer">UCSC</a> and the format looks different. For example:</p>
<pre><code>#bin    chrom   chromStart  chromEnd
13  chr1    39845715    39846245
19  chr1    87030756    87031903
22  chr1    111148649   111149175
22  chr1    113246065   113246628
</code></pre>
<ol>
<li>Why my methods don't output the .bed in the same format?</li>
<li>How can I make the awk/biopython methods to output a .bed file that IGV can actually load.</li>
</ol>
<p><a href="https://i.sstatic.net/H853Y.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/H853Y.png" alt="enter image description here" /></a></p>

CC BY-SA 4.0
2019-07-12T09:19:08.043Z
As @devon-ryan points out below, both of your BED format examples are incorrect. I think it would be helpful for others if you edited your question to give a correct example. See for example http://genome.ucsc.edu/FAQ/FAQformat#format1
winni2k
<fasta><samtools><bed><bedtools><igv>
How to create a .bed file from .fasta?
# How to create a .bed file from .fasta?

(Asked by: username_0 on 2018-11-14)

I have some problems in creating a .bed file for hg19, so I will be able to visualize the .bed file in IGV.
The .fasta file contains rows of this form:
>chr1:0-1000
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
>chr1:1000-2000
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
>chr1:2000-3000
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN
>chr1:3000-4000
NNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNNN

I tried both with biopython:
from Bio import SeqIO

with open(f1) as in_f, open(f1+'.seq','w') as out_f:
    for record in SeqIO.parse(in_f, 'fasta'):
        out_f.write('{}\t0\t{}\n'.format(record.id, len(record))

and awk:
samtools faidx file.fasta
awk 'BEGIN {FS="\t"}; {print $1 FS "0" FS $2}' file.fasta.fai  > file.bed

Both ways gave me the same output which IGV couldn't work with:
chr1:0-1000 0   1000
chr1:1000-2000  0   1000
chr1:2000-3000  0   1000
chr1:3000-4000  0   1000
chr1:4000-5000  0   1000
chr1:5000-6000  0   1000
chr1:6000-7000  0   1000
chr1:7000-8000  0   1000

Now I tried to see what would be a valid .bed file format from UCSC and the format looks different. For example:
#bin    chrom   chromStart  chromEnd
13  chr1    39845715    39846245
19  chr1    87030756    87031903
22  chr1    111148649   111149175
22  chr1    113246065   113246628


Why my methods don't output the .bed in the same format?
How can I make the awk/biopython methods to output a .bed file that IGV can actually load.

**Tags:** fasta, samtools, bed, bedtools, igv
> **Comments:**
> **username_1**: As @devon-ryan points out below, both of your BED format examples are incorrect. I think it would be helpful for others if you edited your question to give a correct example. See for example http://genome.ucsc.edu/FAQ/FAQformat#format1  

---

## 5 answers

### Answer by username_6 on 2018-11-14. Score: 5 | Accepted answer

Here is a fun little python script I cooked up for the occasion. It will take a standard fasta file as a command-line argument and turn it into the proper bed format. Using your example fasta:
import pandas as pd
import sys

inFasta = sys.argv[1] # take fasta as command argument

def fastaParser(fasta):
    headers = []
    with open(fasta) as f:
        header = None
        for line in f:
            if line.startswith('>'): # identifies fasta header line
                headers.append(line[1:-1]) # append all of the line that isnt >
                header = line[1:] # in reset header
    newHeader = (header.replace(':',',') for header in headers) # format to be accepted later
    newnewHeader = (header.replace('-',',') for header in newHeader) # format to accept later
    bedHead = (header.split(',') for header in newnewHeader) # separate by comma from format above
    return bedHead

fastaParsed = fastaParser(inFasta) # run the function

headers = list(fastaParsed) # go from generator to list
bedfile = pd.DataFrame(headers) # create dataframe which will output bedfile

bedfile.to_csv('fastabedfile.bed', sep='\t', index=False, header=None) # output bedfile format

to run:
[dkennetz@nodecn202  fasta_parser]$python fastaParser.py fakeFasta.fa

[dkennetz@nodecn202  fasta_parser]$more fastabedfile.bed
chr1    0       1000
chr1    1000    2000
chr1    2000    3000
chr1    3000    4000


---

### Answer by username_2 on 2018-11-14. Score: 4

I'm assuming the FASTA header contains all the information you want. You can easily generate a proper bed file with Biopython:
from Bio import SeqIO

for record in SeqIO.parse('test.fa', 'fasta'):
    lst = record.id.split(':')
    chr_, (start, end) = lst[0], lst[1].split('-')
    print('\t'.join((chr_, start, end)))

Note that native Python code is only marginally longer:
with open('test.fa') as f:
    for line in f:
        if line.startswith('>'):
            lst = line.rstrip().split(':')
            chr_ = lst[0].lstrip('>')
            start, end = lst[1].split('-')
            print('\t'.join((chr_, start, end)))

Both code snippets output bed format:
chr1    0   1000
chr1    1000    2000
chr1    2000    3000
chr1    3000    4000


---

### Answer by username_3 on 2018-11-14. Score: 3

If your headers are always of the form >chrZ:a-b, where chrZ is a chromosome name, a is a zero-indexed, half-open start position, and b is a zero-indexed, half-open stop position:
$ awk '($0 ~ /^>/){ print substr($0,2) }' in.fa | sed 's/[:|-]/\t/g' > out.bed

If your headers contain coordinates using a different index, then you can make adjustments to $1 and $2 in the awk statement to create zero-indexed, half-open coordinates to export to BED, depending on the initial index.

> **Comments:**
> **username_0**: How do I do it with biopython?  
> **username_3**: I would not use Biopython for this. I recommend using standard Unix tools that are fast and flexible. I would not use a hammer to open a jar.  

---

### Answer by username_4 on 2018-11-14. Score: 3

The UCSC format you linked to isn't a BED file, your method should never produce it. What you posted as your desired output is also not a BED file. Below is a BED file:
chr1    0       1000
chr1    1000    2000
chr1    2000    3000
chr1    3000    4000

awk and biopython were producing the appropriate thing already. You just need to zoom in on a region in IGV. Since it's not a bigBed file, IGV won't show everything at all zoom levels.
As a demonstration, below is the BED file from above in IGV:


---

### Answer by username_5 on 2018-11-14. Score: 2

Assuming that you have a reference genome sequence file (e.g., reference.fasta) available. Getting this kind of file is straightforward.
1) Index the reference genome and map your reads or FASTA sequences to it (for example with bowtie2)
# index reference genome (should be precomputed)
bowtie2-build reference.fasta reference
# map reads
bowtie2 -x  reference -U file.fasta -S file.sam
# compress SAM to a BAM (binary) file
samtools view -bS file.sam > file.bam

2) Create a BED files from the BAM file using bedtools
# extract BED file
bedtools bamtobed -i file.bam > file.bed

Alternatively, for sliding windows you can generate these from a reference sequence provided that you know the length of each chromosome (perhaps there is a way to extract these directly from reference.fasta):
# length per chromosome
samtools view -H file.bam | grep "SQ" | cut -d":" -f2-3 | sed 's/LN://' > file.chr.txt

Create sliding windows (using only the lengths per chromosome)
# create sliding windows
bedtools makewindows -g file.chr.txt -w 1000 > windows.bed


---

