1 package hiseq; 2 3 import java.util.Arrays; 4 5 import dna.AminoAcid; 6 import shared.Tools; 7 import stream.Read; 8 9 /** 10 * Tracks base and quality composition per cycle. 11 * 12 * @author Brian Bushnell 13 * @date August 16, 2018 14 * 15 */ 16 public class CycleTracker { 17 add(Read r)18 public void add(Read r){ 19 if(r==null || r.length()<1){return;} 20 addBases(r.bases); 21 addQuality(r.quality); 22 } 23 add(CycleTracker ct)24 public void add(CycleTracker ct){ 25 // assert(false) : length+", "+ct.length; 26 final long[][] matrix=ct.acgtnq; 27 if(matrix[0]==null){return;} 28 if(acgtnq[0]==null || ct.length>length){ 29 resize(ct.length); 30 } 31 for(int i=0; i<matrix.length; i++){ 32 for(int j=0; j<matrix[i].length; j++){ 33 acgtnq[i][j]+=matrix[i][j]; 34 } 35 } 36 } 37 38 //Do this before using results process()39 public void process(){ 40 // System.err.println("Processing); length="+length); 41 if(length<1){return;} 42 long[] cycleSum=new long[length]; 43 for(int i=0; i<5; i++){ 44 long[] array=acgtnq[i]; 45 for(int j=0; j<array.length; j++){ 46 cycleSum[j]+=array[j]; 47 } 48 } 49 maxes=new float[6]; 50 averages=new float[6]; 51 for(int i=0; i<6; i++){ 52 cycleAverages[i]=new float[length]; 53 long[] array=acgtnq[i]; 54 for(int j=0; j<length; j++){ 55 float f=array[j]/(float)cycleSum[j]; 56 cycleAverages[i][j]=f; 57 maxes[i]=Tools.max(f, maxes[i]); 58 } 59 } 60 61 long[] sum=new long[6]; 62 long sumsum=0; 63 for(int i=0; i<5; i++){ 64 long x=Tools.sum(acgtnq[i]); 65 sum[i]=x; 66 sumsum+=x; 67 } 68 sum[5]=Tools.sum(acgtnq[5]); 69 for(int i=0; i<6; i++){ 70 averages[i]=sum[i]/(float)sumsum; 71 } 72 } 73 74 /*--------------------------------------------------------------*/ 75 addBases(byte[] bases)76 private void addBases(byte[] bases){ 77 if(length<bases.length){resize(bases.length);} 78 for(int i=0; i<bases.length; i++){ 79 byte b=bases[i]; 80 int x=AminoAcid.baseToNumberACGTN[b]; 81 assert(x>=0) : "This program does not support degenerate base codes: "+new String(bases); 82 acgtnq[x][i]++; 83 } 84 } 85 addQuality(byte[] quals)86 private void addQuality(byte[] quals){ 87 if(quals==null){return;} 88 if(length<quals.length){resize(quals.length);} 89 final long[] sum=acgtnq[5]; 90 for(int i=0; i<quals.length; i++){ 91 byte q=quals[i]; 92 sum[i]+=q; 93 } 94 } 95 resize(int newLen)96 private void resize(int newLen){ 97 assert(newLen>length); 98 length=newLen; 99 if(acgtnq[0]==null){ 100 for(int i=0; i<acgtnq.length; i++){ 101 acgtnq[i]=new long[newLen]; 102 } 103 }else{ 104 for(int i=0; i<acgtnq.length; i++){ 105 acgtnq[i]=Arrays.copyOf(acgtnq[i], newLen); 106 } 107 } 108 } 109 max(byte base)110 public float max(byte base) { 111 final int x=AminoAcid.baseToNumberACGTN[base]; 112 return(maxes[x]); 113 } 114 max(char base)115 public float max(char base) { 116 final int x=AminoAcid.baseToNumberACGTN[base]; 117 return(maxes[x]); 118 } 119 avg(byte base)120 public float avg(byte base) { 121 final int x=AminoAcid.baseToNumberACGTN[base]; 122 return(averages[x]); 123 } 124 avg(char base)125 public float avg(char base) { 126 final int x=AminoAcid.baseToNumberACGTN[base]; 127 return(averages[x]); 128 } 129 130 /*--------------------------------------------------------------*/ 131 132 public long[][] acgtnq=new long[6][]; 133 public float[][] cycleAverages=new float[6][]; 134 public float[] maxes; 135 public float[] averages; 136 public int length=0; 137 138 } 139