diff --git a/sequencing/src/main/java/org/biojava/bio/program/abi/ABITrace.java b/sequencing/src/main/java/org/biojava/bio/program/abi/ABITrace.java
index 1e181cd..bb8a2f3 100644
--- a/sequencing/src/main/java/org/biojava/bio/program/abi/ABITrace.java
+++ b/sequencing/src/main/java/org/biojava/bio/program/abi/ABITrace.java
@@ -58,365 +58,500 @@
* @author Matthew Pocock
* @version 0.5alpha
*/
-public class ABITrace
-{
+public class ABITrace {
+ //the next three lines are the important persistent data
+ private String sequence;
+ private int A[], G[], C[], T[], Basecalls[], Qcalls[];
+ private int TraceLength, SeqLength;
+
+ //This is the actual file data.
+ private byte[] TraceData;
+
+ private final int maximum;
+ //the next four declaration lines comprise the file index information
+ //sometimes when macintosh files are
+ private int MacJunk;
+ //FTPed in binary form, they have 128 bytes
+ //of crap pre-pended to them. This constant
+ //allows ABITrace to handle that in a way that
+ //is invisible to the user.
+ private static final int ABS_INDEX_BASE = 26; //The file location of the Index pointer
+ private int IndexBase, PLOC, PCON;
+
+ //the next declaration is for the actual file pointers
+ private int DATA9, DATA10, DATA11, DATA12, PBAS2, FWO;
- //the next three lines are the important persistent data
- private String sequence;
- private int A[], G[], C[], T[], Basecalls[], Qcalls[];
- private int TraceLength, SeqLength;
-
- //This is the actual file data.
- private byte[] TraceData;
-
- private int maximum = 0;
-
- //the next four declaration lines comprise the file index information
- private int MacJunk=0; //sometimes when macintosh files are
- //FTPed in binary form, they have 128 bytes
- //of crap pre-pended to them. This constant
- //allows ABITrace to handle that in a way that
- //is invisible to the user.
- private static int AbsIndexBase=26; //The file location of the Index pointer
- private int IndexBase, PLOC, PCON;
-
- //the next declaration is for the actual file pointers
- private int DATA9, DATA10, DATA11, DATA12, PBAS2, FWO;
-
-/**
- * The File constructor opens a local ABI file and parses the content.
- * @param ABIFile is a java.io.File
on the local file system.
- * @throws IOException if there is a problem reading the file.
- * @throws IllegalArgumentException if the file is not a valid ABI file.
- */
- public ABITrace( File ABIFile ) throws IOException
- {
- byte[] bytes = null;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- FileInputStream fis = new FileInputStream(ABIFile);
- BufferedInputStream bis = new BufferedInputStream(fis);
- int b;
- while ((b = bis.read()) >= 0)
- {
- baos.write(b);
+ /**
+ * The File constructor opens a local ABI file and parses the content.
+ *
+ * @param ABIFile is a java.io.File
on the local file system.
+ * @throws IOException if there is a problem reading the file.
+ * @throws IllegalArgumentException if the file is not a valid ABI file.
+ */
+ public ABITrace(File ABIFile) throws IOException {
+ this.MacJunk = 0;
+ this.maximum = 0;
+ byte[] bytes = null;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ FileInputStream fis = new FileInputStream(ABIFile);
+ BufferedInputStream bis = new BufferedInputStream(fis);
+ int b;
+ while ((b = bis.read()) >= 0) {
+ baos.write(b);
+ }
+ bis.close();
+ fis.close();
+ baos.close();
+ bytes = baos.toByteArray();
+ initData(bytes);
}
- bis.close(); fis.close(); baos.close();
- bytes = baos.toByteArray();
- initData(bytes);
- }
-/**
- * The URL constructor opens an ABI file from any URL.
- * @param ABIFile is a java.net.URL
for an ABI trace file.
- * @throws IOException if there is a problem reading from the URL.
- * @throws IllegalArgumentException if the URL does not contain a valid ABI file.
- */
- public ABITrace( URL ABIFile ) throws IOException
- {
- byte[] bytes = null;
- ByteArrayOutputStream baos = new ByteArrayOutputStream();
- InputStream is = ABIFile.openStream();
- BufferedInputStream bis = new BufferedInputStream(is);
- int b;
- while ((b = bis.read()) >= 0)
- {
- baos.write(b);
+ /**
+ * The URL constructor opens an ABI file from any URL.
+ *
+ * @param ABIFile is a java.net.URL
for an ABI trace file.
+ * @throws IOException if there is a problem reading from the URL.
+ * @throws IllegalArgumentException if the URL does not contain a valid ABI
+ * file.
+ */
+ public ABITrace(URL ABIFile) throws IOException {
+ this.MacJunk = 0;
+ this.maximum = 0;
+ byte[] bytes = null;
+ ByteArrayOutputStream baos = new ByteArrayOutputStream();
+ InputStream is = ABIFile.openStream();
+ BufferedInputStream bis = new BufferedInputStream(is);
+ int b;
+ while ((b = bis.read()) >= 0) {
+ baos.write(b);
+ }
+ bis.close();
+ is.close();
+ baos.close();
+ bytes = baos.toByteArray();
+ initData(bytes);
}
- bis.close(); is.close(); baos.close();
- bytes = baos.toByteArray();
- initData(bytes);
- }
-/**
- * The byte[]
constructor parses an ABI file represented as a byte array.
- * @throws IllegalArgumentException if the data does not represent a valid ABI file.
- */
- public ABITrace(byte[] ABIFileData)
- {
- initData(ABIFileData);
- }
-
-/**
- * Returns the length of the sequence (number of bases) in this trace.
- */
- public int getSequenceLength() { return SeqLength; }
+ /**
+ * The byte[]
constructor parses an ABI file represented as a
+ * byte array.
+ *
+ * @param ABIFileData
+ * @throws IllegalArgumentException if the data does not represent a valid
+ * ABI file.
+ */
+ public ABITrace(byte[] ABIFileData) {
+ this.MacJunk = 0;
+ this.maximum = 0;
+ initData(ABIFileData);
+ }
-/**
- * Returns the length of the trace (number of x-coordinate points in the graph).
- */
- public int getTraceLength() { return TraceLength; }
+ /**
+ * Returns the length of the sequence (number of bases) in this trace.
+ */
+ public int getSequenceLength() {
+ return SeqLength;
+ }
-/**
- * Returns an int[]
array that represents the basecalls - each int in the
- * array corresponds to an x-coordinate point in the graph that is a peak (a base location).
- */
- public int[] getBasecalls() { return Basecalls; }
-
- /**
- * Returns an int[]
array that represents the quality - each int in the
- * array corresponds to an quality value 90-255) in the graph at a base location).
- */
- public int[] getQcalls() { return Qcalls; }
+ /**
+ * Returns the length of the trace (number of x-coordinate points in the
+ * graph).
+ */
+ public int getTraceLength() {
+ return TraceLength;
+ }
-/**
- * Returns the original programatically determined (unedited) sequence as a SymbolList
.
- */
- public SymbolList getSequence() throws BioError
- {
- try {
- return DNATools.createDNA(sequence);
+ /**
+ * Returns an int[]
array that represents the basecalls - each
+ * int in the array corresponds to an x-coordinate point in the graph that
+ * is a peak (a base location).
+ */
+ public int[] getBasecalls() {
+ return Basecalls;
}
- catch (IllegalSymbolException ise) {
- // this should be impossible!
- throw new BioError(ise);
+
+ /**
+ * Returns an int[]
array that represents the quality - each
+ * int in the array corresponds to an quality value 90-255) in the graph at
+ * a base location).
+ */
+ public int[] getQcalls() {
+ return Qcalls;
}
- }
-/**
- * Returns one of the four traces - all of the y-coordinate values,
- * each of which correspond to a single x-coordinate relative to the
- * position in the array, so that if element 4 in the array is 972, then
- * x is 4 and y is 972 for that point.
- *
- * @param base the DNA AttomicSymbol to retrieve the trace values for
- * @return an array of ints giving the entire trace for that base
- * @throws IllegalSymbolException if the base is not valid
- */
- public int[] getTrace (AtomicSymbol base) throws IllegalSymbolException
- {
- if (base == DNATools.a()) {
- return A;
- } else if (base == DNATools.c()) {
- return C;
- } else if (base == DNATools.g()) {
- return G;
- } else if (base == DNATools.t()) {
- return T;
- } else {
- DNATools.getDNA().validate(base);
- throw new IllegalSymbolException("Don't know symbol: " + base);
+ /**
+ * Returns the original programatically determined (unedited) sequence as a
+ * SymbolList
.
+ */
+ public String getSequence() {
+ return sequence;
}
- }
-/**
- * Returns a BufferedImage that represents the entire trace. The height can be set precisely in
- * pixels, the width in pixels is determined by the scaling factor times the number
- * of points in the trace (getTraceLength()
). The entire trace is represented
- * in the returned image.
- *
- * @param imageHeight is the desired height of the image in pixels.
- * @param widthScale indiates how many horizontal pixels to use to represent a single x-coordinate (try 2).
- */
- public BufferedImage getImage(int imageHeight, int widthScale)
- {
- BufferedImage out = new BufferedImage(TraceLength * widthScale, imageHeight, BufferedImage.TYPE_BYTE_INDEXED);
- Graphics2D g = out.createGraphics();
- Color acolor = Color.green.darker();
- Color ccolor = Color.blue;
- Color gcolor = Color.black;
- Color tcolor = Color.red;
- Color ncolor = Color.pink;
- double scale = calculateScale(imageHeight);
- int[] bc = Basecalls;
- char[] seq = sequence.toCharArray();
- g.setBackground(Color.white);
- g.clearRect(0, 0, TraceLength * widthScale, imageHeight);
- int here = 0;
- int basenum = 0;
- for (int q = 1; q <= 5; q++)
- {
- for (int x = 0; x <= TraceLength - 2; x++)
- {
- if (q==1)
- {
- g.setColor(acolor);
- g.drawLine(2*x, transmute(A[x], imageHeight, scale),
- 2*(x + 1), transmute(A[x+1], imageHeight, scale));
- }
- if (q==2)
- {
- g.setColor(ccolor);
- g.drawLine(2*x, transmute(C[x], imageHeight, scale),
- 2*(x + 1), transmute(C[x+1], imageHeight, scale));
- }
- if (q==3)
- {
- g.setColor(tcolor);
- g.drawLine(2*x, transmute(T[x], imageHeight, scale),
- 2*(x + 1), transmute(T[x+1], imageHeight, scale));
+ /**
+ * Returns one of the four traces - all of the y-coordinate values, each of
+ * which correspond to a single x-coordinate relative to the position in the
+ * array, so that if element 4 in the array is 972, then x is 4 and y is 972
+ * for that point.
+ *
+ * @param base the DNA AttomicSymbol to retrieve the trace values for
+ * @return an array of ints giving the entire trace for that base
+ * @throws IllegalSymbolException if the base is not valid
+ */
+ public int[] getTrace(char base) {
+ switch (base) {
+ case 'a':
+ return A;
+ case 'c':
+ return C;
+ case 'g':
+ return G;
+ case 't':
+ return T;
+ default:
+ throw new IllegalArgumentException("Don't know symbol: " + base);
}
- if (q==4)
- {
- g.setColor(gcolor);
- g.drawLine(2*x, transmute(G[x], imageHeight, scale),
- 2*(x + 1), transmute(G[x+1], imageHeight, scale));
+ }
+
+ /**
+ * Returns reverse representation of sequence.
+ * @param sequence
+ * @return
+ */
+ private int[] getSequenceReverted(int[] sequence){
+ for (int i = 0; i < sequence.length/2; i++) {
+ int s = sequence[i];
+ sequence[i] = sequence[sequence.length - i - 1];
+ sequence[sequence.length - i - 1] = s;
}
- if (q==5)
- {
- if ((here > bc.length-1) || (basenum > seq.length-1)) break;
- if (bc[here] == x)
- {
- g.drawLine(2*x, transmute(-2, imageHeight, 1.0),
- 2*x, transmute(-7, imageHeight, 1.0));
- if ((basenum+1)%10 == 0) //if the basecount is divisible by ten
- //add a number
- {
- g.drawLine(2*x, transmute(-20, imageHeight, 1.0),
- 2*x, transmute(-25, imageHeight, 1.0));
- g.drawString(Integer.toString(basenum+1),
- 2*x-3, transmute(-36, imageHeight, 1.0));
+
+ return sequence;
+ }
+
+ /**
+ * Returns a BufferedImage that represents the entire trace. The height can
+ * be set precisely in pixels, the width in pixels is determined by the
+ * scaling factor times the number of points in the trace
+ * (getTraceLength()
). The entire trace is represented in the
+ * returned image.
+ *
+ * @param imageHeight is the desired height of the image in pixels.
+ * @param widthScale indiates how many horizontal pixels to use to represent
+ * a single x-coordinate (try 2).
+ * @return BufferedImage that represents the entire trace.
+ */
+ public BufferedImage getImage(int imageHeight, int widthScale) {
+ BufferedImage out = new BufferedImage(TraceLength * widthScale, imageHeight, BufferedImage.TYPE_BYTE_INDEXED);
+ Graphics2D g = out.createGraphics();
+ Color acolor = Color.green.darker();
+ Color ccolor = Color.blue;
+ Color gcolor = Color.black;
+ Color tcolor = Color.red;
+ Color ncolor = Color.pink;
+ double scale = calculateScale(imageHeight);
+ int[] bc = Basecalls;
+ char[] seq = sequence.toCharArray();
+ g.setBackground(Color.white);
+ g.clearRect(0, 0, TraceLength * widthScale, imageHeight);
+ int here = 0;
+ int basenum = 0;
+ for (int q = 1; q <= 5; q++) {
+ for (int x = 0; x <= TraceLength - 2; x++) {
+ if (q == 1) {
+ g.setColor(acolor);
+ g.drawLine(widthScale * x, transmute(A[x], imageHeight, scale),
+ widthScale * (x + 1), transmute(A[x + 1], imageHeight, scale));
+ }
+ if (q == 2) {
+ g.setColor(ccolor);
+ g.drawLine(widthScale * x, transmute(C[x], imageHeight, scale),
+ widthScale * (x + 1), transmute(C[x + 1], imageHeight, scale));
+ }
+ if (q == 3) {
+ g.setColor(tcolor);
+ g.drawLine(widthScale * x, transmute(T[x], imageHeight, scale),
+ widthScale * (x + 1), transmute(T[x + 1], imageHeight, scale));
+ }
+ if (q == 4) {
+ g.setColor(gcolor);
+ g.drawLine(widthScale * x, transmute(G[x], imageHeight, scale),
+ widthScale * (x + 1), transmute(G[x + 1], imageHeight, scale));
+ }
+ if (q == 5) {
+ if ((here > bc.length - 1) || (basenum > seq.length - 1)) {
+ break;
+ }
+ if (bc[here] == x) {
+ g.drawLine(widthScale * x, transmute(-2, imageHeight, 1.0),
+ widthScale * x, transmute(-7, imageHeight, 1.0));
+ if ((basenum + 1) % 10 == 0) //if the basecount is divisible by ten
+ //add a number
+ {
+ g.drawLine(widthScale * x, transmute(-20, imageHeight, 1.0),
+ widthScale * x, transmute(-25, imageHeight, 1.0));
+ g.drawString(Integer.toString(basenum + 1),
+ widthScale * x - 3, transmute(-36, imageHeight, 1.0));
+ }
+ switch (seq[basenum]) {
+ case 'A':
+ case 'a':
+ g.setColor(acolor);
+ break;
+ case 'C':
+ case 'c':
+ g.setColor(ccolor);
+ break;
+ case 'G':
+ case 'g':
+ g.setColor(gcolor);
+ break;
+ case 'T':
+ case 't':
+ g.setColor(tcolor);
+ break;
+ default:
+ g.setColor(ncolor);
+ }
+ /*g.drawChars(seq, basenum, 1,
+ 2*x-3, transmute(-18, imageHeight, 1.0));*/
+ g.setColor(Color.black);
+ here++;
+ basenum++;
+ }
+ }
}
- switch (seq[basenum])
- {
- case 'A': case 'a': g.setColor(acolor); break;
- case 'C': case 'c': g.setColor(ccolor); break;
- case 'G': case 'g': g.setColor(gcolor); break;
- case 'T': case 't': g.setColor(tcolor); break;
- default: g.setColor(ncolor);
+ }
+ return out;
+ }
+
+ /**
+ * Returns a BufferedImage that represents the Reverse Complement counterpart of entire trace. The height can
+ * be set precisely in pixels, the width in pixels is determined by the
+ * scaling factor times the number of points in the trace
+ * (getTraceLength()
). The entire trace is represented in the
+ * returned image.
+ *
+ * @param imageHeight is the desired height of the image in pixels.
+ * @param widthScale indiates how many horizontal pixels to use to represent
+ * a single x-coordinate (try 2).
+ * @return BufferedImage that represents the Reverse Complement counterpart of entire trace.
+ */
+ public BufferedImage getImageReverted(int imageHeight, int widthScale) {
+ BufferedImage out = new BufferedImage(TraceLength * widthScale, imageHeight, BufferedImage.TYPE_BYTE_INDEXED);
+ Graphics2D g = out.createGraphics();
+ Color acolor = Color.green.darker();
+ Color ccolor = Color.blue;
+ Color gcolor = Color.black;
+ Color tcolor = Color.red;
+ Color ncolor = Color.pink;
+ double scale = calculateScale(imageHeight);
+ int[] bc = getSequenceReverted(Basecalls);
+ char[] seq = sequence.toCharArray();
+ int[] AR = getSequenceReverted(A);
+ int[] CR = getSequenceReverted(C);
+ int[] GR = getSequenceReverted(G);
+ int[] TR = getSequenceReverted(T);
+ g.setBackground(Color.white);
+ g.clearRect(0, 0, TraceLength * widthScale, imageHeight);
+ int here = 0;
+ int basenum = 0;
+ for (int q = 1; q <= 5; q++) {
+ for (int x = 0; x <= TraceLength - 2; x++) {
+ if (q == 1) {
+ g.setColor(acolor);
+ g.drawLine(widthScale * x, transmute(AR[x], imageHeight, scale),
+ widthScale * (x + 1), transmute(AR[x + 1], imageHeight, scale));
+ }
+ if (q == 2) {
+ g.setColor(ccolor);
+ g.drawLine(widthScale * x, transmute(CR[x], imageHeight, scale),
+ widthScale * (x + 1), transmute(CR[x + 1], imageHeight, scale));
+ }
+ if (q == 3) {
+ g.setColor(tcolor);
+ g.drawLine(widthScale * x, transmute(TR[x], imageHeight, scale),
+ widthScale * (x + 1), transmute(TR[x + 1], imageHeight, scale));
+ }
+ if (q == 4) {
+ g.setColor(gcolor);
+ g.drawLine(widthScale * x, transmute(GR[x], imageHeight, scale),
+ widthScale * (x + 1), transmute(GR[x + 1], imageHeight, scale));
+ }
+ if (q == 5) {
+ if ((here > bc.length - 1) || (basenum > seq.length - 1)) {
+ break;
+ }
+ if (TraceLength-bc[here] == x) {
+ g.drawLine(widthScale * x, transmute(-2, imageHeight, 1.0),
+ widthScale * x, transmute(-7, imageHeight, 1.0));
+ if ((basenum + 1) % 10 == 0) //if the basecount is divisible by ten add a number
+ {
+ g.drawLine(widthScale * x, transmute(-20, imageHeight, 1.0),
+ widthScale * x, transmute(-25, imageHeight, 1.0));
+ g.drawString(Integer.toString(basenum + 1),
+ widthScale * x - 3, transmute(-36, imageHeight, 1.0));
+ }
+ switch (seq[basenum]) {
+ case 'A':
+ case 'a':
+ g.setColor(acolor);
+ break;
+ case 'C':
+ case 'c':
+ g.setColor(ccolor);
+ break;
+ case 'G':
+ case 'g':
+ g.setColor(gcolor);
+ break;
+ case 'T':
+ case 't':
+ g.setColor(tcolor);
+ break;
+ default:
+ g.setColor(ncolor);
+ }
+ g.setColor(Color.black);
+ here++;
+ basenum++;
+ }
+ }
}
- g.drawChars(seq, basenum, 1,
- 2*x-3, transmute(-18, imageHeight, 1.0));
- g.setColor(Color.black);
- here++; basenum++;
- }
}
- }
+ return out;
}
- return out;
- }
-/**
- * Initialize all of the data fields for this object.
- * @throws IllegalArgumentException which will propagate to all of the constructors.
- */
- private void initData(byte[] fileData)
- {
- TraceData = fileData;
- if (isABI())
- {
- setIndex();
- setBasecalls();
- setQcalls();
- setSeq();
- setTraces();
- }
- else throw new IllegalArgumentException("Not a valid ABI file.");
- }
-/**
- * A utility method which fills array b with data from the trace starting at traceDataOffset.
- */
- private void getSubArray(byte[] b, int traceDataOffset)
- {
- for (int x=0; x<=b.length-1; x++)
- {
- b[x] = TraceData[traceDataOffset + x];
+ /**
+ * Initialize all of the data fields for this object.
+ *
+ * @throws IllegalArgumentException which will propagate to all of the
+ * constructors.
+ */
+ private void initData(byte[] fileData) {
+ TraceData = fileData;
+ if (isABI()) {
+ setIndex();
+ setBasecalls();
+ setQcalls();
+ setSeq();
+ setTraces();
+ } else {
+ throw new IllegalArgumentException("Not a valid ABI file.");
+ }
}
- }
-/**
- * Shuffle the pointers to point to the proper spots in the trace, then load the
- * traces into their arrays.
- */
- private void setTraces()
- {
- int pointers[] = new int[4]; //alphabetical, 0=A, 1=C, 2=G, 3=T
- int datas[] = new int[4];
- char order[] = new char[4];
-
- datas[0] = DATA9;
- datas[1] = DATA10;
- datas[2] = DATA11;
- datas[3] = DATA12;
-
- for (int i=0; i<=3; i++)
- {
- order[i]=(char) TraceData[FWO+i];
+ /**
+ * A utility method which fills array b with data from the trace starting at
+ * traceDataOffset.
+ */
+ private void getSubArray(byte[] b, int traceDataOffset) {
+ for (int x = 0; x <= b.length - 1; x++) {
+ b[x] = TraceData[traceDataOffset + x];
+ }
}
- for (int i=0; i <=3; i++)
- {
- switch (order[i])
- {
- case 'A': case 'a':
- pointers[0] = datas[i];
- break;
- case 'C': case 'c':
- pointers[1] = datas[i];
- break;
- case 'G': case 'g':
- pointers[2] = datas[i];
- break;
- case 'T': case 't':
- pointers[3] = datas[i];
- break;
- default:
- throw new IllegalArgumentException("Trace contains illegal values.");
- }
- }
+ /**
+ * Shuffle the pointers to point to the proper spots in the trace, then load
+ * the traces into their arrays.
+ */
+ private void setTraces() {
+ int pointers[] = new int[4]; //alphabetical, 0=A, 1=C, 2=G, 3=T
+ int datas[] = new int[4];
+ char order[] = new char[4];
+
+ datas[0] = DATA9;
+ datas[1] = DATA10;
+ datas[2] = DATA11;
+ datas[3] = DATA12;
+
+ for (int i = 0; i <= 3; i++) {
+ order[i] = (char) TraceData[FWO + i];
+ }
- A = new int[TraceLength];
- C = new int[TraceLength];
- G = new int[TraceLength];
- T = new int[TraceLength];
-
- for (int i=0; i <=3; i++)
- {
- byte[] qq = new byte[TraceLength*2];
- getSubArray(qq, pointers[i]);
- DataInputStream dis = new DataInputStream(new ByteArrayInputStream(qq));
- for (int x=0; x <=TraceLength - 1; x++)
- {
- try
- {
- if (i == 0) A[x] = (int) dis.readShort();
- if (i == 1) C[x] = (int) dis.readShort();
- if (i == 2) G[x] = (int) dis.readShort();
- if (i == 3) T[x] = (int) dis.readShort();
- }catch(IOException e)//This shouldn't happen. If it does something must be seriously wrong.
- {
- throw new IllegalStateException("Unexpected IOException encountered while manipulating internal streams.");
+ for (int i = 0; i <= 3; i++) {
+ switch (order[i]) {
+ case 'A':
+ case 'a':
+ pointers[0] = datas[i];
+ break;
+ case 'C':
+ case 'c':
+ pointers[1] = datas[i];
+ break;
+ case 'G':
+ case 'g':
+ pointers[2] = datas[i];
+ break;
+ case 'T':
+ case 't':
+ pointers[3] = datas[i];
+ break;
+ default:
+ throw new IllegalArgumentException("Trace contains illegal values.");
+ }
}
- }
- }
- return;
- }
-/**
- * Fetch the sequence from the trace data.
- */
- private void setSeq()
- {
- char tempseq[] = new char[SeqLength];
- for (int x = 0; x <= SeqLength - 1; ++x)
- {
- tempseq[x] = (char) TraceData[PBAS2 + x];
+ A = new int[TraceLength];
+ C = new int[TraceLength];
+ G = new int[TraceLength];
+ T = new int[TraceLength];
+
+ for (int i = 0; i <= 3; i++) {
+ byte[] qq = new byte[TraceLength * 2];
+ getSubArray(qq, pointers[i]);
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(qq));
+ for (int x = 0; x <= TraceLength - 1; x++) {
+ try {
+ if (i == 0) {
+ A[x] = (int) dis.readShort();
+ }
+ if (i == 1) {
+ C[x] = (int) dis.readShort();
+ }
+ if (i == 2) {
+ G[x] = (int) dis.readShort();
+ }
+ if (i == 3) {
+ T[x] = (int) dis.readShort();
+ }
+ } catch (IOException e)//This shouldn't happen. If it does something must be seriously wrong.
+ {
+ throw new IllegalStateException("Unexpected IOException encountered while manipulating internal streams.");
+ }
+ }
+ }
+ return;
}
- sequence = new String (tempseq);
- }
+ /**
+ * Fetch the sequence from the trace data.
+ */
+ private void setSeq() {
+ char tempseq[] = new char[SeqLength];
+ for (int x = 0; x <= SeqLength - 1; ++x) {
+ tempseq[x] = (char) TraceData[PBAS2 + x];
+ }
+ sequence = new String(tempseq);
+ }
-/**
- * Fetch the basecalls from the trace data.
- */
- private void setBasecalls()
- {
- Basecalls = new int[SeqLength];
- byte[] qq = new byte[SeqLength*2];
- getSubArray(qq, PLOC);
- DataInputStream dis = new DataInputStream(new ByteArrayInputStream(qq));
- for (int i = 0; i <= SeqLength -1; ++i)
- {
- try
- {
- Basecalls[i]=(int) dis.readShort();
- }catch(IOException e)//This shouldn't happen. If it does something must be seriously wrong.
- {
- throw new IllegalStateException("Unexpected IOException encountered while manipulating internal streams.");
- }
+ /**
+ * Fetch the basecalls from the trace data.
+ */
+ private void setBasecalls() {
+ Basecalls = new int[SeqLength];
+ byte[] qq = new byte[SeqLength * 2];
+ getSubArray(qq, PLOC);
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(qq));
+ for (int i = 0; i <= SeqLength - 1; ++i) {
+ try {
+ Basecalls[i] = (int) dis.readShort();
+ } catch (IOException e)//This shouldn't happen. If it does something must be seriously wrong.
+ {
+ throw new IllegalStateException("Unexpected IOException encountered while manipulating internal streams.");
+ }
+ }
}
- }
-
+
/**
* Fetch the quality calls from the trace data.
*/
@@ -435,162 +570,167 @@ private void setQcalls() {
}
}
-/**
- * Utility method to return an int beginning at pointer
in the TraceData array.
- */
- private int getIntAt(int pointer)
- {
- int out = 0;
- byte[] temp = new byte[4];
- getSubArray(temp, pointer);
- try
- {
- DataInputStream dis = new DataInputStream(new ByteArrayInputStream(temp));
- out = dis.readInt();
- }catch(IOException e) //This shouldn't happen. If it does something must be seriously wrong.
- {
- throw new IllegalStateException("Unexpected IOException encountered while manipulating internal streams.");
+ /**
+ * Utility method to return an int beginning at pointer
in the
+ * TraceData array.
+ */
+ private int getIntAt(int pointer) {
+ int out = 0;
+ byte[] temp = new byte[4];
+ getSubArray(temp, pointer);
+ try {
+ DataInputStream dis = new DataInputStream(new ByteArrayInputStream(temp));
+ out = dis.readInt();
+ } catch (IOException e) //This shouldn't happen. If it does something must be seriously wrong.
+ {
+ throw new IllegalStateException("Unexpected IOException encountered while manipulating internal streams.");
+ }
+ return out;
}
- return out;
- }
-
-/**
- * Utility method to translate y coordinates from graph space (where up is greater)
- * to image space (where down is greater).
- */
- private int transmute(int ya, int height, double scale)
- {
- return (height - 45 - (int) (ya * scale));
- }
-/**
- * Get the maximum height of any of the traces. The data is persisted for performance
- * in the event of multiple calls, but it initialized lazily.
- */
- private int getMaximum()
- {
- if (maximum > 0) return maximum;
- int max = 0;
- for (int x=0; x<=T.length-1; x++)
- {
- if (T[x] > max) max = T[x];
- if (A[x] > max) max = A[x];
- if (C[x] > max) max = C[x];
- if (G[x] > max) max = G[x];
+ /**
+ * Utility method to translate y coordinates from graph space (where up is
+ * greater) to image space (where down is greater).
+ */
+ private int transmute(int ya, int height, double scale) {
+ return (height - 45 - (int) (ya * scale));
}
- return max;
- }
- //calculates the necessary scaling to allow the trace to fit vertically
- //in the space specified.
-/**
- * Returns the scaling factor necessary to allow all of the traces to fit vertically
- * into the specified space.
- * @param height
- the required height in pixels.
- */
- private double calculateScale(int height)
- {
- double newScale = 0.0;
- double max = (double)getMaximum();
- double ht = (double)height;
- newScale = ((ht - 50.0))/max;
- return newScale;
- }
+ /**
+ * Get the maximum height of any of the traces. The data is persisted for
+ * performance in the event of multiple calls, but it initialized lazily.
+ */
+ private int getMaximum() {
+ if (maximum > 0) {
+ return maximum;
+ }
+ int max = 0;
+ for (int x = 0; x <= T.length - 1; x++) {
+ if (T[x] > max) {
+ max = T[x];
+ }
+ if (A[x] > max) {
+ max = A[x];
+ }
+ if (C[x] > max) {
+ max = C[x];
+ }
+ if (G[x] > max) {
+ max = G[x];
+ }
+ }
+ return max;
+ }
-/**
- * Sets up all of the initial pointers to the important records in TraceData.
- */
- private void setIndex()
- {
- int DataCounter, PBASCounter, PLOCCounter, PCONCounter, NumRecords;
- byte[] RecNameArray = new byte[4];
- String RecName;
-
- DataCounter = 0; PBASCounter = 0; PLOCCounter = 0; PCONCounter = 0;
-
- IndexBase = getIntAt(AbsIndexBase + MacJunk);
- NumRecords = getIntAt(AbsIndexBase - 8 + MacJunk);
-
- for (int record = 0; record <= NumRecords - 1; record++)
- {
- getSubArray(RecNameArray, (IndexBase + (record * 28)));
- RecName = new String (RecNameArray);
- if (RecName.equals("FWO_"))
- FWO = IndexBase + (record * 28) + 20;
- if (RecName.equals("DATA"))
- {
- ++DataCounter;
- if (DataCounter == 9)
- DATA9 = IndexBase + (record * 28) + 20;
- if (DataCounter == 10)
- DATA10 = IndexBase + (record * 28) + 20;
- if (DataCounter == 11)
- DATA11 = IndexBase + (record * 28) + 20;
- if (DataCounter == 12)
- DATA12 = IndexBase + (record * 28) + 20;
- }
- if (RecName.equals("PBAS"))
- {
- ++PBASCounter;
- if (PBASCounter == 2)
- PBAS2 = IndexBase + (record * 28) + 20;
- }
- if (RecName.equals("PLOC"))
- {
- ++PLOCCounter;
- if (PLOCCounter == 2)
- PLOC = IndexBase + (record * 28) + 20;
- }
- if (RecName.equals("PCON"))
- {
- ++PCONCounter;
- if (PCONCounter == 2)
- PCON = IndexBase + (record * 28) + 20;
- }
-
- } //next record
- TraceLength = getIntAt(DATA12 - 8);
- SeqLength = getIntAt(PBAS2-4);
- PLOC = getIntAt(PLOC) + MacJunk;
- DATA9 = getIntAt(DATA9) + MacJunk;
- DATA10 = getIntAt(DATA10) + MacJunk;
- DATA11 = getIntAt(DATA11) + MacJunk;
- DATA12 = getIntAt(DATA12) + MacJunk;
- PBAS2 = getIntAt(PBAS2) + MacJunk;
- PCON = getIntAt(PCON) + MacJunk;
- }
+ //calculates the necessary scaling to allow the trace to fit vertically
+ //in the space specified.
+ /**
+ * Returns the scaling factor necessary to allow all of the traces to fit
+ * vertically into the specified space.
+ *
+ * @param height
- the required height in pixels.
+ */
+ private double calculateScale(int height) {
+ double newScale = 0.0;
+ double max = (double) getMaximum();
+ double ht = (double) height;
+ newScale = ((ht - 50.0)) / max;
+ return newScale;
+ }
-/**
- * Test to see if the file is ABI format by checking to see that the first three bytes
- * are "ABI". Also handle the special case where 128 bytes were prepended to the file
- * due to binary FTP from an older macintosh system.
- */
- private boolean isABI()
- {
- char ABI[] = new char[4];
+ /**
+ * Sets up all of the initial pointers to the important records in
+ * TraceData.
+ */
+ private void setIndex() {
+ int DataCounter, PBASCounter, PLOCCounter, PCONCounter, NumRecords;
+ byte[] RecNameArray = new byte[4];
+ String RecName;
+
+ DataCounter = 0;
+ PBASCounter = 0;
+ PLOCCounter = 0;
+ PCONCounter = 0;
+
+ IndexBase = getIntAt(ABS_INDEX_BASE + MacJunk);
+ NumRecords = getIntAt(ABS_INDEX_BASE - 8 + MacJunk);
+
+ for (int record = 0; record <= NumRecords - 1; record++) {
+ getSubArray(RecNameArray, (IndexBase + (record * 28)));
+ RecName = new String(RecNameArray);
+ if (RecName.equals("FWO_")) {
+ FWO = IndexBase + (record * 28) + 20;
+ }
+ if (RecName.equals("DATA")) {
+ ++DataCounter;
+ if (DataCounter == 9) {
+ DATA9 = IndexBase + (record * 28) + 20;
+ }
+ if (DataCounter == 10) {
+ DATA10 = IndexBase + (record * 28) + 20;
+ }
+ if (DataCounter == 11) {
+ DATA11 = IndexBase + (record * 28) + 20;
+ }
+ if (DataCounter == 12) {
+ DATA12 = IndexBase + (record * 28) + 20;
+ }
+ }
+ if (RecName.equals("PBAS")) {
+ ++PBASCounter;
+ if (PBASCounter == 2) {
+ PBAS2 = IndexBase + (record * 28) + 20;
+ }
+ }
+ if (RecName.equals("PLOC")) {
+ ++PLOCCounter;
+ if (PLOCCounter == 2) {
+ PLOC = IndexBase + (record * 28) + 20;
+ }
+ }
+ if (RecName.equals("PCON")) {
+ ++PCONCounter;
+ if (PCONCounter == 2) {
+ PCON = IndexBase + (record * 28) + 20;
+ }
+ }
- for (int i=0; i<=2; i++)
- {
- ABI[i]=(char) TraceData[i];
+ } //next record
+ TraceLength = getIntAt(DATA12 - 8);
+ SeqLength = getIntAt(PBAS2 - 4);
+ PLOC = getIntAt(PLOC) + MacJunk;
+ DATA9 = getIntAt(DATA9) + MacJunk;
+ DATA10 = getIntAt(DATA10) + MacJunk;
+ DATA11 = getIntAt(DATA11) + MacJunk;
+ DATA12 = getIntAt(DATA12) + MacJunk;
+ PBAS2 = getIntAt(PBAS2) + MacJunk;
+ PCON = getIntAt(PCON) + MacJunk;
}
- if (ABI[0] == 'A' && (ABI[1] == 'B' && ABI[2] == 'I'))
- {
- return true;
- }
- else
- {
- for (int i=128; i<=130; i++)
- {
- ABI[i]=(char) TraceData[i];
- }
- if (ABI[0] == 'A' && (ABI[1] == 'B' && ABI[2] == 'I'))
- {
- MacJunk=128;
- return true;
- }
- else
- return false;
- }
- }
+
+ /**
+ * Test to see if the file is ABI format by checking to see that the first
+ * three bytes are "ABI". Also handle the special case where 128 bytes were
+ * prepended to the file due to binary FTP from an older macintosh system.
+ */
+ private boolean isABI() {
+ char ABI[] = new char[4];
+
+ for (int i = 0; i <= 2; i++) {
+ ABI[i] = (char) TraceData[i];
+ }
+ if (ABI[0] == 'A' && (ABI[1] == 'B' && ABI[2] == 'I')) {
+ return true;
+ } else {
+ for (int i = 128; i <= 130; i++) {
+ ABI[i] = (char) TraceData[i];
+ }
+ if (ABI[0] == 'A' && (ABI[1] == 'B' && ABI[2] == 'I')) {
+ MacJunk = 128;
+ return true;
+ } else {
+ return false;
+ }
+ }
+ }
}