Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Total Sequences 5
Total Bases 80 bp
Sequences flagged as poor quality 0
Sequence length 16
Mean sequence length 16.00
Median sequence length 16
%GC 50
>>END_MODULE
>>Per base sequence quality pass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,14 @@ <h2 id="M0"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYA
<td>Sequence length</td>
<td>16</td>
</tr>
<tr>
<td>Mean sequence length</td>
<td>16.00</td>
</tr>
<tr>
<td>Median sequence length</td>
<td>16</td>
</tr>
<tr>
<td>%GC</td>
<td>50</td>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ Total Sequences 1
Total Bases 16 bp
Sequences flagged as poor quality 0
Sequence length 16
Mean sequence length 16.00
Median sequence length 16
%GC 0
>>END_MODULE
>>Per base sequence quality pass
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -255,6 +255,14 @@ <h2 id="M0"><img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAYA
<td>Sequence length</td>
<td>16</td>
</tr>
<tr>
<td>Mean sequence length</td>
<td>16.00</td>
</tr>
<tr>
<td>Median sequence length</td>
<td>16</td>
</tr>
<tr>
<td>%GC</td>
<td>0</td>
Expand Down
63 changes: 58 additions & 5 deletions uk/ac/babraham/FastQC/Modules/BasicStats.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@

import java.awt.BorderLayout;
import java.io.IOException;
import java.util.Locale;

import javax.swing.JLabel;
import javax.swing.JPanel;
Expand All @@ -41,6 +42,9 @@ public class BasicStats extends AbstractQCModule {
private long filteredCount = 0;
private int minLength = 0;
private int maxLength = 0;
// Histogram of read lengths (over non-filtered sequences), indexed by
// length. Used to calculate the median read length.
private long [] lengthCounts = new long[0];
private long totalBases = 0;
private long gCount = 0;
private long cCount = 0;
Expand Down Expand Up @@ -74,6 +78,7 @@ public JPanel getResultsPanel() {
public void reset () {
minLength = 0;
maxLength = 0;
lengthCounts = new long[0];
gCount = 0;
cCount = 0;
aCount = 0;
Expand Down Expand Up @@ -123,6 +128,17 @@ public void processSequence(Sequence sequence) {
if (sequence.getSequence().length() > maxLength) maxLength = sequence.getSequence().length();
}

// Record the length in the histogram (used for the median).
int len = sequence.getSequence().length();
if (len+1 > lengthCounts.length) {
long [] newLengthCounts = new long[len+1];
for (int i=0;i<lengthCounts.length;i++) {
newLengthCounts[i] = lengthCounts[i];
}
lengthCounts = newLengthCounts;
}
++lengthCounts[len];

String seq = sequence.getSequence();
int seqLen = seq.length();
for (int c=0;c<seqLen;c++) {
Expand Down Expand Up @@ -157,6 +173,41 @@ public boolean ignoreInReport () {
return false;
}

// Mean read length over all non-filtered sequences. Returns 0 for an empty file.
private double meanLength () {
if (actualCount == 0) return 0;
return (double)totalBases / actualCount;
}

// Median read length over all non-filtered sequences. For an even number
// of sequences this is the mean of the two central values, rounded up.
// Returns 0 for an empty file.
private long medianLength () {
if (actualCount == 0) return 0;
if (actualCount % 2 == 1) {
return lengthAtRank(actualCount/2);
}
else {
long lo = lengthAtRank((actualCount/2) - 1);
long hi = lengthAtRank(actualCount/2);
// Integer ceiling division: rounds a halfway average (e.g. 15.5) up.
return (lo + hi + 1) / 2;
}
}

// Returns the read length at the given zero-based rank in ascending order
// of length (i.e. as if all read lengths were sorted).
private long lengthAtRank (long rank) {
long cumulative = 0;
for (int length=0;length<lengthCounts.length;length++) {
cumulative += lengthCounts[length];
if (cumulative > rank) {
return length;
}
}
return 0;
}

public static String formatLength (long originalLength) {

double length = originalLength;
Expand Down Expand Up @@ -223,8 +274,10 @@ private class ResultsTable extends AbstractTableModel {
"Total Bases",
"Sequences flagged as poor quality",
"Sequence length",
"Mean sequence length",
"Median sequence length",
"%GC",
};
};

// Sequence - Count - Percentage
public int getColumnCount() {
Expand Down Expand Up @@ -253,16 +306,16 @@ public Object getValueAt(int rowIndex, int columnIndex) {
else {
return minLength+"-"+maxLength;
}
case 7 :
case 7 : return String.format(Locale.ROOT, "%.2f", meanLength());
case 8 : return ""+medianLength();
case 9 :
if (aCount+tCount+gCount+cCount > 0) {
return ""+(((gCount+cCount)*100)/(aCount+tCount+gCount+cCount));
}
else {
return 0;
}

}
}
return null;
Expand Down