]> git.donarmstrong.com Git - mothur.git/blobdiff - sensspeccommand.cpp
sffinfo bug with flow grams right index when clipQualRight=0
[mothur.git] / sensspeccommand.cpp
index 82922ededbff38fd76909d1694742c6adac7666b..f61232a26c133fb9d0cebfa9cdcca31fdfe2f0dc 100644 (file)
 //**********************************************************************************************************************
 vector<string> SensSpecCommand::setParameters(){       
        try {
-               CommandParameter plist("list", "InputTypes", "", "", "none", "none", "none",false,true); parameters.push_back(plist);
-               CommandParameter pphylip("phylip", "InputTypes", "", "", "PhylipColumn", "PhylipColumn", "none",false,false); parameters.push_back(pphylip);
-               //CommandParameter pname("name", "InputTypes", "", "", "none", "none", "ColumnName",false,false); parameters.push_back(pname);
-               CommandParameter pcolumn("column", "InputTypes", "", "", "PhylipColumn", "PhylipColumn", "none",false,false); parameters.push_back(pcolumn);
-               CommandParameter plabel("label", "String", "", "", "", "", "",false,false); parameters.push_back(plabel);
-               CommandParameter pcutoff("cutoff", "Number", "", "-1.00", "", "", "",false,false); parameters.push_back(pcutoff);
-               CommandParameter pprecision("precision", "Number", "", "100", "", "", "",false,false); parameters.push_back(pprecision);
-               CommandParameter phard("hard", "Boolean", "", "F", "", "", "",false,false); parameters.push_back(phard);
-               CommandParameter pinputdir("inputdir", "String", "", "", "", "", "",false,false); parameters.push_back(pinputdir);
-               CommandParameter poutputdir("outputdir", "String", "", "", "", "", "",false,false); parameters.push_back(poutputdir);
+               CommandParameter plist("list", "InputTypes", "", "", "none", "none", "none","sensspec",false,true,true); parameters.push_back(plist);
+               CommandParameter pphylip("phylip", "InputTypes", "", "", "PhylipColumn", "PhylipColumn", "none","",false,false); parameters.push_back(pphylip);
+               CommandParameter pcolumn("column", "InputTypes", "", "", "PhylipColumn", "PhylipColumn", "none","",false,false); parameters.push_back(pcolumn);
+               CommandParameter plabel("label", "String", "", "", "", "", "","",false,false); parameters.push_back(plabel);
+               CommandParameter pcutoff("cutoff", "Number", "", "-1.00", "", "", "","",false,false); parameters.push_back(pcutoff);
+               CommandParameter pprecision("precision", "Number", "", "100", "", "", "","",false,false); parameters.push_back(pprecision);
+               CommandParameter phard("hard", "Boolean", "", "T", "", "", "","",false,false); parameters.push_back(phard);
+               CommandParameter pinputdir("inputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(pinputdir);
+               CommandParameter poutputdir("outputdir", "String", "", "", "", "", "","",false,false); parameters.push_back(poutputdir);
                
                vector<string> myArray;
                for (int i = 0; i < parameters.size(); i++) {   myArray.push_back(parameters[i].name);          }
@@ -45,6 +44,21 @@ string SensSpecCommand::getHelpString(){
        }
 }
 //**********************************************************************************************************************
+string SensSpecCommand::getOutputPattern(string type) {
+    try {
+        string pattern = "";
+        
+        if (type == "sensspec") {  pattern = "[filename],sensspec"; } 
+        else { m->mothurOut("[ERROR]: No definition for type " + type + " output pattern.\n"); m->control_pressed = true;  }
+        
+        return pattern;
+    }
+    catch(exception& e) {
+        m->errorOut(e, "SensSpecCommand", "getOutputPattern");
+        exit(1);
+    }
+}
+//**********************************************************************************************************************
 SensSpecCommand::SensSpecCommand(){    
        try {
                abort = true; calledHelp = true; 
@@ -116,16 +130,7 @@ SensSpecCommand::SensSpecCommand(string option)  {
                                        path = m->hasPath(it->second);
                                        //if the user has not given a path then, add inputdir. else leave path alone.
                                        if (path == "") {       parameters["column"] = inputDir + it->second;           }
-                               }
-                               
-                               //it = parameters.find("name");
-                               //user has given a template file
-                               //if(it != parameters.end()){ 
-                                       //path = m->hasPath(it->second);
-                                       //if the user has not given a path then, add inputdir. else leave path alone.
-                                       //if (path == "") {     parameters["name"] = inputDir + it->second;             }
-                               //}
-                               
+                               }                               
                        }
                        //check for required parameters
                        listFile = validParameter.validFile(parameters, "list", true);
@@ -176,12 +181,6 @@ SensSpecCommand::SensSpecCommand(string option)  {
                        else if(!m->isTrue(temp))       {       hard = 0;       }
                        else if(m->isTrue(temp))        {       hard = 1;       }
                        
-//                     temp = validParameter.validFile(parameters, "name", true);
-//                     if (temp == "not found")        {       nameFile = "";          }
-//                     else if(temp == "not open")     {       abort = true;           }
-//                     else                                            {       nameFile = temp;        }
-//                     cout << "name:\t" << nameFile << endl;
-
                        temp = validParameter.validFile(parameters, "cutoff", false);           if (temp == "not found") { temp = "-1.00"; }
                        m->mothurConvert(temp, cutoff);  
 //                     cout << cutoff << endl;
@@ -197,7 +196,9 @@ SensSpecCommand::SensSpecCommand(string option)  {
                                else { allLines = 1;  }
                        }
                        
-                       sensSpecFileName = outputDir + m->getRootName(m->getSimpleName(listFile)) + "sensspec";
+            map<string, string> variables; 
+            variables["[filename]"] = outputDir + m->getRootName(m->getSimpleName(listFile));
+                       sensSpecFileName = getOutputFileName("sensspec",variables);
                }
        }
        catch(exception& e) {
@@ -210,16 +211,27 @@ SensSpecCommand::SensSpecCommand(string option)  {
 int SensSpecCommand::execute(){
        try{
                if (abort == true) { if (calledHelp) { return 0; }  return 2;   }
-
+        
+        int startTime = time(NULL);
+        
+        //create list file with only unique names, saves time and memory by removing redundant names from list file that are not in the distance file.
+        string newListFile = preProcessList();
+        if (newListFile != "") { listFile = newListFile; }
+        
                setUpOutput();
                outputNames.push_back(sensSpecFileName); outputTypes["sensspec"].push_back(sensSpecFileName);
                if(format == "phylip")          {       processPhylip();        }
                else if(format == "column")     {       processColumn();        }
                
+        //remove temp file if created
+        if (newListFile != "") { m->mothurRemove(newListFile); }
+        
                if (m->control_pressed) { m->mothurRemove(sensSpecFileName); return 0; }
-               
+        
+        m->mothurOut("It took " + toString(time(NULL) - startTime) + " to run sens.spec."); m->mothurOutEndLine();
+        
                m->mothurOutEndLine();
-               m->mothurOut("Output File Name: "); m->mothurOutEndLine();
+               m->mothurOut("Output File Names: "); m->mothurOutEndLine();
                m->mothurOut(sensSpecFileName); m->mothurOutEndLine();  
                m->mothurOutEndLine();
                
@@ -256,7 +268,9 @@ int SensSpecCommand::processPhylip(){
                
                while((list != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {
                        
-                       if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) {        m->mothurRemove(outputNames[i]);  }  delete list;  return 0;  }
+                       if(m->control_pressed){
+                for (int i = 0; i < outputNames.size(); i++){  m->mothurRemove(outputNames[i]);  }  delete list;  return 0;
+            }
                        
                        if(allLines == 1 || labels.count(list->getLabel()) == 1){                       
                                
@@ -324,7 +338,9 @@ int SensSpecCommand::processPhylip(){
                exit(1);
        }
 }
+
 //***************************************************************************************************************
+
 int SensSpecCommand::fillSeqMap(map<string, int>& seqMap, ListVector*& list){
        try {
                //for each otu
@@ -387,7 +403,7 @@ int SensSpecCommand::fillSeqPairSet(set<string>& seqPairSet, ListVector*& list){
                return numSeqs;
        }
        catch(exception& e) {
-               m->errorOut(e, "SensSpecCommand", "fillSeqMap");
+               m->errorOut(e, "SensSpecCommand", "fillSeqPairSet");
                exit(1);
        }
 }
@@ -401,7 +417,7 @@ int SensSpecCommand::process(map<string, int>& seqMap, string label, bool& getCu
                ifstream phylipFile;
                m->openInputFile(distFile, phylipFile);
                phylipFile >> pNumSeqs;
-               if(pNumSeqs != lNumSeqs){       m->mothurOut("numSeq mismatch!\n"); m->control_pressed = true; }
+               if(pNumSeqs != lNumSeqs){       m->mothurOut("numSeq mismatch!\n"); /*m->control_pressed = true;*/ }
                
                string seqName;
                double distance;
@@ -426,7 +442,7 @@ int SensSpecCommand::process(map<string, int>& seqMap, string label, bool& getCu
                
                m->mothurOut(label); m->mothurOutEndLine();
                
-               for(int i=0;i<lNumSeqs;i++){
+               for(int i=0;i<pNumSeqs;i++){
                        
                        if (m->control_pressed) { return 0; }
                        
@@ -679,6 +695,122 @@ void SensSpecCommand::outputStatistics(string label, string cutoff){
                exit(1);
        }
 }
+//***************************************************************************************************************
+
+string SensSpecCommand::preProcessList(){
+    try {
+        set<string> uniqueNames;
+        //get unique names from distance file
+        if (format == "phylip") {
+            
+            ifstream phylipFile;
+            m->openInputFile(distFile, phylipFile);
+            string numTest;
+            int pNumSeqs;
+                       phylipFile >> numTest;
+                       
+                       if (!m->isContainingOnlyDigits(numTest)) { m->mothurOut("[ERROR]: expected a number and got " + numTest + ", quitting."); m->mothurOutEndLine(); exit(1); }
+            else {
+                m->mothurConvert(numTest, pNumSeqs);
+            }
+            phylipFile >> pNumSeqs; m->gobble(phylipFile);
+            
+            string seqName;
+            double distance;
+            
+            for(int i=0;i<pNumSeqs;i++){
+                
+                if (m->control_pressed) { return ""; }
+                
+                phylipFile >> seqName; 
+                uniqueNames.insert(seqName);
+                
+                for(int j=0;j<i;j++){
+                    phylipFile >> distance;
+                }
+                m->gobble(phylipFile);
+            }
+            phylipFile.close();
+        }else {
+            ifstream columnFile;
+            m->openInputFile(distFile, columnFile);
+            string seqNameA, seqNameB;
+            double distance;
+            
+            while(columnFile){
+                if (m->control_pressed) { return ""; }
+                columnFile >> seqNameA >> seqNameB >> distance;
+                uniqueNames.insert(seqNameA); uniqueNames.insert(seqNameB);
+                m->gobble(columnFile);
+            }
+            columnFile.close();
+        }
+        
+        //read list file, if numSeqs > unique names then remove redundant names
+        string newListFile = listFile + ".temp";
+        ofstream out;
+        m->openOutputFile(newListFile, out);
+        ifstream in;
+               m->openInputFile(listFile, in);
+               
+               bool wroteSomething = false;
+               
+               while(!in.eof()){
+                       
+                       if (m->control_pressed) { in.close(); out.close(); m->mothurRemove(newListFile);  return ""; }
+            
+                       //read in list vector
+                       ListVector list(in);
+            
+            //listfile is already unique
+            if (list.getNumSeqs() == uniqueNames.size()) { in.close(); out.close(); m->mothurRemove(newListFile);  return ""; }
+                       
+                       //make a new list vector
+                       ListVector newList;
+                       newList.setLabel(list.getLabel());
+                       
+                       //for each bin
+                       for (int i = 0; i < list.getNumBins(); i++) {
+                
+                               //parse out names that are in accnos file
+                               string binnames = list.get(i);
+                vector<string> bnames;
+                m->splitAtComma(binnames, bnames);
+                               
+                               string newNames = "";
+                for (int i = 0; i < bnames.size(); i++) {
+                                       string name = bnames[i];
+                                       //if that name is in the .accnos file, add it
+                                       if (uniqueNames.count(name) != 0) {  newNames += name + ",";  }
+                               }
+                
+                               //if there are names in this bin add to new list
+                               if (newNames != "") { 
+                                       newNames = newNames.substr(0, newNames.length()-1); //rip off extra comma
+                                       newList.push_back(newNames);    
+                               }
+                       }
+            
+                       //print new listvector
+                       if (newList.getNumBins() != 0) {
+                               wroteSomething = true;
+                               newList.print(out);
+                       }
+                       
+                       m->gobble(in);
+               }
+               in.close();     
+               out.close();
+
+        if (wroteSomething) { return newListFile; }
+        return ""; 
+    }
+    catch(exception& e) {
+        m->errorOut(e, "SensSpecCommand", "preProcessList");
+        exit(1);
+    }
+}
+
 
 //***************************************************************************************************************