CommandParameter pmintm("mintm", "Number", "", "-1", "", "", "","",false,false); parameters.push_back(pmintm);
CommandParameter pmaxtm("maxtm", "Number", "", "-1", "", "", "","",false,false); parameters.push_back(pmaxtm);
CommandParameter pprocessors("processors", "Number", "", "1", "", "", "","",false,false); parameters.push_back(pprocessors);
- CommandParameter potunumber("otunumber", "Number", "", "-1", "", "", "","",false,true,true); parameters.push_back(potunumber);
+ CommandParameter potunumber("otulabel", "String", "", "", "", "", "","",false,true,true); parameters.push_back(potunumber);
CommandParameter ppdiffs("pdiffs", "Number", "", "0", "", "", "","",false,false,true); parameters.push_back(ppdiffs);
CommandParameter pcutoff("cutoff", "Number", "", "100", "", "", "","",false,false); parameters.push_back(pcutoff);
CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
try {
string helpString = "";
helpString += "The primer.design allows you to identify sequence fragments that are specific to particular OTUs.\n";
- helpString += "The primer.design command parameters are: list, fasta, name, count, otunumber, cutoff, length, pdiffs, mintm, maxtm, processors and label.\n";
+ helpString += "The primer.design command parameters are: list, fasta, name, count, otulabel, cutoff, length, pdiffs, mintm, maxtm, processors and label.\n";
helpString += "The list parameter allows you to provide a list file and is required.\n";
helpString += "The fasta parameter allows you to provide a fasta file and is required.\n";
helpString += "The name parameter allows you to provide a name file associated with your fasta file.\n";
helpString += "The count parameter allows you to provide a count file associated with your fasta file.\n";
helpString += "The label parameter is used to indicate the label you want to use from your list file.\n";
- helpString += "The otunumber parameter is used to indicate the otu you want to use from your list file. It is required.\n";
+ helpString += "The otulabel parameter is used to indicate the otu you want to use from your list file. It is required.\n";
helpString += "The pdiffs parameter is used to specify the number of differences allowed in the primer. The default is 0.\n";
helpString += "The length parameter is used to indicate the length of the primer. The default is 18.\n";
helpString += "The mintm parameter is used to indicate minimum melting temperature.\n";
temp = validParameter.validFile(parameters, "maxtm", false); if (temp == "not found") { temp = "-1"; }
m->mothurConvert(temp, maxTM);
- temp = validParameter.validFile(parameters, "otunumber", false); if (temp == "not found") { temp = "-1"; }
- m->mothurConvert(temp, otunumber);
- if (otunumber < 1) { m->mothurOut("[ERROR]: You must provide an OTU number, aborting.\n"); abort = true; }
+ otulabel = validParameter.validFile(parameters, "otulabel", false); if (otulabel == "not found") { temp = ""; }
+ if (otulabel == "") { m->mothurOut("[ERROR]: You must provide an OTU label, aborting.\n"); abort = true; }
temp = validParameter.validFile(parameters, "processors", false); if (temp == "not found"){ temp = m->getProcessors(); }
m->setProcessors(temp);
//reads list file and selects the label the users specified or the first label
getListVector();
- if (otunumber > list->getNumBins()) { m->mothurOut("[ERROR]: You selected an OTU number larger than the number of OTUs you have in your list file, quitting.\n"); return 0; }
+ vector<string> binLabels = list->getLabels();
+ int binIndex = findIndex(otulabel, binLabels);
+ if (binIndex == -1) { m->mothurOut("[ERROR]: You selected an OTU label that is not in your in your list file, quitting.\n"); return 0; }
map<string, int> nameMap;
unsigned long int numSeqs; //used to sanity check the files. numSeqs = total seqs for namefile and uniques for count.
m->mothurOut("Done.\n\n");
- set<string> primers = getPrimer(conSeqs[otunumber-1]);
+ set<string> primers = getPrimer(conSeqs[binIndex]);
if (m->control_pressed) { delete list; for (int i = 0; i < outputNames.size(); i++) { m->mothurRemove(outputNames[i]); } return 0; }
ofstream outSum;
m->openOutputFile(consSummaryFile, outSum);
- outSum << "PrimerOtu: " << otunumber << " Members: " << list->get(otunumber-1) << endl << "Primers\tminTm\tmaxTm" << endl;
+ outSum << "PrimerOtu: " << otulabel << " Members: " << list->get(binIndex) << endl << "Primers\tminTm\tmaxTm" << endl;
//find min and max melting points
vector<double> minTms;
outSum.close();
//check each otu's conseq for each primer in otunumber
- set<int> otuToRemove = createProcesses(consSummaryFile, minTms, maxTms, primers, conSeqs);
+ set<int> otuToRemove = createProcesses(consSummaryFile, minTms, maxTms, primers, conSeqs, binIndex);
if (m->control_pressed) { delete list; for (int i = 0; i < outputNames.size(); i++) { m->mothurRemove(outputNames[i]); } return 0; }
mvariables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(listfile));
mvariables["[extension]"] = m->getExtension(listfile);
string newListFile = getOutputFileName("list", mvariables);
- outputNames.push_back(newListFile); outputTypes["list"].push_back(newListFile);
- ofstream outList;
- m->openOutputFile(newListFile, outList);
+ ofstream outListTemp;
+ m->openOutputFile(newListFile+".temp", outListTemp);
- outList << list->getLabel() << '\t' << (list->getNumBins()-otuToRemove.size()) << '\t';
+ outListTemp << list->getLabel() << '\t' << (list->getNumBins()-otuToRemove.size()) << '\t';
+ string headers = "label\tnumOtus\t";
for (int j = 0; j < list->getNumBins(); j++) {
if (m->control_pressed) { break; }
//good otus
if (otuToRemove.count(j) == 0) {
string bin = list->get(j);
- if (bin != "") { outList << bin << '\t'; }
+ if (bin != "") { outListTemp << bin << '\t'; headers += binLabels[j] + '\t'; }
}
}
- outList << endl;
+ outListTemp << endl;
+ outListTemp.close();
+
+ ofstream outList;
+ m->openOutputFile(newListFile, outList);
+ outList << headers << endl;
outList.close();
+ m->appendFiles(newListFile+".temp", newListFile);
+ m->mothurRemove(newListFile+".temp");
+ outputNames.push_back(newListFile); outputTypes["list"].push_back(newListFile);
if (m->control_pressed) { delete list; for (int i = 0; i < outputNames.size(); i++) { m->mothurRemove(outputNames[i]); } return 0; }
}
}
/**************************************************************************************************/
-set<int> PrimerDesignCommand::createProcesses(string newSummaryFile, vector<double>& minTms, vector<double>& maxTms, set<string>& primers, vector<Sequence>& conSeqs) {
+set<int> PrimerDesignCommand::createProcesses(string newSummaryFile, vector<double>& minTms, vector<double>& maxTms, set<string>& primers, vector<Sequence>& conSeqs, int binIndex) {
try {
vector<int> processIDS;
//clear old file because we append in driver
m->mothurRemove(newSummaryFile + toString(getpid()) + ".temp");
- otusToRemove = driver(newSummaryFile + toString(getpid()) + ".temp", minTms, maxTms, primers, conSeqs, lines[process].start, lines[process].end, numBinsProcessed);
+ otusToRemove = driver(newSummaryFile + toString(getpid()) + ".temp", minTms, maxTms, primers, conSeqs, lines[process].start, lines[process].end, numBinsProcessed, binIndex);
string tempFile = toString(getpid()) + ".otus2Remove.temp";
ofstream outTemp;
}
//do my part
- otusToRemove = driver(newSummaryFile, minTms, maxTms, primers, conSeqs, lines[0].start, lines[0].end, numBinsProcessed);
+ otusToRemove = driver(newSummaryFile, minTms, maxTms, primers, conSeqs, lines[0].start, lines[0].end, numBinsProcessed, binIndex);
//force parent to wait until all the processes are done
for (int i=0;i<processIDS.size();i++) {
string extension = toString(i) + ".temp";
m->mothurRemove(newSummaryFile+extension);
- primerDesignData* tempPrimer = new primerDesignData((newSummaryFile+extension), m, lines[i].start, lines[i].end, minTms, maxTms, primers, conSeqs, pdiffs, otunumber, length, i);
+ primerDesignData* tempPrimer = new primerDesignData((newSummaryFile+extension), m, lines[i].start, lines[i].end, minTms, maxTms, primers, conSeqs, pdiffs, binIndex, length, i);
pDataArray.push_back(tempPrimer);
processIDS.push_back(i);
//using the main process as a worker saves time and memory
- otusToRemove = driver(newSummaryFile, minTms, maxTms, primers, conSeqs, lines[0].start, lines[0].end, numBinsProcessed);
+ otusToRemove = driver(newSummaryFile, minTms, maxTms, primers, conSeqs, lines[0].start, lines[0].end, numBinsProcessed, binIndex);
//Wait until all threads have terminated.
WaitForMultipleObjects(processors-1, hThreadArray, TRUE, INFINITE);
}
}
//**********************************************************************************************************************
-set<int> PrimerDesignCommand::driver(string summaryFileName, vector<double>& minTms, vector<double>& maxTms, set<string>& primers, vector<Sequence>& conSeqs, int start, int end, int& numBinsProcessed){
+set<int> PrimerDesignCommand::driver(string summaryFileName, vector<double>& minTms, vector<double>& maxTms, set<string>& primers, vector<Sequence>& conSeqs, int start, int end, int& numBinsProcessed, int binIndex){
try {
set<int> otuToRemove;
if (m->control_pressed) { break; }
- if (i != (otunumber-1)) {
+ if (i != (binIndex)) {
int primerIndex = 0;
for (set<string>::iterator it = primers.begin(); it != primers.end(); it++) {
vector<int> primerStarts;
}
}
//**********************************************************************************************************************
+int PrimerDesignCommand::findIndex(string binLabel, vector<string> binLabels){
+ try {
+ int index = -1;
+ for (int i = 0; i < binLabels.size(); i++){
+ if (m->control_pressed) { return index; }
+ if (m->isLabelEquivalent(binLabel, binLabels[i])) { index = i; break; }
+ }
+ return index;
+ }
+ catch(exception& e) {
+ m->errorOut(e, "PrimerDesignCommand", "findIndex");
+ exit(1);
+ }
+}
+//**********************************************************************************************************************