5 // Created by Sarah Westcott on 4/4/14.
6 // Copyright (c) 2014 Schloss Lab. All rights reserved.
11 /**************************************************************************************************/
13 Oligos::Oligos(string o){
15 m = MothurOut::getInstance();
16 hasPPrimers = false; hasPBarcodes = false; pairedOligos = false; reversePairs = true;
17 indexBarcode = 0; indexPairedBarcode = 0; indexPrimer = 0; indexPairedPrimer = 0;
21 numBarcodes = pairedBarcodes.size();
22 numFPrimers = pairedPrimers.size();
24 numBarcodes = barcodes.size();
25 numFPrimers = primers.size();
29 m->errorOut(e, "Oligos", "Oligos");
33 /**************************************************************************************************/
37 m = MothurOut::getInstance();
38 hasPPrimers = false; hasPBarcodes = false; pairedOligos = false; reversePairs = true;
39 indexBarcode = 0; indexPairedBarcode = 0; indexPrimer = 0; indexPairedPrimer = 0;
40 numFPrimers = 0; numBarcodes = 0;
43 m->errorOut(e, "Oligos", "Oligos");
47 /**************************************************************************************************/
48 int Oligos::read(string o){
53 numBarcodes = pairedBarcodes.size();
54 numFPrimers = pairedPrimers.size();
56 numBarcodes = barcodes.size();
57 numFPrimers = primers.size();
62 m->errorOut(e, "Oligos", "read");
66 /**************************************************************************************************/
67 int Oligos::read(string o, bool reverse){
70 reversePairs = reverse;
73 numBarcodes = pairedBarcodes.size();
74 numFPrimers = pairedPrimers.size();
76 numBarcodes = barcodes.size();
77 numFPrimers = primers.size();
82 m->errorOut(e, "Oligos", "read");
86 //***************************************************************************************************************
88 int Oligos::readOligos(){
91 m->openInputFile(oligosfile, inOligos);
93 string type, oligo, roligo, group;
95 while(!inOligos.eof()){
99 if (m->debug) { m->mothurOut("[DEBUG]: reading type - " + type + ".\n"); }
102 while (!inOligos.eof()) { char c = inOligos.get(); if (c == 10 || c == 13){ break; } } // get rest of line if there's any crap there
107 //make type case insensitive
108 for(int i=0;i<type.length();i++){ type[i] = toupper(type[i]); }
112 if (m->debug) { m->mothurOut("[DEBUG]: reading - " + oligo + ".\n"); }
114 for(int i=0;i<oligo.length();i++){
115 oligo[i] = toupper(oligo[i]);
116 if(oligo[i] == 'U') { oligo[i] = 'T'; }
119 if(type == "FORWARD"){
122 // get rest of line in case there is a primer name
123 while (!inOligos.eof()) {
124 char c = inOligos.get();
125 if (c == 10 || c == 13 || c == -1){ break; }
126 else if (c == 32 || c == 9){;} //space or tab
130 //check for repeat barcodes
131 map<string, int>::iterator itPrime = primers.find(oligo);
132 if (itPrime != primers.end()) { m->mothurOut("[WARNING]: primer " + oligo + " is in your oligos file already."); m->mothurOutEndLine(); }
134 if (m->debug) { if (group != "") { m->mothurOut("[DEBUG]: reading group " + group + ".\n"); }else{ m->mothurOut("[DEBUG]: no group for primer " + oligo + ".\n"); } }
136 primers[oligo]=indexPrimer; indexPrimer++;
137 primerNameVector.push_back(group);
139 else if (type == "PRIMER"){
144 for(int i=0;i<roligo.length();i++){
145 roligo[i] = toupper(roligo[i]);
146 if(roligo[i] == 'U') { roligo[i] = 'T'; }
148 if (reversePairs) { roligo = reverseOligo(roligo); }
151 // get rest of line in case there is a primer name
152 while (!inOligos.eof()) {
153 char c = inOligos.get();
154 if (c == 10 || c == 13 || c == -1){ break; }
155 else if (c == 32 || c == 9){;} //space or tab
159 oligosPair newPrimer(oligo, roligo);
161 if (m->debug) { m->mothurOut("[DEBUG]: primer pair " + newPrimer.forward + " " + newPrimer.reverse + ", and group = " + group + ".\n"); }
163 //check for repeat barcodes
164 string tempPair = oligo+roligo;
165 if (uniquePrimers.count(tempPair) != 0) { m->mothurOut("primer pair " + newPrimer.forward + " " + newPrimer.reverse + " is in your oligos file already."); m->mothurOutEndLine(); }
166 else { uniquePrimers.insert(tempPair); }
168 if (m->debug) { if (group != "") { m->mothurOut("[DEBUG]: reading group " + group + ".\n"); }else{ m->mothurOut("[DEBUG]: no group for primer pair " + newPrimer.forward + " " + newPrimer.reverse + ".\n"); } }
170 pairedPrimers[indexPairedPrimer]=newPrimer; indexPairedPrimer++;
171 primerNameVector.push_back(group);
174 else if(type == "REVERSE"){
175 string oligoRC = reverseOligo(oligo);
176 revPrimer.push_back(oligoRC);
178 else if(type == "BARCODE"){
181 //barcode lines can look like BARCODE atgcatgc groupName - for 454 seqs
182 //or BARCODE atgcatgc atgcatgc groupName - for illumina data that has forward and reverse info
185 while (!inOligos.eof()) {
186 char c = inOligos.get();
187 if (c == 10 || c == 13 || c == -1){ break; }
188 else if (c == 32 || c == 9){;} //space or tab
192 //then this is illumina data with 4 columns
195 string reverseBarcode = group; //reverseOligo(group); //reverse barcode
198 for(int i=0;i<reverseBarcode.length();i++){
199 reverseBarcode[i] = toupper(reverseBarcode[i]);
200 if(reverseBarcode[i] == 'U') { reverseBarcode[i] = 'T'; }
203 if (reversePairs) { reverseBarcode = reverseOligo(reverseBarcode); }
204 oligosPair newPair(oligo, reverseBarcode);
206 if (m->debug) { m->mothurOut("[DEBUG]: barcode pair " + newPair.forward + " " + newPair.reverse + ", and group = " + group + ".\n"); }
208 //check for repeat barcodes
209 string tempPair = oligo+reverseBarcode;
210 if (uniqueBarcodes.count(tempPair) != 0) { m->mothurOut("barcode pair " + newPair.forward + " " + newPair.reverse + " is in your oligos file already, disregarding."); m->mothurOutEndLine(); }
211 else { uniqueBarcodes.insert(tempPair); }
213 pairedBarcodes[indexPairedBarcode]=newPair; indexPairedBarcode++;
214 barcodeNameVector.push_back(group);
216 //check for repeat barcodes
217 map<string, int>::iterator itBar = barcodes.find(oligo);
218 if (itBar != barcodes.end()) { m->mothurOut("[WARNING]: barcode " + oligo + " is in your oligos file already."); m->mothurOutEndLine(); }
220 barcodes[oligo]=indexBarcode; indexBarcode++;
221 barcodeNameVector.push_back(group);
223 }else if(type == "LINKER"){
224 linker.push_back(oligo);
225 }else if(type == "SPACER"){
226 spacer.push_back(oligo);
228 else{ m->mothurOut("[WARNING]: " + type + " is not recognized as a valid type. Choices are forward, reverse, and barcode. Ignoring " + oligo + "."); m->mothurOutEndLine(); }
234 if (hasPBarcodes || hasPPrimers) {
236 if ((primers.size() != 0) || (barcodes.size() != 0) || (linker.size() != 0) || (spacer.size() != 0) || (revPrimer.size() != 0)) { m->control_pressed = true; m->mothurOut("[ERROR]: cannot mix paired primers and barcodes with non paired or linkers and spacers, quitting."); m->mothurOutEndLine(); return 0; }
240 //add in potential combos
241 if(barcodeNameVector.size() == 0){
243 oligosPair newPair("", "");
244 pairedBarcodes[0] = newPair;
248 barcodeNameVector.push_back("");
251 if(primerNameVector.size() == 0){
253 oligosPair newPair("", "");
254 pairedPrimers[0] = newPair;
258 primerNameVector.push_back("");
263 for(map<int, oligosPair>::iterator itBar = pairedBarcodes.begin();itBar != pairedBarcodes.end();itBar++){
264 for(map<int, oligosPair>::iterator itPrimer = pairedPrimers.begin();itPrimer != pairedPrimers.end(); itPrimer++){
266 string primerName = primerNameVector[itPrimer->first];
267 string barcodeName = barcodeNameVector[itBar->first];
269 if (m->debug) { m->mothurOut("[DEBUG]: primerName = " + primerName + " barcodeName = " + barcodeName + "\n"); }
271 if ((primerName == "ignore") || (barcodeName == "ignore")) { if (m->debug) { m->mothurOut("[DEBUG]: in ignore. \n"); } } //do nothing
272 else if ((primerName == "") && (barcodeName == "")) { if (m->debug) { m->mothurOut("[DEBUG]: in blank. \n"); } } //do nothing
274 string comboGroupName = "";
275 string fastqFileName = "";
277 if(primerName == ""){
278 comboGroupName = barcodeNameVector[itBar->first];
281 if(barcodeName == ""){
282 comboGroupName = primerNameVector[itPrimer->first];
285 comboGroupName = barcodeNameVector[itBar->first] + "." + primerNameVector[itPrimer->first];
289 if (m->debug) { m->mothurOut("[DEBUG]: comboGroupName = " + comboGroupName + "\n"); }
291 uniqueNames.insert(comboGroupName);
293 map<string, vector<string> >::iterator itGroup2Barcode = Group2Barcode.find(comboGroupName);
294 if (itGroup2Barcode == Group2Barcode.end()) {
295 vector<string> tempBarcodes; tempBarcodes.push_back((itBar->second).forward+"."+(itBar->second).reverse);
296 Group2Barcode[comboGroupName] = tempBarcodes;
298 Group2Barcode[comboGroupName].push_back((itBar->second).forward+"."+(itBar->second).reverse);
301 itGroup2Barcode = Group2Primer.find(comboGroupName);
302 if (itGroup2Barcode == Group2Primer.end()) {
303 vector<string> tempPrimers; tempPrimers.push_back((itPrimer->second).forward+"."+(itPrimer->second).reverse);
304 Group2Primer[comboGroupName] = tempPrimers;
306 Group2Primer[comboGroupName].push_back((itPrimer->second).forward+"."+(itPrimer->second).reverse);
312 for(map<string, int>::iterator itBar = barcodes.begin();itBar != barcodes.end();itBar++){
313 for(map<string, int>::iterator itPrimer = primers.begin();itPrimer != primers.end(); itPrimer++){
315 string primerName = primerNameVector[itPrimer->second];
316 string barcodeName = barcodeNameVector[itBar->second];
318 if ((primerName == "ignore") || (barcodeName == "ignore")) { } //do nothing
319 else if ((primerName == "") && (barcodeName == "")) { } //do nothing
321 string comboGroupName = "";
322 string fastqFileName = "";
324 if(primerName == ""){
325 comboGroupName = barcodeNameVector[itBar->second];
328 if(barcodeName == ""){
329 comboGroupName = primerNameVector[itPrimer->second];
332 comboGroupName = barcodeNameVector[itBar->second] + "." + primerNameVector[itPrimer->second];
335 uniqueNames.insert(comboGroupName);
337 map<string, vector<string> >::iterator itGroup2Barcode = Group2Barcode.find(comboGroupName);
338 if (itGroup2Barcode == Group2Barcode.end()) {
339 vector<string> tempBarcodes; tempBarcodes.push_back(itBar->first);
340 Group2Barcode[comboGroupName] = tempBarcodes;
342 Group2Barcode[comboGroupName].push_back(itBar->first);
345 itGroup2Barcode = Group2Primer.find(comboGroupName);
346 if (itGroup2Barcode == Group2Primer.end()) {
347 vector<string> tempPrimers; tempPrimers.push_back(itPrimer->first);
348 Group2Primer[comboGroupName] = tempPrimers;
350 Group2Primer[comboGroupName].push_back(itPrimer->first);
358 if (m->debug) { int count = 0; for (set<string>::iterator it = uniqueNames.begin(); it != uniqueNames.end(); it++) { m->mothurOut("[DEBUG]: " + toString(count) + " groupName = " + *it + "\n"); count++; } }
362 for (set<string>::iterator it = uniqueNames.begin(); it != uniqueNames.end(); it++) { Groups.push_back(*it); }
366 catch(exception& e) {
367 m->errorOut(e, "Oligos", "readOligos");
371 //********************************************************************/
372 vector<string> Oligos::getBarcodes(string groupName){
374 vector<string> thisGroupsBarcodes;
376 map<string, vector<string> >::iterator it = Group2Barcode.find(groupName);
378 if (it == Group2Barcode.end()) { m->mothurOut("[ERROR]: no barcodes found for group " + groupName + ".\n"); m->control_pressed=true;
379 }else { thisGroupsBarcodes = it->second; }
381 return thisGroupsBarcodes;
383 catch(exception& e) {
384 m->errorOut(e, "Oligos", "getBarcodes");
388 //********************************************************************/
389 vector<string> Oligos::getPrimers(string groupName){
391 vector<string> thisGroupsPrimers;
393 map<string, vector<string> >::iterator it = Group2Primer.find(groupName);
395 if (it == Group2Primer.end()) { m->mothurOut("[ERROR]: no primers found for group " + groupName + ".\n"); m->control_pressed=true;
396 }else { thisGroupsPrimers = it->second; }
398 return thisGroupsPrimers;
400 catch(exception& e) {
401 m->errorOut(e, "Oligos", "getPrimers");
405 //********************************************************************/
406 //can't have paired and unpaired so this function will either run the paired map or the unpaired
407 map<int, oligosPair> Oligos::getReorientedPairedPrimers(){
409 map<int, oligosPair> rpairedPrimers;
411 for (map<int, oligosPair>::iterator it = pairedPrimers.begin(); it != pairedPrimers.end(); it++) {
412 string forward = (it->second).reverse;
413 if (reversePairs) { forward = reverseOligo(forward); }
414 string reverse = (it->second).forward;
415 if (reversePairs) { reverse = reverseOligo(reverse); }
416 oligosPair tempPair(forward, reverse); //reversePrimer, rc ForwardPrimer
417 rpairedPrimers[it->first] = tempPair;
421 for (map<string, int>::iterator it = primers.begin(); it != primers.end(); it++) {
422 oligosPair tempPair("", reverseOligo((it->first))); //reverseBarcode, rc ForwardBarcode
423 rpairedPrimers[it->second] = tempPair;
426 return rpairedPrimers;
428 catch(exception& e) {
429 m->errorOut(e, "Oligos", "getReorientedPairedPrimers");
433 //********************************************************************/
434 //can't have paired and unpaired so this function will either run the paired map or the unpaired
435 map<int, oligosPair> Oligos::getReorientedPairedBarcodes(){
437 map<int, oligosPair> rpairedBarcodes;
439 for (map<int, oligosPair>::iterator it = pairedBarcodes.begin(); it != pairedBarcodes.end(); it++) {
440 string forward = (it->second).reverse;
441 if (reversePairs) { forward = reverseOligo(forward); }
442 string reverse = (it->second).forward;
443 if (reversePairs) { reverse = reverseOligo(reverse); }
444 oligosPair tempPair(forward, reverse); //reversePrimer, rc ForwardPrimer
445 rpairedBarcodes[it->first] = tempPair;
448 for (map<string, int>::iterator it = barcodes.begin(); it != barcodes.end(); it++) {
449 oligosPair tempPair("", reverseOligo((it->first))); //reverseBarcode, rc ForwardBarcode
450 rpairedBarcodes[it->second] = tempPair;
453 return rpairedBarcodes;
455 catch(exception& e) {
456 m->errorOut(e, "Oligos", "getReorientedPairedBarcodes");
461 //********************************************************************/
462 string Oligos::reverseOligo(string oligo){
466 for(int i=oligo.length()-1;i>=0;i--){
468 if(oligo[i] == 'A') { reverse += 'T'; }
469 else if(oligo[i] == 'T'){ reverse += 'A'; }
470 else if(oligo[i] == 'U'){ reverse += 'A'; }
472 else if(oligo[i] == 'G'){ reverse += 'C'; }
473 else if(oligo[i] == 'C'){ reverse += 'G'; }
475 else if(oligo[i] == 'R'){ reverse += 'Y'; }
476 else if(oligo[i] == 'Y'){ reverse += 'R'; }
478 else if(oligo[i] == 'M'){ reverse += 'K'; }
479 else if(oligo[i] == 'K'){ reverse += 'M'; }
481 else if(oligo[i] == 'W'){ reverse += 'W'; }
482 else if(oligo[i] == 'S'){ reverse += 'S'; }
484 else if(oligo[i] == 'B'){ reverse += 'V'; }
485 else if(oligo[i] == 'V'){ reverse += 'B'; }
487 else if(oligo[i] == 'D'){ reverse += 'H'; }
488 else if(oligo[i] == 'H'){ reverse += 'D'; }
490 else { reverse += 'N'; }
496 catch(exception& e) {
497 m->errorOut(e, "Oligos", "reverseOligo");
501 //********************************************************************/
502 string Oligos::getBarcodeName(int index){
506 if ((index >= 0) && (index < barcodeNameVector.size())) { name = barcodeNameVector[index]; }
510 catch(exception& e) {
511 m->errorOut(e, "Oligos", "getBarcodeName");
515 //********************************************************************/
516 string Oligos::getPrimerName(int index){
520 if ((index >= 0) && (index < primerNameVector.size())) { name = primerNameVector[index]; }
524 catch(exception& e) {
525 m->errorOut(e, "Oligos", "getPrimerName");
529 //********************************************************************/
530 string Oligos::getGroupName(int barcodeIndex, int primerIndex){
533 string thisGroup = "";
534 if(numBarcodes != 0){
535 thisGroup = getBarcodeName(barcodeIndex);
536 if (numFPrimers != 0) {
537 if (getPrimerName(primerIndex) != "") {
538 if(thisGroup != "") {
539 thisGroup += "." + getPrimerName(primerIndex);
541 thisGroup = getPrimerName(primerIndex);
549 catch(exception& e) {
550 m->errorOut(e, "Oligos", "getGroupName");
555 /**************************************************************************************************/