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