2
* Copyright Copyright 2010-12 Simon Andrews
4
* This file is part of FastQC.
6
* FastQC is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; either version 3 of the License, or
9
* (at your option) any later version.
11
* FastQC is distributed in the hope that it will be useful,
12
* but WITHOUT ANY WARRANTY; without even the implied warranty of
13
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14
* GNU General Public License for more details.
16
* You should have received a copy of the GNU General Public License
17
* along with FastQC; if not, write to the Free Software
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
package uk.ac.babraham.FastQC.Modules;
22
import java.awt.Graphics;
23
import java.awt.image.BufferedImage;
24
import java.io.IOException;
25
import java.util.zip.ZipEntry;
26
import java.util.zip.ZipOutputStream;
28
import javax.imageio.ImageIO;
29
import javax.swing.JPanel;
31
import uk.ac.babraham.FastQC.Graphs.BaseGroup;
32
import uk.ac.babraham.FastQC.Graphs.LineGraph;
33
import uk.ac.babraham.FastQC.Report.HTMLReportArchive;
34
import uk.ac.babraham.FastQC.Sequence.Sequence;
36
public class PerBaseGCContent implements QCModule {
38
public long [] gcCounts = new long [0];
39
public long [] atCounts = new long [0];
40
private double [] percentages = null;
41
private String [] xCategories = new String[0];
42
private boolean calculated = false;
43
private double maxDeviation;
46
public JPanel getResultsPanel() {
48
if (!calculated) getPercentages();
50
return new LineGraph(new double [][] {percentages}, 0d, 100d, "Position in read (bp)", new String [] {"%GC"}, xCategories, "GC content across all bases");
53
public boolean ignoreFilteredSequences() {
57
private synchronized void getPercentages () {
59
BaseGroup [] groups = BaseGroup.makeBaseGroups(gcCounts.length);
61
xCategories = new String[groups.length];
63
percentages = new double [groups.length];
66
// For error calling we also want to work out what the
67
// maximum deviation from the mean GC is to see if we
68
// have any great level of variation
74
for (int i=0;i<groups.length;i++) {
76
xCategories[i] = groups[i].toString();
81
for (int bp=groups[i].lowerCount()-1;bp<groups[i].upperCount();bp++) {
82
gcCount += gcCounts[bp];
83
total += gcCounts[bp];
84
total += atCounts[bp];
87
percentages[i] = 100*(gcCount/(double)total);
88
mean += percentages[i];
91
mean /= percentages.length;
93
// We now calculate the maximumn percentage deviation
94
maxDeviation = Math.abs(mean - percentages[0]);
95
for (int i=1;i<percentages.length;i++) {
96
double diff = Math.abs(mean-percentages[i]);
97
if (diff > maxDeviation) {
105
public void processSequence(Sequence sequence) {
107
char [] seq = sequence.getSequence().toCharArray();
109
if (gcCounts.length < seq.length) {
110
// We need to expand the size of the data structures
112
long [] gcCountsNew = new long [seq.length];
113
long [] atCountsNew = new long [seq.length];
115
for (int i=0;i<gcCounts.length;i++) {
116
gcCountsNew[i] = gcCounts[i];
117
atCountsNew[i] = atCounts[i];
120
gcCounts = gcCountsNew;
121
atCounts = atCountsNew;
124
for (int i=0;i<seq.length;i++) {
125
if (seq[i] == 'G' || seq[i] == 'C') {
128
if (seq[i] == 'A' || seq[i] == 'T' || seq[i] == 'U') {
135
public void reset () {
136
gcCounts = new long[0];
137
atCounts = new long[0];
140
public String description() {
141
return "Shows the GC content of all bases at a given position in a sequencing run";
144
public String name() {
145
return "Per base GC content";
148
public boolean raisesError() {
149
if (!calculated) getPercentages();
151
return maxDeviation > 10;
154
public boolean raisesWarning() {
155
if (!calculated) getPercentages();
157
return maxDeviation > 5;
160
public void makeReport(HTMLReportArchive report) throws IOException {
161
if (!calculated) getPercentages();
162
ZipOutputStream zip = report.zipFile();
163
zip.putNextEntry(new ZipEntry(report.folderName()+"/Images/per_base_gc_content.png"));
165
BufferedImage b = new BufferedImage(Math.max(800, percentages.length*15),600,BufferedImage.TYPE_INT_RGB);
166
Graphics g = b.getGraphics();
168
LineGraph lg = new LineGraph(new double [][] {percentages}, 0d, 100d, "Position in read (bp)", new String [] {"%GC"}, xCategories, "GC content across all bases");
169
lg.paint(g,b.getWidth(),b.getHeight());
171
ImageIO.write((BufferedImage)(b),"PNG",zip);
173
StringBuffer sb = report.htmlDocument();
175
sb.append("<p><img class=\"indented\" src=\"Images/per_base_gc_content.png\" alt=\"Per base GC content graph\"></p>\n");
177
sb = report.dataDocument();
178
sb.append("#Base\t%GC\n");
179
for (int i=0;i<xCategories.length;i++) {
180
sb.append(xCategories[i]);
182
sb.append(percentages[i]);