]> git.donarmstrong.com Git - rsem.git/blobdiff - rsem-calculate-expression
Merge remote-tracking branch 'origin/master'
[rsem.git] / rsem-calculate-expression
index 27243140a19bc25893b75bfb38f83bf6361f028a..bc976c32269a2938cb0607dabc36157e58509ffb 100755 (executable)
@@ -45,7 +45,9 @@ my $estRSPD = 0;
 my $B = 20;
 
 my $nThreads = 1;
-my $genBamF = 0;
+my $genBamF = 1;  # default is generating transcript bam file
+my $genGenomeBamF = 0;
+my $sampling = 0;
 my $calcCI = 0;
 my $quiet = 0;
 my $help = 0;
@@ -84,7 +86,8 @@ GetOptions("keep-intermediate-files" => \$keep_intermediate_files,
           "estimate-rspd" => \$estRSPD,
           "num-rspd-bins=i" => \$B,
           "p|num-threads=i" => \$nThreads,
-          "out-bam" => \$genBamF,
+          "output-genome-bam" => \$genGenomeBamF,
+          "sampling-for-bam" => \$sampling,
           "calc-ci" => \$calcCI,
           "ci-memory=i" => \$NMB,
           "time" => \$mTime,
@@ -112,7 +115,10 @@ pod2usage(-msg => "Min fragment length should be at least 1!", -exitval => 2, -v
 pod2usage(-msg => "Min fragment length should be smaller or equal to max fragment length!", -exitval => 2, -verbose => 2) if ($minL > $maxL);
 pod2usage(-msg => "The memory allocated for calculating credibility intervals should be at least 1 MB!\n", -exitval => 2, -verbose => 2) if ($NMB < 1);
 pod2usage(-msg => "Number of threads should be at least 1!\n", -exitval => 2, -verbose => 2) if ($nThreads < 1);
-pod2usage(-msg => "Seed length should be at least 25!\n", -exitval => 2, -verbose => 2) if ($L < 25);
+pod2usage(-msg => "Seed length should be at least 5!\n", -exitval => 2, -verbose => 2) if ($L < 5);
+pod2usage(-msg => "--sampling-for-bam cannot be specified if --out-bam is not specified!\n", -exitval => 2, -verbose => 2) if ($sampling && !$genBamF);
+
+if ($L < 25) { print "Warning: the seed length set is less than 25! This is only allowed if the references are not added poly(A) tails.\n"; }
 
 if ($strand_specific) { $probF = 1.0; }
 
@@ -145,6 +151,14 @@ else {
     $sampleName = $ARGV[3];
 }
 
+if ($genGenomeBamF) {
+    open(INPUT, "$refName.ti");
+    my $line = <INPUT>; chomp($line);
+    close(INPUT);
+    my ($M, $type) = split(/ /, $line);
+    pod2usage(-msg => "No genome information provided, so genome bam file cannot be generated!\n", -exitval => 2, -verbose => 2) if ($type != 0);
+}
+
 my $pos = rindex($sampleName, '/');
 if ($pos < 0) { $sampleToken = $sampleName; }
 else { $sampleToken = substr($sampleName, $pos + 1); }
@@ -197,20 +211,13 @@ if (!$is_sam && !$is_bam) {
     }
 
     $command .= " | gzip > $imdName.sam.gz";
-    print "$command\n";
 
     if ($mTime) { $time_start = time(); }
 
-    $status = system($command);
+    &runCommand($command);
 
     if ($mTime) { $time_end = time(); $time_alignment = $time_end - $time_start; }
 
-    if ($status != 0) {
-       print "bowtie failed! Please check if you provide correct parameters/options for the pipeline!\n";
-       exit(-1);
-    }
-    print "\n";
-
     $inpF = "$imdName.sam.gz";
     $is_sam = 1; # output of bowtie is a sam file
 }
@@ -228,13 +235,7 @@ if ($fn_list ne "") { $command .= " -l $fn_list"; }
 if ($tagName ne "") { $command .= " -tag $tagName"; }
 if ($quiet) { $command .= " -q"; }
 
-print "$command\n";
-$status = system($command);
-if ($status != 0) {
-    print "rsem-parse-alignments failed! Please check if you provide correct parameters/options for the pipeline!\n";
-    exit(-1);
-}
-print "\n";
+&runCommand($command);
 
 $command = $dir."rsem-build-read-index $gap"; 
 switch($read_type) {
@@ -243,13 +244,7 @@ switch($read_type) {
     case 2  { $command .= " 0 $quiet $imdName\_alignable_1.fa $imdName\_alignable_2.fa"; }
     case 3  { $command .= " 1 $quiet $imdName\_alignable_1.fq $imdName\_alignable_2.fq"; }
 }
-print "$command\n";
-$status = system($command);
-if ($status != 0) {
-    print "rsem-build-read-index failed! Please check if you provide correct parameters/options for the pipeline!\n";
-    exit(-1);
-}
-print "\n";
+&runCommand($command);
 
 my $doesOpen = open(OUTPUT, ">$imdName.mparams");
 if ($doesOpen == 0) { print "Cannot generate $imdName.mparams!\n"; exit(-1); }
@@ -267,35 +262,27 @@ if ($genBamF) {
     $command .= " -b $samInpType $inpF";
     if ($fn_list ne "") { $command .= " 1 $fn_list"; }
     else { $command .= " 0"; }
+    if ($sampling) { $command .= " --sampling"; }
 }
 if ($calcCI) { $command .= " --gibbs-out"; }
 if ($quiet) { $command .= " -q"; }
 
-print "$command\n";
-$status = system($command);
-if ($status != 0) {
-    print "rsem-run-em failed! Please check if you provide correct parameters/options for the pipeline!\n";
-    exit(-1);
-}
-print "\n";
+&runCommand($command);
 
 if ($genBamF) {
-    $command = $dir."sam/samtools sort $sampleName.bam $sampleName.sorted";
-    print "$command\n";
-    $status = system($command);
-    if ($status != 0) {
-       print "sam/samtools sort failed! Please check if you provide correct parameters/options for the pipeline!\n";
-       exit(-1);
-    }
-    print "\n";
-    $command = $dir."sam/samtools index $sampleName.sorted.bam";
-    print "$command\n";
-    $status = system($command);
-    if ($status != 0) {
-       print "sam/samtools index failed! Please check if you provide correct parameters/options for the pipeline!\n";
-       exit(-1);
+    $command = $dir."sam/samtools sort $sampleName.transcript.bam $sampleName.transcript.sorted";
+    &runCommand($command);
+    $command = $dir."sam/samtools index $sampleName.transcript.sorted.bam";
+    &runCommand($command);
+
+    if ($genGenomeBamF) {
+       $command = $dir."rsem-tbam2gbam $refName $sampleName.transcript.bam $sampleName.genome.bam";
+       &runCommand($command);
+       $command = $dir."sam/samtools sort $sampleName.genome.bam $sampleName.genome.sorted";
+       &runCommand($command);
+       $command = $dir."sam/samtools index $sampleName.genome.sorted.bam";
+       &runCommand($command);
     }
-    print "\n";
 }
 
 &collectResults("$imdName.iso_res", "$sampleName.isoforms.results"); # isoform level
@@ -309,13 +296,7 @@ if ($calcCI) {
     $command = $dir."rsem-run-gibbs $refName $sampleName $sampleToken $BURNIN $CHAINLEN $SAMPLEGAP";
 #    $command .= " -p $nThreads";
     if ($quiet) { $command .= " -q"; }
-    print "$command\n";
-    $status = system($command);
-    if ($status != 0) {
-       print "rsem-run-gibbs failed! Please check if you provide correct parameters/options for the pipeline!\n";
-       exit(-1);
-    }
-    print "\n";
+    &runCommand($command);
 
     system("mv $sampleName.isoforms.results $imdName.isoforms.results.bak1");
     system("mv $sampleName.genes.results $imdName.genes.results.bak1");
@@ -324,13 +305,7 @@ if ($calcCI) {
 
     $command = $dir."rsem-calculate-credibility-intervals $refName $sampleName $sampleToken $CONFIDENCE $NSPC $NMB";
     if ($quiet) { $command .= " -q"; }
-    print "$command\n";
-    $status = system($command);
-    if ($status != 0) {
-       print "rsem-calculate-credibility-intervals failed! Please check if you provide correct parameters/options for the pipeline!\n";
-       exit(-1);
-    }
-    print "\n";
+    &runCommand($command);
 
     system("mv $sampleName.isoforms.results $imdName.isoforms.results.bak2");
     system("mv $sampleName.genes.results $imdName.genes.results.bak2");
@@ -343,11 +318,7 @@ if ($mTime) { $time_end = time(); $time_ci = $time_end - $time_start; }
 if ($mTime) { $time_start = time(); }
 
 if (!$keep_intermediate_files) {
-    $status = system("rm -rf $temp_dir");
-    if ($status != 0) {
-       print "Fail to delete the temporary folder!\n";
-       exit(-1);
-    }
+    &runCommand("rm -rf $temp_dir", "Fail to delete the temporary folder!");
 }
 
 if ($mTime) { $time_end = time(); }
@@ -362,11 +333,25 @@ if ($mTime) {
     close(OUTPUT);
 }
 
+# command, {err_msg}
+sub runCommand {
+    print $_[0]."\n";
+    my $status = system($_[0]);
+    if ($status != 0) { 
+       my $errmsg;
+       if (scalar(@_) > 1) { $errmsg = $_[1]; }
+       else { $errmsg = "\"$command\" failed! Plase check if you provide correct parameters/options for the pipeline!"; }
+       print $errmsg."\n";
+       exit(-1);
+    }
+    print "\n";
+}
+
 # inpF, outF
 sub collectResults {
     my $local_status;
     my ($inpF, $outF);
-    my (@results, @comment) = ();
+    my (@results, @ids) = ();
     my $line;
     my $cnt;
 
@@ -383,11 +368,11 @@ sub collectResults {
        ++$cnt;
        chomp($line);
        my @local_arr = split(/\t/, $line);
-       if ($cnt == 4) { @comment = @local_arr; }
+       if ($cnt == 4) { @ids = @local_arr; }
        else { push(@results, \@local_arr); }
     }
     
-    push(@results, \@comment);
+    push(@results, \@ids);
     close(INPUT);
 
     $local_status = open(OUTPUT, ">$outF");
@@ -479,17 +464,21 @@ RSEM reads header information from input by default. If this option is on, heade
 
 Number of threads to use. Both Bowtie and expression estimation will use this many threads. (Default: 1)
 
-=item B<--out-bam>
+=item B<--output-genome-bam>
+
+Generate a BAM file, 'sample_name.genome.bam', with alignments mapped to genomic coordinates and annotated with their posterior probabilities. In addition, RSEM will call samtools (included in RSEM package) to sort and index the bam file. 'sample_name.genome.sorted.bam' and 'sample_name.genome.sorted.bam.bai' will be generated. (Default: off)
 
-Generate a BAM file, 'sample_name.bam', with alignments mapped to genomic coordinates and annotated with their posterior probabilities. In addition, RSEM will call samtools (included in RSEM package) to sort and index the bam file. 'sample_name.sorted.bam' and 'sample_name.sorted.bam.bai' will be generated. (Default: off)
+=item B<--sampling-for-bam>
 
+When RSEM generates a BAM file, instead of outputing all alignments a read has with their posterior probabilities, one alignment is sampled and outputed according to the posterior probabilities. If the sampling result is that the read comes from the "noise" transcript, nothing is outputed. (Default: off)
 =item B<--calc-ci>
 
 Calculate 95% credibility intervals and posterior mean estimates.  (Default: off)
 
 =item B<--seed-length> <int>
 
-Seed length used by the read aligner.  Providing the correct value for this parameter is important for RSEM's accuracy if the data are single-end reads.  If RSEM runs Bowtie, it uses this value for Bowtie's seed length parameter. The minimum value is 25. Any read with its or at least one of its mates' (for paired-end reads) length less than 25 will be ignored. (Default: 25)
+Seed length used by the read aligner.  Providing the correct value is important for RSEM. If RSEM runs Bowtie, it uses this value for Bowtie's seed length parameter. Any read with its or at least one of its mates' (for paired-end reads) length less than this value will be ignored. If the references are not added poly(A) tails, the minimum allowed value is 5, otherwise, the minimum allowed value is 25. Note that this script will only check if the value >= 5 and give a warning message if the value < 25 but >= 5. (Default: 25)
 
 =item B<--tag> <string>
 
@@ -520,11 +509,11 @@ The path to the bowtie executables. (Default: the path to the bowtie executables
 Input quality scores are encoded as Phred+33. (Default: on)
 
 =item B<--phred64-quals>
-          
+
 Input quality scores are encoded as Phred+64 (default for GA Pipeline ver. >= 1.3). (Default: off)
 
 =item B<--solexa-quals>
-                             
+
 Input quality scores are solexa encoded (from GA Pipeline ver. < 1.3). (Default: off)
 
 =item B<--forward-prob> <double>
@@ -575,13 +564,15 @@ Show help information.
 
 =head1 DESCRIPTION
 
-In its default mode, this program aligns input reads against a reference transcriptome with Bowtie and calculates expression values using the alignments.  RSEM assumes the data are single-end reads with quality scores, unless the '--paired-end' or '--no-qualities' options are specified.  Users may use an alternative aligner by specifying one of the --sam and --bam options, and providing an alignment file in the specified format. However, users should make sure the alignment file satisfies the requirements mentioned in ARGUMENTS section. 
+In its default mode, this program aligns input reads against a reference transcriptome with Bowtie and calculates expression values using the alignments.  RSEM assumes the data are single-end reads with quality scores, unless the '--paired-end' or '--no-qualities' options are specified.  Users may use an alternative aligner by specifying one of the --sam and --bam options, and providing an alignment file in the specified format. However, users should make sure that they align against the indices generated by 'rsem-prepare-reference' and the alignment file satisfies the requirements mentioned in ARGUMENTS section. 
+
+One simple way to make the alignment file satisfying RSEM's requirements (assuming the aligner used put mates in a paired-end read adjacent) is to use 'convert-sam-for-rsem' script. This script only accept SAM format files as input. If a BAM format file is obtained, please use samtools to convert it to a SAM file first. For example, if '/ref/mouse_125' is the 'reference_name' and the SAM file is named 'input.sam', you can run the following command: 
 
-One simple way to make the alignment file (e.g. input.sam) satisfying RSEM's requirements (assuming the aligner used put mates in a paired-end read adjacent) is to use the following command:
+  convert-sam-for-rsem /ref/mouse_125 input.sam -o input_for_rsem.sam  
 
-  sort -k 1,1 -s input.sam > input.sorted.sam
+For details, please refer to 'convert-sam-for-rsem's documentation page.
 
-The SAM/BAM format RSEM uses is v1.3. However, it is compatible with old SAM/BAM format
+The SAM/BAM format RSEM uses is v1.4. However, it is compatible with old SAM/BAM format. However, RSEM cannot recognize 0x100 in the FLAG field. In addition, RSEM requires SEQ and QUAL are not '*'
 
 The user must run 'rsem-prepare-reference' with the appropriate reference before using this program.
 
@@ -591,7 +582,7 @@ Please note that some of the default values for the Bowtie parameters are not th
 
 The temporary directory and all intermediate files will be removed when RSEM finishes unless '--keep-intermediate-files' is specified.
 
-With the "--calc-ci" option, 95% credibility intervals and posterior mean estimates will be calculated in addition to maximum likelihood estimates.
+With the '--calc-ci' option, 95% credibility intervals and posterior mean estimates will be calculated in addition to maximum likelihood estimates.
 
 =head1 OUTPUT
 
@@ -610,26 +601,40 @@ estimation. pmc stands for posterior mean counts. ci_lower_bound(l)
 means the lower bound of the credibility intervals, ci_upper_bound(u)
 means the upper bound of the credibility intervals. So the credibility
 interval is [l, u]. 'transcript_id_list' is a space-separated list of
-transcript_ids belonging to the gene.
+transcript_ids belonging to the gene. If no gene information is
+provided, this file has the same content as
+'sample_name.isoforms.results'.
 
 =item B<sample_name.isoforms.results> 
 
 File containing isoform level expression values. The format of each
 line in this file is:
 
-transcript_id expected_counts tau_value [pmc_value tau_pme_value tau_ci_lower_bound tau_ci_upper_bound] other_attributes
+transcript_id expected_counts tau_value [pmc_value tau_pme_value tau_ci_lower_bound tau_ci_upper_bound] gene_id
 
-Fields are separated by the tab character. 'other_attributes' are all
-other attributes after attribute 'transcript_id' field in the GTF
-file. If no other attributes are given or no GTF file is provided in
-'rsem-prepare-reference', there will be no tab after the
-tau_value field.
+Fields are separated by the tab character. 'gene_id' is the gene_id of
+the gene which this transcript belongs to. If no gene information is
+provided, 'gene_id' and 'transcript_id' are the same.
 
-=item B<sample_name.bam, sample_name.sorted.bam and sample_name.sorted.bam.bai>
+=item B<sample_name.transcript.bam, sample_name.transcript.sorted.bam and sample_name.transcript.sorted.bam.bai>
 
-Only generated when --out-bam is specified.
+'sample_name.transcript.bam' is a BAM-formatted file of read
+alignments in transcript coordinates. The MAPQ field of each alignment
+is set to min(100, floor(-10 * log10(1.0 - w) + 0.5)), where w is the
+posterior probability of that alignment being the true mapping of a
+read.  In addition, RSEM pads a new tag ZW:f:value, where value is a
+single precision floating number representing the posterior
+probability.
 
-'sample_name.bam' is a BAM-formatted file of read alignments in
+'sample_name.transcript.sorted.bam' and
+'sample_name.transcript.sorted.bam.bai' are the sorted BAM file and
+indices generated by samtools (included in RSEM package).
+
+=item B<sample_name.genome.bam, sample_name.genome.sorted.bam and sample_name.genome.sorted.bam.bai>
+
+Only generated when --output-genome-bam is specified.
+
+'sample_name.genome.bam' is a BAM-formatted file of read alignments in
 genomic coordinates. Alignments of reads that have identical genomic
 coordinates (i.e., alignments to different isoforms that share the
 same genomic region) are collapsed into one alignment.  The MAPQ field
@@ -637,9 +642,11 @@ of each alignment is set to min(100, floor(-10 * log10(1.0 - w) +
 0.5)), where w is the posterior probability of that alignment being
 the true mapping of a read.  In addition, RSEM pads a new tag
 ZW:f:value, where value is a single precision floating number
-representing the posterior probability.
+representing the posterior probability. If an alignment is spliced, a
+XS:A:value tag is also added, where value is either '+' or '-'
+indicating the strand of the transcript it aligns to.
 
-'sample_name.sorted.bam' and 'sample_name.sorted.bam.bai' are the
+'sample_name.genome.sorted.bam' and 'sample_name.genome.sorted.bam.bai' are the
 sorted BAM file and indices generated by samtools (included in RSEM package).
 
 =item B<sample_name.stat>
@@ -650,56 +657,55 @@ This is a folder instead of a file. All model related statistics are stored in t
 
 =head1 EXAMPLES
 
-Assume the path to the bowtie executables is in the user's PATH environment variable. Reference files are under '/ref' with name 'mm9'. 
+Assume the path to the bowtie executables is in the user's PATH environment variable. Reference files are under '/ref' with name 'mouse_125'. 
 
-1) '/data/mmliver.fq', single-end reads with quality scores. Quality scores are encoded as for 'GA pipeline version >= 1.3'. We want to use 8 threads and generate a BAM file:
+1) '/data/mmliver.fq', single-end reads with quality scores. Quality scores are encoded as for 'GA pipeline version >= 1.3'. We want to use 8 threads and generate a genome BAM file:
 
  rsem-calculate-expression --phred64-quals \
                            -p 8 \
-                           --out-bam \
+                           --output-genome-bam \
                            /data/mmliver.fq \
-                           /ref/mm9 \
+                           /ref/mouse_125 \
                            mmliver_single_quals
 
-2) '/data/mmliver_1.fq' and '/data/mmliver_2.fq', paired-end reads with quality scores. Quality scores are in SANGER format. We want to use 8 threads and do not generate a BAM file:
+2) '/data/mmliver_1.fq' and '/data/mmliver_2.fq', paired-end reads with quality scores. Quality scores are in SANGER format. We want to use 8 threads and do not generate a genome BAM file:
 
  rsem-calculate-expression -p 8 \
                            --paired-end \
                            /data/mmliver_1.fq \
                            /data/mmliver_2.fq \
-                           /ref/mm9 \
+                           /ref/mouse_125 \
                            mmliver_paired_end_quals
 
-3) '/data/mmliver.fa', single-end reads without quality scores. We want to use 8 threads and generate a BAM file:
+3) '/data/mmliver.fa', single-end reads without quality scores. We want to use 8 threads:
 
  rsem-calculate-expression -p 8 \
                            --no-qualities \
                            /data/mmliver.fa \
-                           /ref/mm9 \
+                           /ref/mouse_125 \
                            mmliver_single_without_quals
 
-4) Data are the same as 1). We want to take a fragment length distribution into consideration. We set the fragment length mean to 150 and the standard deviation to 35. In addition to a BAM file, we also want to generate credibility intervals.  We allow RSEM to use 1GB of memory for CI calculation.
+4) Data are the same as 1). We want to take a fragment length distribution into consideration. We set the fragment length mean to 150 and the standard deviation to 35. In addition to a BAM file, we also want to generate credibility intervals.  We allow RSEM to use 1GB of memory for CI calculation:
 
  rsem-calculate-expression --bowtie-path /sw/bowtie \
                            --phred64-quals \
                            --fragment-length-mean 150.0 \
                            --fragment-length-sd 35.0 \
                            -p 8 \
-                           --out-bam \
+                           --output-genome-bam \
                            --calc-ci \
                            --ci-memory 1024 \
                            /data/mmliver.fq \
-                           /ref/mm9 \
+                           /ref/mouse_125 \
                            mmliver_single_quals
 
-5) '/data/mmliver_paired_end_quals.bam', paired-end reads with quality scores.  We want to use 8 threads and do not generate a BAM file:
+5) '/data/mmliver_paired_end_quals.bam', paired-end reads with quality scores.  We want to use 8 threads:
 
  rsem-calculate-expression --paired-end \
                            --bam \
                            -p 8 \
                            /data/mmliver_paired_end_quals.bam \
-                           /ref/mm9 \
+                           /ref/mouse_125 \
                            mmliver_paired_end_quals
 
 =cut
-