5 * Created by westcott on 9/8/09.
6 * Copyright 2009 Schloss Lab. All rights reserved.
10 #include "chimeracheckrdp.h"
12 //***************************************************************************************************************
13 ChimeraCheckRDP::ChimeraCheckRDP(string filename, string o) { fastafile = filename; outputDir = o; }
14 //***************************************************************************************************************
16 ChimeraCheckRDP::~ChimeraCheckRDP() {
22 m->errorOut(e, "ChimeraCheckRDP", "~AlignSim");
26 //***************************************************************************************************************
27 void ChimeraCheckRDP::print(ostream& out, ostream& outAcc) {
30 m->mothurOut("Processing: " + querySeq->getName()); m->mothurOutEndLine();
32 out << querySeq->getName() << endl;
33 out << "IS scores: " << '\t';
35 for (int k = 0; k < IS.size(); k++) {
36 out << IS[k].score << '\t';
41 if (name != "") { //if user has specific names
42 map<string, string>::iterator it = names.find(querySeq->getName());
44 if (it != names.end()) { //user wants pic of this
45 makeSVGpic(IS); //zeros out negative results
47 }else{//output them all
48 makeSVGpic(IS); //zeros out negative results
53 m->errorOut(e, "ChimeraCheckRDP", "print");
57 //***************************************************************************************************************
58 void ChimeraCheckRDP::doPrep() {
60 templateDB = new AlignmentDB(templateFileName, "kmer", kmerSize, 0.0,0.0,0.0,0.0);
61 m->mothurOutEndLine();
63 kmer = new Kmer(kmerSize);
66 readName(name); //fills name map with names of seqs the user wants to have .svg for.
70 m->errorOut(e, "ChimeraCheckRDP", "doPrep");
74 //***************************************************************************************************************
75 int ChimeraCheckRDP::getChimeras(Sequence* query) {
82 closest = templateDB->findClosestSequence(query);
86 //determine chimera report cutoff - window score above 95%
87 //getCutoff(); - not very acurate predictor
92 m->errorOut(e, "ChimeraCheckRDP", "getChimeras");
96 //***************************************************************************************************************
97 vector<sim> ChimeraCheckRDP::findIS() {
101 vector< map<int, int> > queryKmerInfo; //vector of maps - each entry in the vector is a map of the kmers up to that spot in the unaligned seq
102 //example: seqKmerInfo[50] = map containing the kmers found in the first 50 + kmersize characters of ecoli.
103 //i chose to store the kmers numbers in a map so you wouldn't have to check for dupilcate entries and could easily find the
104 //kmers 2 seqs had in common. There may be a better way to do this thats why I am leaving so many comments...
105 vector< map<int, int> > subjectKmerInfo;
107 vector<sim> isValues;
108 string queryName = querySeq->getName();
109 string seq = querySeq->getUnaligned();
111 queryKmerInfo = kmer->getKmerCounts(seq);
112 subjectKmerInfo = kmer->getKmerCounts(closest.getUnaligned());
114 //find total kmers you have in common with closest[query] by looking at the last entry in the vector of maps for each
115 int nTotal = calcKmers(queryKmerInfo[(queryKmerInfo.size()-1)], subjectKmerInfo[(subjectKmerInfo.size()-1)]);
117 //you don't want the starting point to be virtually at hte end so move it in 10%
118 int start = seq.length() / 10;
121 for (int f = start; f < (seq.length() - start); f+=increment) {
123 if ((f - kmerSize) < 0) { m->mothurOut("Your sequence is too short for your kmerSize."); m->mothurOutEndLine(); exit(1); }
127 string fragLeft = seq.substr(0, f); //left side of breakpoint
128 string fragRight = seq.substr(f); //right side of breakpoint
130 //make a sequence of the left side and right side
131 Sequence* left = new Sequence(queryName, fragLeft);
132 Sequence* right = new Sequence(queryName, fragRight);
134 //find seqs closest to each fragment
135 Sequence closestLeft = templateDB->findClosestSequence(left);
137 Sequence closestRight = templateDB->findClosestSequence(right);
139 //get kmerinfo for the closest left
140 vector< map<int, int> > closeLeftKmerInfo = kmer->getKmerCounts(closestLeft.getUnaligned());
142 //get kmerinfo for the closest right
143 vector< map<int, int> > closeRightKmerInfo = kmer->getKmerCounts(closestRight.getUnaligned());
145 //right side is tricky - since the counts grow on eachother to find the correct counts of only the right side you must subtract the counts of the left side
146 //iterate through left sides map to subtract the number of times you saw things before you got the the right side
147 map<int, int> rightside = queryKmerInfo[queryKmerInfo.size()-1];
148 for (map<int, int>::iterator itleft = queryKmerInfo[f-kmerSize].begin(); itleft != queryKmerInfo[f-kmerSize].end(); itleft++) {
149 int howManyTotal = queryKmerInfo[queryKmerInfo.size()-1][itleft->first]; //times that kmer was seen in total
151 //itleft->second is times it was seen in left side, so howmanytotal - leftside should give you right side
152 int howmanyright = howManyTotal - itleft->second;
154 //if any were seen just on the left erase
155 if (howmanyright == 0) {
156 rightside.erase(itleft->first);
160 map<int, int> closerightside = closeRightKmerInfo[closeRightKmerInfo.size()-1];
161 for (map<int, int>::iterator itright = closeRightKmerInfo[f-kmerSize].begin(); itright != closeRightKmerInfo[f-kmerSize].end(); itright++) {
162 int howManyTotal = closeRightKmerInfo[(closeRightKmerInfo.size()-1)][itright->first]; //times that kmer was seen in total
164 //itleft->second is times it was seen in left side, so howmanytotal - leftside should give you right side
165 int howmanyright = howManyTotal - itright->second;
167 //if any were seen just on the left erase
168 if (howmanyright == 0) {
169 closerightside.erase(itright->first);
174 int nLeft = calcKmers(closeLeftKmerInfo[f-kmerSize], queryKmerInfo[f-kmerSize]);
176 int nRight = calcKmers(closerightside, rightside);
178 int is = nLeft + nRight - nTotal;
180 //save IS, leftparent, rightparent, breakpoint
181 temp.leftParent = closestLeft.getName();
182 temp.rightParent = closestRight.getName();
186 isValues.push_back(temp);
195 catch(exception& e) {
196 m->errorOut(e, "ChimeraCheckRDP", "findIS");
200 //***************************************************************************************************************
201 void ChimeraCheckRDP::readName(string namefile) {
204 openInputFile(namefile, in);
217 catch(exception& e) {
218 m->errorOut(e, "ChimeraCheckRDP", "readName");
223 //***************************************************************************************************************
224 //find the smaller map and iterate through it and count kmers in common
225 int ChimeraCheckRDP::calcKmers(map<int, int> query, map<int, int> subject) {
229 map<int, int>::iterator small;
230 map<int, int>::iterator large;
232 if (query.size() < subject.size()) {
234 for (small = query.begin(); small != query.end(); small++) {
235 large = subject.find(small->first);
237 //if you found it they have that kmer in common
238 if (large != subject.end()) { common++; }
243 for (small = subject.begin(); small != subject.end(); small++) {
244 large = query.find(small->first);
246 //if you found it they have that kmer in common
247 if (large != query.end()) { common++; }
254 catch(exception& e) {
255 m->errorOut(e, "ChimeraCheckRDP", "calcKmers");
260 //***************************************************************************************************************
261 void ChimeraCheckRDP::makeSVGpic(vector<sim> info) {
264 string file = outputDir + querySeq->getName() + ".chimeracheck.svg";
266 openOutputFile(file, outsvg);
268 int width = (info.size()*5) + 150;
270 outsvg << "<svg xmlns:svg=\"http://www.w3.org/2000/svg\" xmlns=\"http://www.w3.org/2000/svg\" width=\"100%\" height=\"100%\" viewBox=\"0 0 700 " + toString(width) + "\">\n";
272 outsvg << "<text fill=\"black\" class=\"seri\" x=\"" + toString((width / 2) - 150) + "\" y=\"25\">Plotted IS values for " + querySeq->getName() + "</text>\n";
274 outsvg << "<line x1=\"75\" y1=\"600\" x2=\"" + toString((info.size()*5) + 75) + "\" y2=\"600\" stroke=\"black\" stroke-width=\"2\"/>\n";
275 outsvg << "<line x1=\"75\" y1=\"600\" x2=\"75\" y2=\"125\" stroke=\"black\" stroke-width=\"2\"/>\n";
277 outsvg << "<text fill=\"black\" class=\"seri\" x=\"80\" y=\"620\">" + toString(info[0].midpoint) + "</text>\n";
278 outsvg << "<text fill=\"black\" class=\"seri\" x=\"" + toString((info.size()*5) + 75) + "\" y=\"620\">" + toString(info[info.size()-1].midpoint) + "</text>\n";
279 outsvg << "<text fill=\"black\" class=\"seri\" x=\"" + toString((width / 2) - 150) + "\" y=\"650\">Base Positions</text>\n";
281 outsvg << "<text fill=\"black\" class=\"seri\" x=\"50\" y=\"580\">0</text>\n";
283 outsvg << "<text fill=\"black\" class=\"seri\" x=\"50\" y=\"350\">IS</text>\n";
288 for (int i = 0; i < info.size(); i++) {
289 if (info[i].score > biggest) {
290 biggest = info[i].score;
294 outsvg << "<text fill=\"black\" class=\"seri\" x=\"50\" y=\"135\">" + toString(biggest) + "</text>\n";
296 int scaler2 = 500 / biggest;
299 outsvg << "<polyline fill=\"none\" stroke=\"red\" stroke-width=\"2\" points=\"";
300 //160,200 180,230 200,210 234,220\"/> ";
301 for (int i = 0; i < info.size(); i++) {
302 if(info[i].score < 0) { info[i].score = 0; }
303 outsvg << ((i*5) + 75) << "," << (600 - (info[i].score * scaler2)) << " ";
307 outsvg << "</g>\n</svg>\n";
312 catch(exception& e) {
313 m->errorOut(e, "ChimeraCheckRDP", "makeSVGpic");
317 //***************************************************************************************************************