]> git.donarmstrong.com Git - mothur.git/blob - catchallcommand.cpp
a07928bdf01b249b7925a912d5223e7e8e2eeac0
[mothur.git] / catchallcommand.cpp
1 /*\r
2  *  catchallcommand.cpp\r
3  *  Mothur\r
4  *\r
5  *  Created by westcott on 5/11/10.\r
6  *  Copyright 2010 Schloss Lab. All rights reserved.\r
7  *\r
8  */\r
9 \r
10 #include "catchallcommand.h"\r
11 #include "globaldata.hpp"\r
12 \r
13 //**********************************************************************************************************************\r
14 vector<string> CatchAllCommand::getValidParameters(){   \r
15         try {\r
16                 string AlignArray[] =  {"sabund","label","inputdir","outputdir"};\r
17                 vector<string> myArray (AlignArray, AlignArray+(sizeof(AlignArray)/sizeof(string)));\r
18                 return myArray;\r
19         }\r
20         catch(exception& e) {\r
21                 m->errorOut(e, "CatchAllCommand", "getValidParameters");\r
22                 exit(1);\r
23         }\r
24 }\r
25 //**********************************************************************************************************************\r
26 CatchAllCommand::CatchAllCommand(){     \r
27         try {\r
28                 //initialize outputTypes\r
29                 vector<string> tempOutNames;\r
30                 outputTypes["csv"] = tempOutNames;\r
31                 outputTypes["summary"] = tempOutNames;\r
32         }\r
33         catch(exception& e) {\r
34                 m->errorOut(e, "CatchAllCommand", "CatchAllCommand");\r
35                 exit(1);\r
36         }\r
37 }\r
38 //**********************************************************************************************************************\r
39 vector<string> CatchAllCommand::getRequiredParameters(){        \r
40         try {\r
41                 string AlignArray[] =  {"sabund"};\r
42                 vector<string> myArray (AlignArray, AlignArray+(sizeof(AlignArray)/sizeof(string)));\r
43                 return myArray;\r
44         }\r
45         catch(exception& e) {\r
46                 m->errorOut(e, "CatchAllCommand", "getRequiredParameters");\r
47                 exit(1);\r
48         }\r
49 }\r
50 //**********************************************************************************************************************\r
51 vector<string> CatchAllCommand::getRequiredFiles(){     \r
52         try {\r
53                 vector<string> myArray;\r
54                 return myArray;\r
55         }\r
56         catch(exception& e) {\r
57                 m->errorOut(e, "CatchAllCommand", "getRequiredFiles");\r
58                 exit(1);\r
59         }\r
60 }\r
61 /**************************************************************************************/\r
62 CatchAllCommand::CatchAllCommand(string option)  {      \r
63         try {\r
64                 globaldata = GlobalData::getInstance();\r
65                 abort = false;\r
66                 allLines = 1;\r
67                 \r
68                 //allow user to run help\r
69                 if(option == "help") { help(); abort = true; }\r
70                 \r
71                 else {\r
72                         //valid paramters for this command\r
73                         string Array[] =  {"sabund","label","inputdir","outputdir"};\r
74                         vector<string> myArray (Array, Array+(sizeof(Array)/sizeof(string)));\r
75                         \r
76                         OptionParser parser(option);\r
77                         map<string,string> parameters = parser.getParameters();\r
78                         \r
79                         ValidParameters validParameter;\r
80                         map<string, string>::iterator it;\r
81                 \r
82                         //check to make sure all parameters are valid for command\r
83                         for (it = parameters.begin(); it != parameters.end(); it++) { \r
84                                 if (validParameter.isValidParameter(it->first, myArray, it->second) != true) {  abort = true;  }\r
85                         }\r
86                         \r
87                         //initialize outputTypes\r
88                         vector<string> tempOutNames;\r
89                         outputTypes["csv"] = tempOutNames;\r
90                         outputTypes["summary"] = tempOutNames;\r
91                         \r
92                         //if the user changes the input directory command factory will send this info to us in the output parameter \r
93                         string inputDir = validParameter.validFile(parameters, "inputdir", false);              \r
94                         if (inputDir == "not found"){   inputDir = "";          }\r
95                         else {\r
96                                 string path;\r
97                                 it = parameters.find("sabund");\r
98                                 //user has given a template file\r
99                                 if(it != parameters.end()){ \r
100                                         path = m->hasPath(it->second);\r
101                                         //if the user has not given a path then, add inputdir. else leave path alone.\r
102                                         if (path == "") {       parameters["sabund"] = inputDir + it->second;           }\r
103                                 }\r
104                         }\r
105 \r
106                         //check for required parameters\r
107                         sabundfile = validParameter.validFile(parameters, "sabund", true);\r
108                         if (sabundfile == "not open") { sabundfile = ""; abort = true; }\r
109                         else if (sabundfile == "not found") { sabundfile = "";  m->mothurOut("You must provide a sabund file for the catchall command."); m->mothurOutEndLine(); abort=true; }\r
110                         else { globaldata->setSabundFile(sabundfile); globaldata->setFormat("sabund"); }\r
111                         \r
112                         string label = validParameter.validFile(parameters, "label", false);                    \r
113                         if (label == "not found") { label = ""; }\r
114                         else { \r
115                                 if(label != "all") {  m->splitAtDash(label, labels);  allLines = 0;  }\r
116                                 else { allLines = 1;  }\r
117                         }\r
118                 \r
119 \r
120                         //if the user changes the output directory command factory will send this info to us in the output parameter \r
121                         outputDir = validParameter.validFile(parameters, "outputdir", false);           if (outputDir == "not found"){  outputDir = m->hasPath(sabundfile);     }\r
122                 }\r
123 \r
124         }\r
125         catch(exception& e) {\r
126                 m->errorOut(e, "CatchAllCommand", "CatchAllCommand");\r
127                 exit(1);\r
128         }\r
129 }\r
130 //**********************************************************************************************************************\r
131 \r
132 void CatchAllCommand::help(){\r
133         try {\r
134                 m->mothurOut("The catchall command interfaces mothur with the catchall program written by Linda Woodard, Sean Connolly and John Bunge.\n");\r
135                 m->mothurOut("For more information about catchall refer to http://www.northeastern.edu/catchall/index.html \n");\r
136                 m->mothurOut("The catchall executable must be in the same folder as your mothur executable. \n");\r
137                 m->mothurOut("If you are a MAC or Linux user you must also have installed mono, a link to mono is on the webpage. \n");\r
138                 m->mothurOut("The catchall command parameters are sabund and label, sabund is required. \n");\r
139                 m->mothurOut("The label parameter is used to analyze specific labels in your input.\n");\r
140                 m->mothurOut("The catchall command should be in the following format: \n");\r
141                 m->mothurOut("catchall(sabund=yourSabundFile) \n");\r
142                 m->mothurOut("Example: catchall(sabund=abrecovery.fn.sabund) \n");      \r
143         }\r
144         catch(exception& e) {\r
145                 m->errorOut(e, "CatchAllCommand", "help");\r
146                 exit(1);\r
147         }\r
148 }\r
149 \r
150 /**************************************************************************************/\r
151 int CatchAllCommand::execute() {        \r
152         try {\r
153                 \r
154                 if (abort == true) { return 0; }\r
155                 \r
156                 //prepare full output directory\r
157                 outputDir = m->getFullPathName(outputDir);\r
158                 \r
159                 //get location of catchall\r
160                 GlobalData* globaldata = GlobalData::getInstance();\r
161                 path = globaldata->argv;\r
162                 path = path.substr(0, (path.find_last_of('m')));\r
163                 path = m->getFullPathName(path);\r
164 \r
165                 string catchAllCommandExe = ""; \r
166                 #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)\r
167                         catchAllCommandExe += "mono " + path + "CatchAllcmdL.exe ";\r
168                 #else\r
169                         catchAllCommandExe += "\"" + path + "CatchAllcmdW.exe\"" + " ";\r
170                 #endif\r
171                 \r
172                 read = new ReadOTUFile(sabundfile);     \r
173                 read->read(&*globaldata); \r
174                 \r
175                 SAbundVector* sabund = globaldata->sabund;\r
176                 string lastLabel = sabund->getLabel();\r
177                 input = globaldata->ginput;\r
178                                                 \r
179                 set<string> processedLabels;\r
180                 set<string> userLabels = labels;\r
181                 \r
182                 string summaryfilename = outputDir + m->getRootName(m->getSimpleName(sabundfile)) + "catchall.summary";\r
183                 summaryfilename = m->getFullPathName(summaryfilename);\r
184                 outputNames.push_back(summaryfilename); outputTypes["summary"].push_back(summaryfilename);\r
185                 \r
186                 ofstream out;\r
187                 m->openOutputFile(summaryfilename, out);        \r
188                 \r
189                 out << "label\tmodel\testimate\tlci\tuci" << endl;\r
190                 \r
191                 //for each label the user selected\r
192                 while((sabund != NULL) && ((allLines == 1) || (userLabels.size() != 0))) {\r
193 \r
194                                         \r
195                         if(allLines == 1 || labels.count(sabund->getLabel()) == 1){\r
196                                         m->mothurOut(sabund->getLabel());  m->mothurOutEndLine();\r
197                                         \r
198                                         //create catchall input file from mothur's inputfile\r
199                                         string filename = process(sabund);\r
200                                         string outputPath = m->getPathName(filename);\r
201                                 \r
202                                         //create system command\r
203                                         string catchAllCommand = "";\r
204                                         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)\r
205                                                 catchAllCommand += catchAllCommandExe + filename + " " + outputPath + " 1";\r
206                                         #else\r
207                                                 if (outputPath.length() > 0) { outputPath = outputPath.substr(0, outputPath.length()-1); }\r
208                                                 catchAllCommand += catchAllCommandExe + "\"" + filename + "\" \""  + outputPath + "\" 1";\r
209                                                 //wrap entire string in ""\r
210                                                 catchAllCommand = "\"" + catchAllCommand + "\"";\r
211                                         #endif\r
212                                                                         //run catchall\r
213                                         system(catchAllCommand.c_str());\r
214                                 \r
215                                         remove(filename.c_str());\r
216                                 \r
217                                         filename = m->getRootName(filename); filename = filename.substr(0, filename.length()-1); //rip off extra .\r
218                                 \r
219                                         outputNames.push_back(filename + "_Analysis.csv"); outputTypes["csv"].push_back(filename + "_Analysis.csv");\r
220                                         outputNames.push_back(filename + "_BestModelsAnalysis.csv"); outputTypes["csv"].push_back(filename + "_BestModelsAnalysis.csv");\r
221                                         outputNames.push_back(filename + "_BestModelsFits.csv"); outputTypes["csv"].push_back(filename + "_BestModelsFits.csv");\r
222                                         outputNames.push_back(filename + "_BubblePlot.csv"); outputTypes["csv"].push_back(filename + "_BubblePlot.csv");\r
223                                 \r
224                                         createSummaryFile(filename + "_BestModelsAnalysis.csv", sabund->getLabel(), out);\r
225                                                                                 \r
226                                         if (m->control_pressed) { out.close(); for (int i = 0; i < outputNames.size(); i++) {remove(outputNames[i].c_str());    } delete read;  delete input; globaldata->ginput = NULL; delete sabund;  return 0; }\r
227 \r
228                                         processedLabels.insert(sabund->getLabel());\r
229                                         userLabels.erase(sabund->getLabel());\r
230                         }\r
231                         \r
232                         if ((m->anyLabelsToProcess(sabund->getLabel(), userLabels, "") == true) && (processedLabels.count(lastLabel) != 1)) {\r
233                                         string saveLabel = sabund->getLabel();\r
234                                         \r
235                                         delete sabund;          \r
236                                         sabund = (input->getSAbundVector(lastLabel));\r
237                                         \r
238                                         m->mothurOut(sabund->getLabel());  m->mothurOutEndLine();\r
239                                         \r
240 \r
241                                         //create catchall input file from mothur's inputfile\r
242                                         string filename = process(sabund);\r
243                                         string outputPath = m->getPathName(filename);\r
244                                         \r
245                                         //create system command\r
246                                         string catchAllCommand = "";\r
247                                         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)\r
248                                                 catchAllCommand += catchAllCommandExe + filename + " " + outputPath + " 1";\r
249                                         #else\r
250                                                 if (outputPath.length() > 0) { outputPath = outputPath.substr(0, outputPath.length()-1); }\r
251                                                 catchAllCommand += catchAllCommandExe + "\"" + filename + "\" \""  + outputPath + "\" 1";\r
252                                                 catchAllCommand = "\"" + catchAllCommand + "\"";\r
253                                         #endif\r
254 \r
255                                         //run catchall\r
256                                         system(catchAllCommand.c_str());\r
257                                 \r
258                                         remove(filename.c_str());\r
259                                 \r
260                                         filename = m->getRootName(filename); filename = filename.substr(0, filename.length()-1); //rip off extra .\r
261                                 \r
262                                         outputNames.push_back(filename + "_Analysis.csv"); outputTypes["csv"].push_back(filename + "_Analysis.csv");\r
263                                         outputNames.push_back(filename + "_BestModelsAnalysis.csv"); outputTypes["csv"].push_back(filename + "_BestModelsAnalysis.csv");\r
264                                         outputNames.push_back(filename + "_BestModelsFits.csv"); outputTypes["csv"].push_back(filename + "_BestModelsFits.csv");\r
265                                         outputNames.push_back(filename + "_BubblePlot.csv"); outputTypes["csv"].push_back(filename + "_BubblePlot.csv");\r
266                                 \r
267                                         createSummaryFile(filename + "_BestModelsAnalysis.csv", sabund->getLabel(), out);\r
268                                 \r
269                                         if (m->control_pressed) { out.close(); for (int i = 0; i < outputNames.size(); i++) {remove(outputNames[i].c_str());    } delete read;  delete input; globaldata->ginput = NULL; delete sabund;  return 0; }\r
270 \r
271                                         processedLabels.insert(sabund->getLabel());\r
272                                         userLabels.erase(sabund->getLabel());\r
273                                         \r
274                                         //restore real lastlabel to save below\r
275                                         sabund->setLabel(saveLabel);\r
276                         }\r
277                         \r
278                         \r
279                         lastLabel = sabund->getLabel(); \r
280                         \r
281                         delete sabund;          \r
282                         sabund = (input->getSAbundVector());\r
283                 }\r
284                 \r
285                 //output error messages about any remaining user labels\r
286                 set<string>::iterator it;\r
287                 bool needToRun = false;\r
288                 for (it = userLabels.begin(); it != userLabels.end(); it++) {  \r
289                         m->mothurOut("Your file does not include the label " + *it); \r
290                         if (processedLabels.count(lastLabel) != 1) {\r
291                                 m->mothurOut(". I will use " + lastLabel + ".");  m->mothurOutEndLine();\r
292                                 needToRun = true;\r
293                         }else {\r
294                                 m->mothurOut(". Please refer to " + lastLabel + ".");  m->mothurOutEndLine();\r
295                         }\r
296                 }\r
297                 \r
298                 //run last label if you need to\r
299                 if (needToRun == true)  {\r
300                         if (sabund != NULL) {   delete sabund;  }\r
301                         sabund = (input->getSAbundVector(lastLabel));\r
302                         \r
303                         m->mothurOut(sabund->getLabel());  m->mothurOutEndLine();\r
304                         \r
305                         //create catchall input file from mothur's inputfile\r
306                         string filename = process(sabund);\r
307                         string outputPath = m->getPathName(filename);\r
308                         \r
309                         //create system command\r
310                         string catchAllCommand = "";\r
311                         #if defined (__APPLE__) || (__MACH__) || (linux) || (__linux)\r
312                                 catchAllCommand += catchAllCommandExe + filename + " " + outputPath + " 1";\r
313                         #else\r
314                                 if (outputPath.length() > 0) { outputPath = outputPath.substr(0, outputPath.length()-1); }\r
315                                 catchAllCommand += catchAllCommandExe + "\"" + filename + "\" \""  + outputPath + "\" 1";\r
316                                 catchAllCommand = "\"" + catchAllCommand + "\"";\r
317                         #endif\r
318                         \r
319                         //run catchall\r
320                         system(catchAllCommand.c_str());\r
321                         \r
322                         remove(filename.c_str());\r
323                         \r
324                         filename = m->getRootName(filename); filename = filename.substr(0, filename.length()-1); //rip off extra .\r
325                         \r
326                         outputNames.push_back(filename + "_Analysis.csv"); outputTypes["csv"].push_back(filename + "_Analysis.csv");\r
327                         outputNames.push_back(filename + "_BestModelsAnalysis.csv"); outputTypes["csv"].push_back(filename + "_BestModelsAnalysis.csv");\r
328                         outputNames.push_back(filename + "_BestModelsFits.csv"); outputTypes["csv"].push_back(filename + "_BestModelsFits.csv");\r
329                         outputNames.push_back(filename + "_BubblePlot.csv"); outputTypes["csv"].push_back(filename + "_BubblePlot.csv");        \r
330                         \r
331                         createSummaryFile(filename + "_BestModelsAnalysis.csv", sabund->getLabel(), out);\r
332                         \r
333                         delete sabund;\r
334                 }\r
335                 \r
336                 out.close();\r
337                 delete read;\r
338                 delete input; globaldata->ginput = NULL;\r
339                 \r
340                 if (m->control_pressed) { for (int i = 0; i < outputNames.size(); i++) {remove(outputNames[i].c_str()); } return 0; }\r
341                 \r
342                 m->mothurOutEndLine();\r
343                 m->mothurOut("Output File Names: "); m->mothurOutEndLine();\r
344                 for (int i = 0; i < outputNames.size(); i++) {  m->mothurOut(outputNames[i]); m->mothurOutEndLine();    }       \r
345                 m->mothurOutEndLine();\r
346                 \r
347 \r
348                 return 0;\r
349         }\r
350         catch(exception& e) {\r
351                 m->errorOut(e, "CatchAllCommand", "execute");\r
352                 exit(1);\r
353         }\r
354 }\r
355 //**********************************************************************************************************************\r
356 string CatchAllCommand::process(SAbundVector* sabund) {\r
357         try {\r
358                 string filename = outputDir + m->getRootName(m->getSimpleName(sabundfile)) + sabund->getLabel() + ".csv";\r
359                 filename = m->getFullPathName(filename);\r
360         \r
361                 ofstream out;\r
362                 m->openOutputFile(filename, out);\r
363                 \r
364                 for (int i = 1; i <= sabund->getMaxRank(); i++) {\r
365                         int temp = sabund->get(i);\r
366                         \r
367                         if (temp != 0) {\r
368                                 out << i << "," << temp << endl;\r
369                         }\r
370                 }\r
371                 out.close();\r
372                 \r
373                 return filename;\r
374         \r
375         }\r
376         catch(exception& e) {\r
377                 m->errorOut(e, "CatchAllCommand", "process");\r
378                 exit(1);\r
379         }\r
380 }\r
381 //**********************************************************************************************************************\r
382 int CatchAllCommand::createSummaryFile(string file1, string label, ofstream& out) {\r
383         try {\r
384                 \r
385                 ifstream in;\r
386                 m->openInputFile(file1, in);\r
387                 \r
388                 if (!in.eof()) {\r
389                         \r
390                         string header = m->getline(in); m->gobble(in);\r
391                         \r
392                         int pos = header.find("Total Number of Observed Species =");\r
393                         string numString = "";\r
394                         \r
395                         \r
396                         if (pos == string::npos) { m->mothurOut("[ERROR]: cannot parse " + file1); m->mothurOutEndLine(); }\r
397                         else {\r
398                                 //pos will be the position of the T in total, so we want to count to the position of =\r
399                                 pos += 34;\r
400                                 char c=header[pos];\r
401                                 while (c != ','){\r
402                                         if (c != ' ') {\r
403                                                 numString += c;\r
404                                         }\r
405                                         pos++;\r
406                                         c=header[pos];\r
407                                         \r
408                                         //sanity check\r
409                                         if (pos > header.length()) { m->mothurOut("Cannot find number of OTUs in " + file1); m->mothurOutEndLine(); in.close(); return 0; }\r
410                                 }\r
411                         }\r
412                                                                                                                           \r
413                         string firstline = m->getline(in); m->gobble(in);\r
414                         vector<string> values;\r
415                         m->splitAtComma(firstline, values);\r
416                         \r
417                         values.pop_back(); //last value is always a blank string since the last character in the line is always a ','\r
418                         \r
419                         if (values.size() == 1) { //grab next line if firstline didn't have what you wanted\r
420                                 string secondline = m->getline(in); m->gobble(in);\r
421                                 values.clear();\r
422                                 m->splitAtComma(secondline, values);\r
423                                 \r
424                                 values.pop_back(); //last value is always a blank string since the last character in the line is always a ','\r
425                         }\r
426                         \r
427                         if (values.size() == 1) { //still not what we wanted fill values with numOTUs\r
428                                 values.resize(8, "");\r
429                                 values[1] = "Sobs";\r
430                                 values[4] = numString;\r
431                                 values[6] = numString;\r
432                                 values[7] = numString;\r
433                         }\r
434                         \r
435                         if (values.size() < 8) { values.resize(8, ""); }\r
436                         \r
437                         out << label << '\t' << values[1] << '\t' << values[4] << '\t' << values[6] << '\t' << values[7] << endl;\r
438                 }\r
439                 \r
440                 in.close();\r
441                 \r
442                 return 0;\r
443                 \r
444         }\r
445         catch(exception& e) {\r
446                 m->errorOut(e, "CatchAllCommand", "createSummaryFile");\r
447                 exit(1);\r
448         }\r
449 }\r
450 /**************************************************************************************/\r
451 \r
452 \r
453 \r